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

#include "examples/provider/event_http_client.h"
#include "examples/provider/event_task_runner.h"

#include <weave/enum_to_string.h>

#include <string>

#include <base/bind.h>

#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/http.h>

// EventHttpClient based on libevent2 http-client sample
// TODO(proppy): https
// TODO(proppy): hostname validation
namespace weave {

namespace {
const weave::EnumToStringMap<evhttp_cmd_type>::Map kMapMethod[] = {
    {EVHTTP_REQ_GET, "GET"},        {EVHTTP_REQ_POST, "POST"},
    {EVHTTP_REQ_HEAD, "HEAD"},      {EVHTTP_REQ_PUT, "PUT"},
    {EVHTTP_REQ_PATCH, "PATCH"},    {EVHTTP_REQ_DELETE, "DELETE"},
    {EVHTTP_REQ_OPTIONS, "OPTIONS"}};
}  // namespace

template <>
EnumToStringMap<evhttp_cmd_type>::EnumToStringMap()
    : EnumToStringMap(kMapMethod) {}

using namespace provider;

namespace examples {

namespace {

class EventDeleter {
 public:
  void operator()(evhttp_uri* http_uri) { evhttp_uri_free(http_uri); }
  void operator()(evhttp_connection* conn) { evhttp_connection_free(conn); }
  void operator()(evhttp_request* req) { evhttp_request_free(req); }
};

class EventHttpResponse : public weave::provider::HttpClient::Response {
 public:
  int GetStatusCode() const override { return status; }
  std::string GetContentType() const override { return content_type; }
  std::string GetData() const { return data; }

  int status;
  std::string content_type;
  std::string data;
};

struct EventRequestState {
  TaskRunner* task_runner_;
  std::unique_ptr<evhttp_uri, EventDeleter> http_uri_;
  std::unique_ptr<evhttp_connection, EventDeleter> evcon_;
  HttpClient::SendRequestCallback callback_;
};

void RequestDoneCallback(evhttp_request* req, void* ctx) {
  std::unique_ptr<EventRequestState> state{
      static_cast<EventRequestState*>(ctx)};
  if (!req) {
    ErrorPtr error;
    auto err = EVUTIL_SOCKET_ERROR();
    Error::AddToPrintf(&error, FROM_HERE, "http_client", "request_failed",
                       "request failed: %s",
                       evutil_socket_error_to_string(err));
    state->task_runner_->PostDelayedTask(
        FROM_HERE, base::Bind(state->callback_, nullptr, base::Passed(&error)),
        {});
    return;
  }
  std::unique_ptr<EventHttpResponse> response{new EventHttpResponse()};
  response->status = evhttp_request_get_response_code(req);
  auto buffer = evhttp_request_get_input_buffer(req);
  auto length = evbuffer_get_length(buffer);
  response->data.resize(length);
  auto n = evbuffer_remove(buffer, &response->data[0], length);
  CHECK_EQ(n, int(length));
  state->task_runner_->PostDelayedTask(
      FROM_HERE, base::Bind(state->callback_, base::Passed(&response), nullptr),
      {});
}

}  // namespace

EventHttpClient::EventHttpClient(EventTaskRunner* task_runner)
    : task_runner_{task_runner} {}

void EventHttpClient::SendRequest(Method method,
                                  const std::string& url,
                                  const Headers& headers,
                                  const std::string& data,
                                  const SendRequestCallback& callback) {
  evhttp_cmd_type method_id;
  CHECK(weave::StringToEnum(weave::EnumToString(method), &method_id));
  std::unique_ptr<evhttp_uri, EventDeleter> http_uri{
      evhttp_uri_parse(url.c_str())};
  CHECK(http_uri);
  auto host = evhttp_uri_get_host(http_uri.get());
  CHECK(host);
  auto port = evhttp_uri_get_port(http_uri.get());
  if (port == -1)
    port = 80;
  std::string path{evhttp_uri_get_path(http_uri.get())};
  if (path.length() == 0) {
    path = "/";
  }
  std::string uri{path};
  auto query = evhttp_uri_get_query(http_uri.get());
  if (query) {
    uri = path + "?" + query;
  }
  auto bev = bufferevent_socket_new(task_runner_->GetEventBase(), -1,
                                    BEV_OPT_CLOSE_ON_FREE);
  CHECK(bev);
  std::unique_ptr<evhttp_connection, EventDeleter> conn{
      evhttp_connection_base_bufferevent_new(task_runner_->GetEventBase(), NULL,
                                             bev, host, port)};
  CHECK(conn);
  std::unique_ptr<evhttp_request, EventDeleter> req{evhttp_request_new(
      &RequestDoneCallback,
      new EventRequestState{task_runner_, std::move(http_uri), std::move(conn),
                            callback})};
  CHECK(req);
  auto output_headers = evhttp_request_get_output_headers(req.get());
  evhttp_add_header(output_headers, "Host", host);
  for (auto& kv : headers)
    evhttp_add_header(output_headers, kv.first.c_str(), kv.second.c_str());
  if (!data.empty()) {
    auto output_buffer = evhttp_request_get_output_buffer(req.get());
    evbuffer_add(output_buffer, data.c_str(), data.length());
    evhttp_add_header(output_headers, "Content-Length",
                      std::to_string(data.length()).c_str());
  }
  auto res =
      evhttp_make_request(conn.get(), req.release(), method_id, uri.c_str());
  if (res >= 0)
    return;
  ErrorPtr error;
  Error::AddToPrintf(&error, FROM_HERE, "http_client", "request_failed",
                     "request failed: %s %s", EnumToString(method).c_str(),
                     url.c_str());
  task_runner_->PostDelayedTask(
      FROM_HERE, base::Bind(callback, nullptr, base::Passed(&error)), {});
}

}  // namespace examples
}  // namespace weave
