// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LIBBRILLO_BRILLO_HTTP_HTTP_TRANSPORT_FAKE_H_
#define LIBBRILLO_BRILLO_HTTP_HTTP_TRANSPORT_FAKE_H_

#include <map>
#include <memory>
#include <queue>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

#include <base/callback.h>
#include <base/location.h>
#include <base/values.h>
#include <brillo/http/http_transport.h>
#include <brillo/http/http_utils.h>

namespace brillo {
namespace http {
namespace fake {

class ServerRequest;
class ServerResponse;
class Connection;

///////////////////////////////////////////////////////////////////////////////
// A fake implementation of http::Transport that simulates HTTP communication
// with a server.
///////////////////////////////////////////////////////////////////////////////
class Transport : public http::Transport {
 public:
  Transport();
  ~Transport() override;

  // Server handler callback signature.
  using HandlerCallback =
      base::Callback<void(const ServerRequest&, ServerResponse*)>;

  // This method allows the test code to provide a callback to handle requests
  // for specific URL/HTTP-verb combination. When a specific |method| request
  // is made on the given |url|, the |handler| will be invoked and all the
  // request data will be filled in the |ServerRequest| parameter. Any server
  // response should be returned through the |ServerResponse| parameter.
  // Either |method| or |url| (or both) can be specified as "*" to handle
  // any requests. So, ("http://localhost","*") will handle any request type
  // on that URL and ("*","GET") will handle any GET requests.
  // The lookup starts with the most specific data pair to the catch-all (*,*).
  void AddHandler(const std::string& url,
                  const std::string& method,
                  const HandlerCallback& handler);
  // Simple version of AddHandler. AddSimpleReplyHandler just returns the
  // specified text response of given MIME type.
  void AddSimpleReplyHandler(const std::string& url,
                             const std::string& method,
                             int status_code,
                             const std::string& reply_text,
                             const std::string& mime_type);
  // Retrieve a handler for specific |url| and request |method|.
  HandlerCallback GetHandler(const std::string& url,
                             const std::string& method) const;

  // For tests that want to assert on the number of HTTP requests sent,
  // these methods can be used to do just that.
  int GetRequestCount() const { return request_count_; }
  void ResetRequestCount() { request_count_ = 0; }

  // For tests that wish to simulate critical transport errors, this method
  // can be used to specify the error to be returned when creating a connection.
  void SetCreateConnectionError(brillo::ErrorPtr create_connection_error) {
    create_connection_error_ = std::move(create_connection_error);
  }

  // For tests that really need async operations with message loop, call this
  // function with true.
  void SetAsyncMode(bool async) { async_ = async; }

  // Pops one callback from the top of |async_callback_queue_| and invokes it.
  // Returns false if the queue is empty.
  bool HandleOneAsyncRequest();

  // Invokes all the callbacks currently queued in |async_callback_queue_|.
  void HandleAllAsyncRequests();

  // Overrides from http::Transport.
  std::shared_ptr<http::Connection> CreateConnection(
      const std::string& url,
      const std::string& method,
      const HeaderList& headers,
      const std::string& user_agent,
      const std::string& referer,
      brillo::ErrorPtr* error) override;

  void RunCallbackAsync(const base::Location& from_here,
                        const base::Closure& callback) override;

  RequestID StartAsyncTransfer(http::Connection* connection,
                               const SuccessCallback& success_callback,
                               const ErrorCallback& error_callback) override;

  bool CancelRequest(RequestID request_id) override;

  void SetDefaultTimeout(base::TimeDelta timeout) override;

  void SetLocalIpAddress(const std::string& ip_address) override {}

  void ResolveHostToIp(const std::string& host,
                       uint16_t port,
                       const std::string& ip_address) override {}

 protected:
  void ClearHost() override {}

 private:
  // A list of user-supplied request handlers.
  std::map<std::string, HandlerCallback> handlers_;
  // Counter incremented each time a request is made.
  int request_count_{0};
  bool async_{false};
  // A list of queued callbacks that need to be called at some point.
  // Call HandleOneAsyncRequest() or HandleAllAsyncRequests() to invoke them.
  std::queue<base::Closure> async_callback_queue_;

  // Fake error to be returned from CreateConnection method.
  brillo::ErrorPtr create_connection_error_;

  DISALLOW_COPY_AND_ASSIGN(Transport);
};

///////////////////////////////////////////////////////////////////////////////
// A base class for ServerRequest and ServerResponse. It provides common
// functionality to work with request/response HTTP headers and data.
///////////////////////////////////////////////////////////////////////////////
class ServerRequestResponseBase {
 public:
  ServerRequestResponseBase() = default;

  // Add/retrieve request/response body data.
  void SetData(StreamPtr stream);
  const std::vector<uint8_t>& GetData() const { return data_; }
  std::string GetDataAsString() const;
  base::Optional<base::Value> GetDataAsJson() const;
  // Parses the data into a JSON object and writes it back to JSON to normalize
  // its string representation (no pretty print, extra spaces, etc).
  std::string GetDataAsNormalizedJsonString() const;

