// 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_transport_curl.h"

#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <string.h>
#include <base/logging.h>

#include "buffet/mime_utils.h"
#include "buffet/string_utils.h"
#include "buffet/map_utils.h"

using namespace chromeos;
using namespace chromeos::http::curl;

#define VERBOSE_CURL 0  // Set to 1 to log advanced debugging info for CURL

#if VERBOSE_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:
    LOG(INFO) << "== Info: " << msg;
    break;
  case CURLINFO_HEADER_OUT:
    LOG(INFO) << "=> Send headers:\n" << msg;
    break;
  case CURLINFO_DATA_OUT:
    LOG(INFO) << "=> Send data:\n" << msg;
    break;
  case CURLINFO_SSL_DATA_OUT:
    LOG(INFO) << "=> Send SSL data" << msg;
    break;
  case CURLINFO_HEADER_IN:
    LOG(INFO) << "<= Recv header: " << msg;
    break;
  case CURLINFO_DATA_IN:
    LOG(INFO) << "<= Recv data:\n" << msg;
    break;
  case CURLINFO_SSL_DATA_IN:
    LOG(INFO) << "<= Recv SSL data" << msg;
    break;
  default:
    break;
  }
  return 0;
}
#endif

Transport::Transport(const std::string& url, const char* method) :
    request_url_(url),
    method_(method ? method : request_type::kGet) {
  stage_ = Stage::initialized;
}

Transport::~Transport() {
  Close();
}

void Transport::AddRange(int64_t bytes) {
  if (bytes < 0) {
    ranges_.emplace_back(Transport::range_value_omitted, -bytes);
  } else {
    ranges_.emplace_back(bytes, Transport::range_value_omitted);
  }
}

void Transport::AddRange(uint64_t fromByte, uint64_t toByte) {
  ranges_.emplace_back(fromByte, toByte);
}

std::string Transport::GetAccept() const {
  return accept_;
}

chromeos::http::HeaderList Transport::GetHeaders() const {
  chromeos::http::HeaderList headers = MapToVector(headers_);
  std::vector<std::string> ranges;
  if (method_ != request_type::kHead) {
    ranges.reserve(ranges_.size());
    for (auto p : ranges_) {
      if (p.first != range_value_omitted || p.second != range_value_omitted) {
        std::string range;
        if (p.first != range_value_omitted) {
          range = std::to_string(p.first);
        }
        range += '-';
        if (p.second != range_value_omitted) {
          range += std::to_string(p.second);
        }
        ranges.push_back(range);
      }
    }
  }
  if (!ranges.empty())
    headers.emplace_back(request_header::kRange,
                         "bytes=" + string_utils::Join(',', ranges));

  headers.emplace_back(request_header::kAccept, GetAccept());

  return headers;
}

void Transport::AddHeader(const char* header, const char* value) {
  headers_[header] = value;
}

void Transport::RemoveHeader(const char* header) {
  AddHeader(header, "");
}

bool Transport::AddRequestBody(const void* data, size_t size) {
  if (size == 0)
    return true;

  if (data == nullptr) {
    LOG(ERROR) << "Invalid request body data pointer";
    return false;
  }

  const unsigned char* data_ptr = reinterpret_cast<const unsigned char*>(data);
  request_data_.insert(request_data_.end(), data_ptr, data_ptr + size);
  return true;
}

