// 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.

#include "buffet/http_connection_curl.h"

#include <base/logging.h>
#include <chromeos/string_utils.h>

#include "buffet/http_request.h"
#include "buffet/http_transport_curl.h"

namespace buffet {
namespace http {
namespace curl {

static int curl_trace(CURL *handle, curl_infotype type,
                      char *data, size_t size, void *userp) {
  std::string msg(data, size);

  switch (type) {
  case CURLINFO_TEXT:
    VLOG(3) << "== Info: " << msg;
    break;
  case CURLINFO_HEADER_OUT:
    VLOG(3) << "=> Send headers:\n" << msg;
    break;
  case CURLINFO_DATA_OUT:
    VLOG(3) << "=> Send data:\n" << msg;
    break;
  case CURLINFO_SSL_DATA_OUT:
    VLOG(3) << "=> Send SSL data" << msg;
    break;
  case CURLINFO_HEADER_IN:
    VLOG(3) << "<= Recv header: " << msg;
    break;
  case CURLINFO_DATA_IN:
    VLOG(3) << "<= Recv data:\n" << msg;
    break;
  case CURLINFO_SSL_DATA_IN:
    VLOG(3) << "<= Recv SSL data" << msg;
    break;
  default:
    break;
  }
  return 0;
}

Connection::Connection(CURL* curl_handle, const std::string& method,
                       std::shared_ptr<http::Transport> transport) :
    http::Connection(transport), method_(method), curl_handle_(curl_handle) {
  VLOG(1) << "curl::Connection created: " << method_;
}

Connection::~Connection() {
  VLOG(1) << "curl::Connection destroyed";
}

bool Connection::SendHeaders(const HeaderList& headers,
                             chromeos::ErrorPtr* error) {
  headers_.insert(headers.begin(), headers.end());
  return true;
}

bool Connection::WriteRequestData(const void* data, size_t size,
                                  chromeos::ErrorPtr* error) {
  if (size > 0) {
    auto data_ptr = reinterpret_cast<const unsigned char*>(data);
    request_data_.insert(request_data_.end(), data_ptr, data_ptr + size);
  }
  return true;
}

bool Connection::FinishRequest(chromeos::ErrorPtr* error) {
  if (VLOG_IS_ON(3)) {
    curl_easy_setopt(curl_handle_, CURLOPT_DEBUGFUNCTION, curl_trace);
    curl_easy_setopt(curl_handle_, CURLOPT_VERBOSE, 1L);
  }

  // Set up HTTP request data.
  if (method_ == request_type::kPut) {
    curl_easy_setopt(curl_handle_, CURLOPT_INFILESIZE_LARGE,
                      curl_off_t(request_data_.size()));
  } else {
    curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDSIZE_LARGE,
                      curl_off_t(request_data_.size()));
  }
  if (!request_data_.empty()) {
    curl_easy_setopt(curl_handle_,
                     CURLOPT_READFUNCTION, &Connection::read_callback);
    curl_easy_setopt(curl_handle_, CURLOPT_READDATA, this);
    VLOG(2) << "Raw request data: "
        << std::string(reinterpret_cast<const char*>(request_data_.data()),
                       request_data_.size());
  }

  curl_slist* header_list = nullptr;
  if (!headers_.empty()) {
    for (auto pair : headers_) {
      std::string header = chromeos::string_utils::Join(": ",
                                                        pair.first,
                                                        pair.second);
      VLOG(2) << "Request header: " << header;
      header_list = curl_slist_append(header_list, header.c_str());
    }
    curl_easy_setopt(curl_handle_, CURLOPT_HTTPHEADER, header_list);
  }

  headers_.clear();

  // Set up HTTP response data.
  if (method_ != request_type::kHead) {
    curl_easy_setopt(curl_handle_,
                     CURLOPT_WRITEFUNCTION, &Connection::write_callback);
    curl_easy_setopt(curl_handle_, CURLOPT_WRITEDATA, this);
  }

