/* -*-c++-*- */
/*
 *  $Id: HTTPResponseHeader.h,v 1.3 2002/03/06 02:49:55 sbooth Exp $
 *
 *  Copyright (C) 1996 - 2002 Stephen F. Booth
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _HTTPRESPONSEHEADER_H_
#define _HTTPRESPONSEHEADER_H_ 1

#ifdef __GNUG__
#  pragma interface
#endif

/*! \file HTTPResponseHeader.h
 * \brief Class for generic, complete HTTP header responses
 * 
 * This is an class usually only used with Non-Parsed Header (NPH)
 * applications
 */

#include <string>
#include <vector>

#include "cgicc/MStreamable.h"
#include "cgicc/HTTPCookie.h"

CGICC_BEGIN_NAMESPACE

// ============================================================
// Class HTTPResponseHeader
// ============================================================
/*! \class HTTPResponseHeader HTTPResponseHeader.h cgicc/HTTPResponseHeader.h
 * \brief Generic HTTP response header
 *
 * This class represents an HTTP response header as defined in
 * section 6 of RFC 2616 (see http://www.w3.org)
 *
 * All HTTP/1.1 reponses consist of an initial status line containing
 * the HTTP version, a 3-digit status code, and a human-readable reason
 * phrase explaining the status code.
 *
 * The first digit of the Status-Code defines the class of
 * response. The last two digits do not have any categorization
 * role. There are 5 values for the first digit:
 * <ul>
 * <li>1xx: Informational - Request received, continuing process</li>
 * <li>2xx: Success - The action was successfully received,
 understood, and accepted</li>
 * <li>3xx: Redirection - Further action must be taken in order to
 * complete the request</li>
 * <li>4xx: Client Error - The request contains bad syntax or cannot
 * be fulfilled</li>
 * <li>5xx: Server Error - The server failed to fulfill an apparently
 * valid request</li></ul>
 */
class CGICC_API HTTPResponseHeader : public MStreamable
{
public:

  /*! \name Constructor and Destructor */
  //@{

  /*!
   * \brief Create a new HTTP response header
   * \param http_version The HTTP version string, usually \c HTTP/1.1
   * \param status_code The 3-digit HTTP status code
   * \param reason_phrase A short textual description of the status code
   */
  HTTPResponseHeader(const STDNS string& http_version,
		     int status_code,
		     const STDNS string& reason_phrase);
  
  /*!
   * \brief Delete this HTTPResponseHeader
   * 
   */
  virtual ~HTTPResponseHeader();
  //@}

  // ============================================================

  /*! \name Additional Header Management */
  //@{

  /*!
   * \brief Add a general, response, or entity header to this one
   * 
   * \param header The text of the header to add
   * \return A reference to this
   */
  HTTPResponseHeader&
  addHeader(const STDNS string& header);

  /*!
   * \brief Add a general, response, or entity header to this one
   * 
   * \param header The text of the header to add
   * \return A reference to this
   */
  HTTPResponseHeader&
  addHeader(const STDNS string& name,
	    const STDNS string& value);

  /*!
   * \brief Get a list of all additional headers
   *
   * \return A list of all additional headers
   */
  inline const STDNS vector<STDNS string>&
  getHeaders() 					const
  { return fHeaders; }
  //@}

  /*! \name Cookie Management */
  //@{

  /*!
   * \brief Set a cookie to go out with this HTTPResponseHeader
   * \param cookie The HTTPCookie to set
   */
  HTTPResponseHeader&
  setCookie(const HTTPCookie& cookie);

  /*!
   * \brief Get a list of all cookies associated with this header
   * \return All the cookies associated with this header
   */
  inline const STDNS vector<HTTPCookie>&
  getCookies() 					const
  { return fCookies; }
  //@}

  // ============================================================

  /*! \name Accessor methods 
   * Retrieve information on the header
   */
  //@{

  /*!
   * \brief Get the HTTP version
   *
   * The HTTP version is a string of the form \c HTTP/1.1
   * \return The HTTP version
   */
  inline const STDNS string&
  getHTTPVersion() 				const
  { return fHTTPVersion; }

  /*!
   * \brief Get the 3-digit status code
   *
   * The 3-digit status code indicates the disposition of the response.
   * \return The 3-digit status code
   */
  inline int
  getStatusCode() 				const
  { return fStatusCode; }

  /*!
   * \brief Get the reason phrase associated with the stats code
   *
   * The reason phrase is a human-readable interpretation of the status code
   * \return The reason phrase
   */
  inline STDNS string
  getReasonPhrase() 				const
  { return fReasonPhrase; }
  //@}

  // ============================================================

  /*! \name Mutator methods 
   * Set information on the header
   */
  //@{

  /*!
   * \brief Set the HTTP version
   *
   * The HTTP version is a string of the form \c HTTP/1.1
   * \param http_version The HTTP version string, usually \c HTTP/1.1
   * \return A reference to this
   */
  inline HTTPResponseHeader&
  getHTTPVersion(const STDNS string& http_version)
  { fHTTPVersion = http_version; return *this; }

  /*!
   * \brief Get the 3-digit status code
   *
   * The 3-digit status code indicates the disposition of the response.
   * \param status_code The 3-digit HTTP status code
   * \return A reference to this
   */
  inline HTTPResponseHeader&
  getStatusCode(int status_code)
  { fStatusCode = status_code; return *this; }

  /*!
   * \brief Get the reason phrase associated with the stats code
   *
   * The reason phrase is a human-readable interpretation of the status code
   * \param reason_phrase A short textual description of the status code
   * \return A reference to this
   */
  inline HTTPResponseHeader&
  getReasonPhrase(const STDNS string& reason_phrase)
  { fReasonPhrase = reason_phrase; return *this; }
  //@}

  // ============================================================

  /*! \name Inherited Methods */
  //@{
  virtual void 
  render(STDNS ostream& out) 			const;
  //@}

private:
  HTTPResponseHeader();

  STDNS string 			fHTTPVersion;
  int 				fStatusCode;
  STDNS string 			fReasonPhrase;
  STDNS vector<STDNS string> 	fHeaders;
  STDNS vector<HTTPCookie> 	fCookies;
};
  
CGICC_END_NAMESPACE

#endif /* ! _HTTPRESPONSEHEADER_H_ */