bool Transport::Perform() {
  if (stage_ != Stage::initialized) {
    LOG(ERROR) << "Cannot call Perform() on unintialized transport object";
    return false;
  }

  curl_handle_ = curl_easy_init();
  if (!curl_handle_) {
    LOG(ERROR) << "Failed to initialize CURL";
    return false;
  }

  LOG(INFO) << "Sending a " << method_ << " request to " << request_url_;
  curl_easy_setopt(curl_handle_, CURLOPT_URL, request_url_.c_str());

#if VERBOSE_CURL
  curl_easy_setopt(curl_handle_, CURLOPT_DEBUGFUNCTION, curl_trace);
  curl_easy_setopt(curl_handle_, CURLOPT_VERBOSE, 1L);
#endif

  if (!user_agent_.empty()) {
    curl_easy_setopt(curl_handle_,
                     CURLOPT_USERAGENT, user_agent_.c_str());
  }

  if (!referer_.empty()) {
    curl_easy_setopt(curl_handle_,
                     CURLOPT_REFERER, referer_.c_str());
  }

  // Setup HTTP request method and optional request body.
  if (method_ == request_type::kGet) {
    curl_easy_setopt(curl_handle_, CURLOPT_HTTPGET, 1L);
  } else if (method_ == request_type::kHead) {
    curl_easy_setopt(curl_handle_, CURLOPT_NOBODY, 1L);
  } else if (method_ == request_type::kPut) {
    curl_easy_setopt(curl_handle_, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl_handle_, CURLOPT_INFILESIZE_LARGE,
                     curl_off_t(request_data_.size()));
    curl_easy_setopt(curl_handle_,
                     CURLOPT_READFUNCTION, &Transport::read_callback);
    curl_easy_setopt(curl_handle_, CURLOPT_READDATA, this);
  } else {
    // POST and custom request methods
    curl_easy_setopt(curl_handle_, CURLOPT_POST, 1L);
    curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDS, nullptr);
    if (!request_data_.empty()) {
      curl_easy_setopt(curl_handle_,
                       CURLOPT_READFUNCTION, &Transport::read_callback);
      curl_easy_setopt(curl_handle_, CURLOPT_READDATA, this);
    }
    curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDSIZE_LARGE,
                     curl_off_t(request_data_.size()));
    if (method_ != request_type::kPost)
      curl_easy_setopt(curl_handle_, CURLOPT_CUSTOMREQUEST, method_.c_str());
  }

  VLOG_IF(2, !request_data_.empty()) << "Request data ("
      << request_data_.size() << "): "
      << std::string(reinterpret_cast<const char*>(request_data_.data()),
                                                   request_data_.size());

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

  // HTTP request headers
  auto headers = GetHeaders();
  if (method_ != request_type::kGet && method_ != request_type::kHead) {
    if (!content_type_.empty())
      headers.emplace_back(request_header::kContentType, content_type_);
  }

  curl_slist* header_list = nullptr;
  if (!headers.empty()) {
    for (auto pair : headers) {
      std::string header = 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();

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

  CURLcode ret = curl_easy_perform(curl_handle_);
  if (ret != CURLE_OK) {
    error_ = curl_easy_strerror(ret);
    stage_ = Stage::failed;
    LOG(ERROR) << "CURL request failed: " << error_;
  } else {
    stage_ = Stage::response_received;
  }
  curl_slist_free_all(header_list);
  if (stage_ == Stage::response_received) {
    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 Transport::GetResponseStatusCode() const {
  if (stage_ != Stage::response_received)
    return 0;
  long status_code = 0;
  curl_easy_getinfo(curl_handle_, CURLINFO_RESPONSE_CODE, &status_code);
  return status_code;
}

std::string Transport::GetResponseHeader(const char* headerName) const {
  auto p = headers_.find(headerName);
  return p != headers_.end() ? p->second : std::string();
}

const std::vector<unsigned char>& Transport::GetResponseData() const {
  return response_data_;
}

void Transport::Close() {
  if (curl_handle_) {
    curl_easy_cleanup(curl_handle_);
    curl_handle_ = nullptr;
  }
  stage_ = Stage::closed;
}

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

size_t Transport::read_callback(char* ptr, size_t size,
                                size_t num, void* data) {
  Transport* me = reinterpret_cast<Transport*>(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 Transport::header_callback(char* ptr, size_t size,
                                  size_t num, void* data) {
  Transport* me = reinterpret_cast<Transport*>(data);
  size_t hdr_len = size * num;
  std::string header(ptr, int(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
    size_t pos = header.find(' ');
    if(pos != std::string::npos)
      pos = header.find(' ', pos + 1);
    if (pos != std::string::npos)
      me->status_text_ = header.substr(pos + 1);
    me->status_text_set_ = true;
  } else {
    auto pair = string_utils::SplitAtFirst(header, ':');
    if (!pair.second.empty())
      me->headers_.insert(pair);
  }
  return hdr_len;
}