  // HTTP response headers
  curl_easy_setopt(curl_handle_,
                   CURLOPT_HEADERFUNCTION, &Connection::header_callback);
  curl_easy_setopt(curl_handle_, CURLOPT_HEADERDATA, this);

  CURLcode ret = curl_easy_perform(curl_handle_);
  if (header_list)
    curl_slist_free_all(header_list);
  if (ret != CURLE_OK) {
    chromeos::Error::AddTo(error, http::curl::kErrorDomain,
                           chromeos::string_utils::ToString(ret),
                           curl_easy_strerror(ret));
  } else {
    LOG(INFO) << "Response: " << GetResponseStatusCode() << " ("
      << GetResponseStatusText() << ")";
    VLOG(2) << "Response data (" << response_data_.size() << "): "
        << std::string(reinterpret_cast<const char*>(response_data_.data()),
                       response_data_.size());
  }
  return (ret == CURLE_OK);
}

int Connection::GetResponseStatusCode() const {
  long status_code = 0;  // NOLINT(runtime/int) - curl expects a long here.
  curl_easy_getinfo(curl_handle_, CURLINFO_RESPONSE_CODE, &status_code);
  return status_code;
}

std::string Connection::GetResponseStatusText() const {
  return status_text_;
}

std::string Connection::GetProtocolVersion() const {
  return protocol_version_;
}

std::string Connection::GetResponseHeader(
    const std::string& header_name) const {
  auto p = headers_.find(header_name);
  return p != headers_.end() ? p->second : std::string();
}

uint64_t Connection::GetResponseDataSize() const {
  return response_data_.size();
}

bool Connection::ReadResponseData(void* data,
                                  size_t buffer_size,
                                  size_t* size_read,
                                  chromeos::ErrorPtr* error) {
  size_t size_to_read = response_data_.size() - response_data_ptr_;
  if (size_to_read > buffer_size)
    size_to_read = buffer_size;
  memcpy(data, response_data_.data() + response_data_ptr_, size_to_read);
  if (size_read)
    *size_read = size_to_read;
  response_data_ptr_ += size_to_read;
  return true;
}

size_t Connection::write_callback(char* ptr, size_t size,
                                  size_t num, void* data) {
  Connection* me = reinterpret_cast<Connection*>(data);
  size_t data_len = size * num;
  me->response_data_.insert(me->response_data_.end(), ptr, ptr + data_len);
  return data_len;
}

size_t Connection::read_callback(char* ptr, size_t size,
                                 size_t num, void* data) {
  Connection* me = reinterpret_cast<Connection*>(data);
  size_t data_len = size * num;

  if (me->request_data_ptr_ >= me->request_data_.size())
    return 0;

  if (me->request_data_ptr_ + data_len > me->request_data_.size())
    data_len = me->request_data_.size() - me->request_data_ptr_;

  memcpy(ptr, me->request_data_.data() + me->request_data_ptr_, data_len);
  me->request_data_ptr_ += data_len;

  return data_len;
}

size_t Connection::header_callback(char* ptr, size_t size,
                                   size_t num, void* data) {
  using chromeos::string_utils::SplitAtFirst;
  Connection* me = reinterpret_cast<Connection*>(data);
  size_t hdr_len = size * num;
  std::string header(ptr, hdr_len);
  // Remove newlines at the end of header line.
  while (!header.empty() && (header.back() == '\r' || header.back() == '\n')) {
    header.pop_back();
  }

  VLOG(2) << "Response header: " << header;

  if (!me->status_text_set_) {
    // First header - response code as "HTTP/1.1 200 OK".
    // Need to extract the OK part
    auto pair = SplitAtFirst(header, ' ');
    me->protocol_version_ = pair.first;
    me->status_text_ = SplitAtFirst(pair.second, ' ').second;
    me->status_text_set_ = true;
  } else {
    auto pair = SplitAtFirst(header, ':');
    if (!pair.second.empty())
      me->headers_.insert(pair);
  }
  return hdr_len;
}

}  // namespace curl
}  // namespace http
}  // namespace buffet
