/*
 * libjingle
 * Copyright 2004--2005, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products 
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef TALK_BASE_HTTPCOMMON_H__
#define TALK_BASE_HTTPCOMMON_H__

#include <map>
#include <string>
#include <vector>
#include "talk/base/basictypes.h"
#include "talk/base/common.h"
#include "talk/base/scoped_ptr.h"
#include "talk/base/stringutils.h"
#include "talk/base/stream.h"

namespace talk_base {

class CryptString;
class SocketAddress;

//////////////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////////////

enum HttpCode { 
  HC_OK = 200,
  HC_NON_AUTHORITATIVE = 203,
  HC_NO_CONTENT = 204,
  HC_PARTIAL_CONTENT = 206,

  HC_MULTIPLE_CHOICES = 300,
  HC_MOVED_PERMANENTLY = 301,
  HC_FOUND = 302,
  HC_SEE_OTHER = 303,
  HC_NOT_MODIFIED = 304,
  HC_MOVED_TEMPORARILY = 307,

  HC_BAD_REQUEST = 400,
  HC_UNAUTHORIZED = 401,
  HC_FORBIDDEN = 403,
  HC_NOT_FOUND = 404,
  HC_PROXY_AUTHENTICATION_REQUIRED = 407,
  HC_GONE = 410,

  HC_INTERNAL_SERVER_ERROR = 500,
  HC_NOT_IMPLEMENTED = 501,
  HC_SERVICE_UNAVAILABLE = 503,
};

enum HttpVersion {
  HVER_1_0, HVER_1_1, HVER_UNKNOWN,
  HVER_LAST = HVER_UNKNOWN
};

enum HttpVerb {
  HV_GET, HV_POST, HV_PUT, HV_DELETE, HV_CONNECT, HV_HEAD,
  HV_LAST = HV_HEAD
};

enum HttpError {
  HE_NONE,
  HE_PROTOCOL,            // Received non-valid HTTP data
  HE_DISCONNECTED,        // Connection closed unexpectedly
  HE_OVERFLOW,            // Received too much data for internal buffers
  HE_CONNECT_FAILED,      // The socket failed to connect.
  HE_SOCKET_ERROR,        // An error occurred on a connected socket
  HE_SHUTDOWN,            // Http object is being destroyed
  HE_OPERATION_CANCELLED, // Connection aborted locally
  HE_AUTH,                // Proxy Authentication Required
  HE_CERTIFICATE_EXPIRED, // During SSL negotiation
  HE_STREAM,              // Problem reading or writing to the document
  HE_CACHE,               // Problem reading from cache
  HE_DEFAULT
};

enum HttpHeader {
  HH_AGE,
  HH_CACHE_CONTROL,
  HH_CONNECTION,
  HH_CONTENT_DISPOSITION,
  HH_CONTENT_LENGTH,
  HH_CONTENT_RANGE,
  HH_CONTENT_TYPE,
  HH_COOKIE,
  HH_DATE,
  HH_ETAG,
  HH_EXPIRES,
  HH_HOST,
  HH_IF_MODIFIED_SINCE,
  HH_IF_NONE_MATCH,
  HH_KEEP_ALIVE,
  HH_LAST_MODIFIED,
  HH_LOCATION,
  HH_PROXY_AUTHENTICATE,
  HH_PROXY_AUTHORIZATION,
  HH_PROXY_CONNECTION,
  HH_RANGE,
  HH_SET_COOKIE,
  HH_TE,
  HH_TRAILERS,
  HH_TRANSFER_ENCODING,
  HH_UPGRADE,
  HH_USER_AGENT,
  HH_WWW_AUTHENTICATE,
  HH_LAST = HH_WWW_AUTHENTICATE
};

const uint16 HTTP_DEFAULT_PORT = 80;
const uint16 HTTP_SECURE_PORT = 443;

//////////////////////////////////////////////////////////////////////
// Utility Functions
//////////////////////////////////////////////////////////////////////

inline HttpError mkerr(HttpError err, HttpError def_err = HE_DEFAULT) {
  return (err != HE_NONE) ? err : def_err;
}

const char* ToString(HttpVersion version);
bool FromString(HttpVersion& version, const std::string& str);

const char* ToString(HttpVerb verb);
bool FromString(HttpVerb& verb, const std::string& str);

const char* ToString(HttpHeader header);
bool FromString(HttpHeader& header, const std::string& str);

inline bool HttpCodeIsInformational(uint32 code) { return ((code / 100) == 1); }
inline bool HttpCodeIsSuccessful(uint32 code)    { return ((code / 100) == 2); }
inline bool HttpCodeIsRedirection(uint32 code)   { return ((code / 100) == 3); }
inline bool HttpCodeIsClientError(uint32 code)   { return ((code / 100) == 4); }
inline bool HttpCodeIsServerError(uint32 code)   { return ((code / 100) == 5); }

bool HttpCodeHasBody(uint32 code);
bool HttpCodeIsCacheable(uint32 code);
bool HttpHeaderIsEndToEnd(HttpHeader header);
bool HttpHeaderIsCollapsible(HttpHeader header);

struct HttpData;
bool HttpShouldKeepAlive(const HttpData& data);

typedef std::pair<std::string, std::string> HttpAttribute;
typedef std::vector<HttpAttribute> HttpAttributeList;
void HttpComposeAttributes(const HttpAttributeList& attributes, char separator,
                           std::string* composed);
void HttpParseAttributes(const char * data, size_t len, 
                         HttpAttributeList& attributes);
bool HttpHasAttribute(const HttpAttributeList& attributes,
                      const std::string& name,
                      std::string* value);
bool HttpHasNthAttribute(HttpAttributeList& attributes,
                         size_t index, 
                         std::string* name,
                         std::string* value);

// Convert RFC1123 date (DoW, DD Mon YYYY HH:MM:SS TZ) to unix timestamp
bool HttpDateToSeconds(const std::string& date, unsigned long* seconds);

inline uint16 HttpDefaultPort(bool secure) {
  return secure ? HTTP_SECURE_PORT : HTTP_DEFAULT_PORT;
}

// Returns the http server notation for a given address
std::string HttpAddress(const SocketAddress& address, bool secure);

// functional for insensitive std::string compare
struct iless {
  bool operator()(const std::string& lhs, const std::string& rhs) const {
    return (::_stricmp(lhs.c_str(), rhs.c_str()) < 0);
  }
};

// put quotes around a string and escape any quotes inside it
std::string quote(const std::string& str);

//////////////////////////////////////////////////////////////////////
// Url
//////////////////////////////////////////////////////////////////////

template<class CTYPE>
class Url {
public:
  typedef typename Traits<CTYPE>::string string;

  // TODO: Implement Encode/Decode
  static int Encode(const CTYPE* source, CTYPE* destination, size_t len);
  static int Encode(const string& source, string& destination);
  static int Decode(const CTYPE* source, CTYPE* destination, size_t len);
  static int Decode(const string& source, string& destination);

  Url(const string& url) { do_set_url(url.c_str(), url.size()); }
  Url(const string& path, const string& host, uint16 port = HTTP_DEFAULT_PORT)
  : host_(host), port_(port), secure_(HTTP_SECURE_PORT == port)
  { set_full_path(path); }

  bool valid() const { return !host_.empty(); }
  void clear() {
    host_.clear();
    port_ = HTTP_DEFAULT_PORT;
    secure_ = false;
    path_.assign(1, static_cast<CTYPE>('/'));
    query_.clear();
  }

  void set_url(const string& val) {
    do_set_url(val.c_str(), val.size());
  }
  string url() const {
    string val; do_get_url(&val); return val;
  }

  void set_address(const string& val) {
    do_set_address(val.c_str(), val.size());
  }
  string address() const {
    string val; do_get_address(&val); return val;
  }

  void set_full_path(const string& val) {
    do_set_full_path(val.c_str(), val.size());
  }
  string full_path() const {
    string val; do_get_full_path(&val); return val;
  }

  void set_host(const string& val) { host_ = val; }
  const string& host() const { return host_; }

  void set_port(uint16 val) { port_ = val; }
  uint16 port() const { return port_; }

  void set_secure(bool val) { secure_ = val; }
  bool secure() const { return secure_; }

  void set_path(const string& val) {
    if (val.empty()) {
      path_.assign(1, static_cast<CTYPE>('/'));
    } else {
      ASSERT(val[0] == static_cast<CTYPE>('/'));
      path_ = val;
    }
  }
  const string& path() const { return path_; }

  void set_query(const string& val) {
    ASSERT(val.empty() || (val[0] == static_cast<CTYPE>('?')));
    query_ = val;
  }
  const string& query() const { return query_; }

  bool get_attribute(const string& name, string* value) const;

private:
  void do_set_url(const CTYPE* val, size_t len);
  void do_set_address(const CTYPE* val, size_t len);
  void do_set_full_path(const CTYPE* val, size_t len);

  void do_get_url(string* val) const;
  void do_get_address(string* val) const;
  void do_get_full_path(string* val) const;

  string host_, path_, query_;
  uint16 port_;
  bool secure_;
};

//////////////////////////////////////////////////////////////////////
// HttpData
//////////////////////////////////////////////////////////////////////

struct HttpData {
  typedef std::multimap<std::string, std::string, iless> HeaderMap;
  typedef HeaderMap::const_iterator const_iterator;
  typedef HeaderMap::iterator iterator;

  HttpVersion version;
  scoped_ptr<StreamInterface> document;

  HttpData() : version(HVER_1_1) { }

  enum HeaderCombine { HC_YES, HC_NO, HC_AUTO, HC_REPLACE, HC_NEW };
  void changeHeader(const std::string& name, const std::string& value,
                    HeaderCombine combine);
  inline void addHeader(const std::string& name, const std::string& value,
                        bool append = true) {
    changeHeader(name, value, append ? HC_AUTO : HC_NO);
  }
  inline void setHeader(const std::string& name, const std::string& value,
                        bool overwrite = true) {
    changeHeader(name, value, overwrite ? HC_REPLACE : HC_NEW);
  }
  // Returns count of erased headers
  size_t clearHeader(const std::string& name);
  // Returns iterator to next header
  iterator clearHeader(iterator header);

  // keep in mind, this may not do what you want in the face of multiple headers
  bool hasHeader(const std::string& name, std::string* value) const;

  inline const_iterator begin() const {
    return headers_.begin();
  }
  inline const_iterator end() const {
    return headers_.end();
  }
  inline iterator begin() {
    return headers_.begin();
  }
  inline iterator end() {
    return headers_.end();
  }
  inline const_iterator begin(const std::string& name) const {
    return headers_.lower_bound(name);
  }
  inline const_iterator end(const std::string& name) const {
    return headers_.upper_bound(name);
  }
  inline iterator begin(const std::string& name) {
    return headers_.lower_bound(name);
  }
  inline iterator end(const std::string& name) {
    return headers_.upper_bound(name);
  }

  // Convenience methods using HttpHeader
  inline void changeHeader(HttpHeader header, const std::string& value,
                           HeaderCombine combine) {
    changeHeader(ToString(header), value, combine);
  }
  inline void addHeader(HttpHeader header, const std::string& value,
                        bool append = true) {
    addHeader(ToString(header), value, append);
  }
  inline void setHeader(HttpHeader header, const std::string& value,
                        bool overwrite = true) {
    setHeader(ToString(header), value, overwrite);
  }
  inline void clearHeader(HttpHeader header) {
    clearHeader(ToString(header));
  }
  inline bool hasHeader(HttpHeader header, std::string* value) const {
    return hasHeader(ToString(header), value);
  }
  inline const_iterator begin(HttpHeader header) const {
    return headers_.lower_bound(ToString(header));
  }
  inline const_iterator end(HttpHeader header) const {
    return headers_.upper_bound(ToString(header));
  }
  inline iterator begin(HttpHeader header) {
    return headers_.lower_bound(ToString(header));
  }
  inline iterator end(HttpHeader header) {
    return headers_.upper_bound(ToString(header));
  }

  void setContent(const std::string& content_type, StreamInterface* document);
  void setDocumentAndLength(StreamInterface* document);

  virtual size_t formatLeader(char* buffer, size_t size) const = 0;
  virtual HttpError parseLeader(const char* line, size_t len) = 0;

protected:  
  virtual ~HttpData() { }
  void clear(bool release_document);
  void copy(const HttpData& src);

private:
  HeaderMap headers_;
};

struct HttpRequestData : public HttpData {
  HttpVerb verb;
  std::string path;

  HttpRequestData() : verb(HV_GET) { }

  void clear(bool release_document);
  void copy(const HttpRequestData& src);

  virtual size_t formatLeader(char* buffer, size_t size) const;
  virtual HttpError parseLeader(const char* line, size_t len);

  bool getAbsoluteUri(std::string* uri) const;
  bool getRelativeUri(std::string* host, std::string* path) const;
};

struct HttpResponseData : public HttpData {
  uint32 scode;
  std::string message;

  HttpResponseData() : scode(HC_INTERNAL_SERVER_ERROR) { }
  void clear(bool release_document);
  void copy(const HttpResponseData& src);

  // Convenience methods
  void set_success(uint32 scode = HC_OK);
  void set_success(const std::string& content_type, StreamInterface* document,
                   uint32 scode = HC_OK);
  void set_redirect(const std::string& location,
                    uint32 scode = HC_MOVED_TEMPORARILY);
  void set_error(uint32 scode);

  virtual size_t formatLeader(char* buffer, size_t size) const;
  virtual HttpError parseLeader(const char* line, size_t len);
};

struct HttpTransaction {
  HttpRequestData request;
  HttpResponseData response;
};

//////////////////////////////////////////////////////////////////////
// Http Authentication
//////////////////////////////////////////////////////////////////////

struct HttpAuthContext {
  std::string auth_method;
  HttpAuthContext(const std::string& auth) : auth_method(auth) { }
  virtual ~HttpAuthContext() { }
};

enum HttpAuthResult { HAR_RESPONSE, HAR_IGNORE, HAR_CREDENTIALS, HAR_ERROR };

// 'context' is used by this function to record information between calls.
// Start by passing a null pointer, then pass the same pointer each additional
// call.  When the authentication attempt is finished, delete the context.
HttpAuthResult HttpAuthenticate(
  const char * challenge, size_t len,
  const SocketAddress& server,
  const std::string& method, const std::string& uri,
  const std::string& username, const CryptString& password,
  HttpAuthContext *& context, std::string& response, std::string& auth_method);

//////////////////////////////////////////////////////////////////////

} // namespace talk_base

#endif // TALK_BASE_HTTPCOMMON_H__
