/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef RTC_BASE_HTTPCOMMON_H_
#define RTC_BASE_HTTPCOMMON_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "rtc_base/checks.h"
#include "rtc_base/stream.h"
#include "rtc_base/stringutils.h"

namespace rtc {

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_t HTTP_DEFAULT_PORT = 80;
const uint16_t 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_t code) {
  return ((code / 100) == 1);
}
inline bool HttpCodeIsSuccessful(uint32_t code) {
  return ((code / 100) == 2);
}
inline bool HttpCodeIsRedirection(uint32_t code) {
  return ((code / 100) == 3);
}
inline bool HttpCodeIsClientError(uint32_t code) {
  return ((code / 100) == 4);
}
inline bool HttpCodeIsServerError(uint32_t code) {
  return ((code / 100) == 5);
}

bool HttpCodeHasBody(uint32_t code);
bool HttpCodeIsCacheable(uint32_t 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 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, time_t* seconds);

inline uint16_t 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_t 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_t val) { port_ = val; }
  uint16_t 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 {
      RTC_DCHECK(val[0] == static_cast<CTYPE>('/'));
      path_ = val;
    }
  }
  const string& path() const { return path_; }

  void set_query(const string& val) {
    RTC_DCHECK(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_t 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;
  std::unique_ptr<StreamInterface> document;

  HttpData();

  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);

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

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

struct HttpResponseData : public HttpData {
  uint32_t 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_t scode = HC_OK);
  void set_success(const std::string& content_type,
                   StreamInterface* document,
                   uint32_t scode = HC_OK);
  void set_redirect(const std::string& location,
                    uint32_t scode = HC_MOVED_TEMPORARILY);
  void set_error(uint32_t scode);

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

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.
// TODO(bugs.webrtc.org/8905): Change "response" to "ZeroOnFreeBuffer".
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 rtc

#endif  // RTC_BASE_HTTPCOMMON_H_
