// 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 <base/check.h>
#include <brillo/http/http_connection_curl.h>

#include <utility>

#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/http/http_request.h>
#include <brillo/http/http_transport_curl.h>
#include <brillo/streams/memory_stream.h>
#include <brillo/streams/stream_utils.h>
#include <brillo/strings/string_utils.h>

namespace brillo {
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: " << msg;
      break;
    case CURLINFO_DATA_OUT:
      VLOG(3) << "=> Send data: <" << base::HexEncode(data, size) << ">";
      break;
    case CURLINFO_SSL_DATA_OUT:
      VLOG(3) << "=> Send SSL data: <" << base::HexEncode(data, size) << ">";
      break;
    case CURLINFO_HEADER_IN:
      VLOG(3) << "<= Recv header: " << msg;
      break;
    case CURLINFO_DATA_IN:
      VLOG(3) << "<= Recv data: <" << base::HexEncode(data, size) << ">";
      break;
    case CURLINFO_SSL_DATA_IN:
      VLOG(3) << "<= Recv SSL data: <" << base::HexEncode(data, size) << ">";
      break;
    default:
      break;
  }
  return 0;
}

Connection::Connection(CURL* curl_handle,
                       const std::string& method,
                       const std::shared_ptr<CurlInterface>& curl_interface,
                       const std::shared_ptr<http::Transport>& transport)
    : http::Connection(transport),
      method_(method),
      curl_handle_(curl_handle),
      curl_interface_(curl_interface) {
  // Store the connection pointer inside the CURL handle so we can easily
  // retrieve it when doing asynchronous I/O.
  curl_interface_->EasySetOptPtr(curl_handle_, CURLOPT_PRIVATE, this);
  VLOG(2) << "curl::Connection created: " << method_;
}

Connection::~Connection() {
  if (header_list_)
    curl_slist_free_all(header_list_);
  curl_interface_->EasyCleanup(curl_handle_);
  VLOG(2) << "curl::Connection destroyed";
}

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

bool Connection::SetRequestData(StreamPtr stream,
                                brillo::ErrorPtr* /* error */) {
  request_data_stream_ = std::move(stream);
  return true;
}

void Connection::SetResponseData(StreamPtr stream) {
  response_data_stream_ = std::move(stream);
}

void Connection::PrepareRequest() {
  if (VLOG_IS_ON(3)) {
    curl_interface_->EasySetOptCallback(curl_handle_, CURLOPT_DEBUGFUNCTION,
                                        &curl_trace);
    curl_interface_->EasySetOptInt(curl_handle_, CURLOPT_VERBOSE, 1);
  }

  if (method_ != request_type::kGet) {
    // Set up HTTP request data.
    uint64_t data_size = 0;
    if (request_data_stream_ && request_data_stream_->CanGetSize())
      data_size = request_data_stream_->GetRemainingSize();

    if (!request_data_stream_ || request_data_stream_->CanGetSize()) {
      // Data size is known (either no data, or data size is available).
      if (method_ == request_type::kPut) {
        curl_interface_->EasySetOptOffT(curl_handle_, CURLOPT_INFILESIZE_LARGE,
                                        data_size);
      } else {
        curl_interface_->EasySetOptOffT(curl_handle_,
                                        CURLOPT_POSTFIELDSIZE_LARGE, data_size);
      }
    } else {
      // Data size is unknown, so use chunked upload.
      headers_.emplace(http::request_header::kTransferEncoding, "chunked");
    }

    if (request_data_stream_) {
      curl_interface_->EasySetOptCallback(curl_handle_, CURLOPT_READFUNCTION,
                                          &Connection::read_callback);
      curl_interface_->EasySetOptPtr(curl_handle_, CURLOPT_READDATA, this);
    }
  }

  if (!headers_.empty()) {
    CHECK(header_list_ == nullptr);
    for (auto pair : headers_) {
      std::string header =
          brillo::string_utils::Join(": ", pair.first, pair.second);
      VLOG(2) << "Request header: " << header;
      header_list_ = curl_slist_append(header_list_, header.c_str());
    }
    curl_interface_->EasySetOptPtr(curl_handle_, CURLOPT_HTTPHEADER,
                                   header_list_);
  }

  headers_.clear();

  // Set up HTTP response data.
  if (!response_data_stream_)
    response_data_stream_ = MemoryStream::Create(nullptr);
  if (method_ != request_type::kHead) {
    curl_interface_->EasySetOptCallback(curl_handle_, CURLOPT_WRITEFUNCTION,
                                        &Connection::write_callback);
    curl_interface_->EasySetOptPtr(curl_handle_, CURLOPT_WRITEDATA, this);
  }

  // HTTP response headers
  curl_interface_->EasySetOptCallback(curl_handle_, CURLOPT_HEADERFUNCTION,
                                      &Connection::header_callback);
  curl_interface_->EasySetOptPtr(curl_handle_, CURLOPT_HEADERDATA, this);
}

bool Connection::FinishRequest(brillo::ErrorPtr* error) {
  PrepareRequest();
  CURLcode ret = curl_interface_->EasyPerform(curl_handle_);
  if (ret != CURLE_OK) {
    Transport::AddEasyCurlError(error, FROM_HERE, ret, curl_interface_.get());
  } else {
    // Rewind our data stream to the beginning so that it can be read back.
    if (response_data_stream_->CanSeek() &&
        !response_data_stream_->SetPosition(0, error))
      return false;
    LOG(INFO) << "Response: " << GetResponseStatusCode() << " ("
              << GetResponseStatusText() << ")";
  }
  return (ret == CURLE_OK);
}

RequestID Connection::FinishRequestAsync(
    const SuccessCallback& success_callback,
    const ErrorCallback& error_callback) {
  PrepareRequest();
  return transport_->StartAsyncTransfer(this, success_callback, error_callback);
}

int Connection::GetResponseStatusCode() const {
  int status_code = 0;
  curl_interface_->EasyGetInfoInt(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();
}

StreamPtr Connection::ExtractDataStream(brillo::ErrorPtr* error) {
  if (!response_data_stream_) {
    stream_utils::ErrorStreamClosed(FROM_HERE, error);
  }
  return std::move(response_data_stream_);
}

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;
  VLOG(1) << "Response data (" << data_len
          << "): " << std::string{ptr, data_len};
  // TODO(nathanbullock): Currently we are relying on the stream not blocking,
  // but if the stream is representing a pipe or some other construct that might
  // block then this code will behave badly.
  if (!me->response_data_stream_->WriteAllBlocking(ptr, data_len, nullptr)) {
    LOG(ERROR) << "Failed to write response data";
    data_len = 0;
  }
  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;

  size_t read_size = 0;
  bool success = me->request_data_stream_->ReadBlocking(ptr, data_len,
                                                        &read_size, nullptr);
  VLOG_IF(3, success) << "Sending data: " << std::string{ptr, read_size};
  return success ? read_size : CURL_READFUNC_ABORT;
}

size_t Connection::header_callback(char* ptr,
                                   size_t size,
                                   size_t num,
                                   void* data) {
  using brillo::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 brillo