  // Add/retrieve request/response HTTP headers.
  void AddHeaders(const HeaderList& headers);
  std::string GetHeader(const std::string& header_name) const;
  const std::multimap<std::string, std::string>& GetHeaders() const {
    return headers_;
  }

 protected:
  // Data buffer.
  std::vector<uint8_t> data_;
  // Header map.
  std::multimap<std::string, std::string> headers_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ServerRequestResponseBase);
};

///////////////////////////////////////////////////////////////////////////////
// A container class that encapsulates all the HTTP server request information.
///////////////////////////////////////////////////////////////////////////////
class ServerRequest : public ServerRequestResponseBase {
 public:
  ServerRequest(const std::string& url, const std::string& method);

  // Get the actual request URL. Does not include the query string or fragment.
  const std::string& GetURL() const { return url_; }
  // Get the request method.
  const std::string& GetMethod() const { return method_; }
  // Get the POST/GET request parameters. These are parsed query string
  // parameters from the URL. In addition, for POST requests with
  // application/x-www-form-urlencoded content type, the request body is also
  // parsed and individual fields can be accessed through this method.
  std::string GetFormField(const std::string& field_name) const;

 private:
  // Request URL (without query string or URL fragment).
  std::string url_;
  // Request method
  std::string method_;
  // List of available request data form fields.
  mutable std::map<std::string, std::string> form_fields_;
  // Flag used on first request to GetFormField to parse the body of HTTP POST
  // request with application/x-www-form-urlencoded content.
  mutable bool form_fields_parsed_ = false;

  DISALLOW_COPY_AND_ASSIGN(ServerRequest);
};

///////////////////////////////////////////////////////////////////////////////
// A container class that encapsulates all the HTTP server response information.
// The request handler will use this class to provide a response to the caller.
// Call the Reply() or the appropriate ReplyNNN() specialization to provide
// the response data. Additional calls to AddHeaders() can be made to provide
// custom response headers. The Reply-methods will already provide the
// following response headers:
//    Content-Length
//    Content-Type
///////////////////////////////////////////////////////////////////////////////
class ServerResponse : public ServerRequestResponseBase {
 public:
  ServerResponse() = default;

  // Generic reply method.
  void Reply(int status_code,
             const void* data,
             size_t data_size,
             const std::string& mime_type);
  // Reply with text body.
  void ReplyText(int status_code,
                 const std::string& text,
                 const std::string& mime_type);
  // Reply with JSON object. The content type will be "application/json".
  void ReplyJson(int status_code, const base::Value* json);
  // Special form for JSON response for simple objects that have a flat
  // list of key-value pairs of string type.
  void ReplyJson(int status_code, const FormFieldList& fields);

  // Specialized overload to send the binary data as an array of simple
  // data elements. Only trivial data types (scalars, POD structures, etc)
  // can be used.
  template <typename T>
  void Reply(int status_code,
             const std::vector<T>& data,
             const std::string& mime_type) {
    // Make sure T doesn't have virtual functions, custom constructors, etc.
    static_assert(std::is_trivial<T>::value, "Only simple data is supported");
    Reply(status_code, data.data(), data.size() * sizeof(T), mime_type);
  }

  // Specialized overload to send the binary data.
  // Only trivial data types (scalars, POD structures, etc) can be used.
  template <typename T>
  void Reply(int status_code, const T& data, const std::string& mime_type) {
    // Make sure T doesn't have virtual functions, custom constructors, etc.
    static_assert(std::is_trivial<T>::value, "Only simple data is supported");
    Reply(status_code, &data, sizeof(T), mime_type);
  }

  // For handlers that want to simulate versions of HTTP protocol other
  // than HTTP/1.1, call this method with the custom version string,
  // for example "HTTP/1.0".
  void SetProtocolVersion(const std::string& protocol_version) {
    protocol_version_ = protocol_version;
  }

 protected:
  // These methods are helpers to implement corresponding functionality
  // of fake::Connection.
  friend class Connection;
  // Helper for fake::Connection::GetResponseStatusCode().
  int GetStatusCode() const { return status_code_; }
  // Helper for fake::Connection::GetResponseStatusText().
  std::string GetStatusText() const;
  // Helper for fake::Connection::GetProtocolVersion().
  std::string GetProtocolVersion() const { return protocol_version_; }

 private:
  int status_code_ = 0;
  std::string protocol_version_ = "HTTP/1.1";

  DISALLOW_COPY_AND_ASSIGN(ServerResponse);
};

}  // namespace fake
}  // namespace http
}  // namespace brillo

#endif  // LIBBRILLO_BRILLO_HTTP_HTTP_TRANSPORT_FAKE_H_
