// 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 <brillo/http/curl_api.h>

#include <base/logging.h>

namespace brillo {
namespace http {

namespace {

static_assert(CURLOPTTYPE_LONG == 0 &&
              CURLOPTTYPE_OBJECTPOINT == 10000 &&
              CURLOPTTYPE_FUNCTIONPOINT == 20000 &&
              CURLOPTTYPE_OFF_T == 30000,
              "CURL option types are expected to be multiples of 10000");

inline bool VerifyOptionType(CURLoption option, int expected_type) {
  int option_type = (static_cast<int>(option) / 10000) * 10000;
  return (option_type == expected_type);
}

}  // anonymous namespace

CurlApi::CurlApi() {
  curl_global_init(CURL_GLOBAL_ALL);
}

CurlApi::~CurlApi() {
  curl_global_cleanup();
}

CURL* CurlApi::EasyInit() {
  return curl_easy_init();
}

void CurlApi::EasyCleanup(CURL* curl) {
  curl_easy_cleanup(curl);
}

CURLcode CurlApi::EasySetOptInt(CURL* curl, CURLoption option, int value) {
  CHECK(VerifyOptionType(option, CURLOPTTYPE_LONG))
      << "Only options that expect a LONG data type must be specified here";
  // CURL actually uses "long" type, so have to make sure we feed it what it
  // expects.
  // NOLINTNEXTLINE(runtime/int)
  return curl_easy_setopt(curl, option, static_cast<long>(value));
}

CURLcode CurlApi::EasySetOptStr(CURL* curl,
                                CURLoption option,
                                const std::string& value) {
  CHECK(VerifyOptionType(option, CURLOPTTYPE_OBJECTPOINT))
      << "Only options that expect a STRING data type must be specified here";
  return curl_easy_setopt(curl, option, value.c_str());
}

CURLcode CurlApi::EasySetOptPtr(CURL* curl, CURLoption option, void* value) {
  CHECK(VerifyOptionType(option, CURLOPTTYPE_OBJECTPOINT))
      << "Only options that expect a pointer data type must be specified here";
  return curl_easy_setopt(curl, option, value);
}

CURLcode CurlApi::EasySetOptCallback(CURL* curl,
                                     CURLoption option,
                                     intptr_t address) {
  CHECK(VerifyOptionType(option, CURLOPTTYPE_FUNCTIONPOINT))
      << "Only options that expect a function pointers must be specified here";
  return curl_easy_setopt(curl, option, address);
}

CURLcode CurlApi::EasySetOptOffT(CURL* curl,
                                 CURLoption option,
                                 curl_off_t value) {
  CHECK(VerifyOptionType(option, CURLOPTTYPE_OFF_T))
      << "Only options that expect a large data size must be specified here";
  return curl_easy_setopt(curl, option, value);
}

CURLcode CurlApi::EasyPerform(CURL* curl) {
  return curl_easy_perform(curl);
}

CURLcode CurlApi::EasyGetInfoInt(CURL* curl, CURLINFO info, int* value) const {
  CHECK_EQ(CURLINFO_LONG, info & CURLINFO_TYPEMASK) << "Wrong option type";
  long data = 0;  // NOLINT(runtime/int) - curl expects a long here.
  CURLcode code = curl_easy_getinfo(curl, info, &data);
  if (code == CURLE_OK)
    *value = static_cast<int>(data);
  return code;
}

CURLcode CurlApi::EasyGetInfoDbl(CURL* curl,
                                 CURLINFO info,
                                 double* value) const {
  CHECK_EQ(CURLINFO_DOUBLE, info & CURLINFO_TYPEMASK) << "Wrong option type";
  return curl_easy_getinfo(curl, info, value);
}

CURLcode CurlApi::EasyGetInfoStr(CURL* curl,
                                 CURLINFO info,
                                 std::string* value) const {
  CHECK_EQ(CURLINFO_STRING, info & CURLINFO_TYPEMASK) << "Wrong option type";
  char* data = nullptr;
  CURLcode code = curl_easy_getinfo(curl, info, &data);
  if (code == CURLE_OK)
    *value = data;
  return code;
}

CURLcode CurlApi::EasyGetInfoPtr(CURL* curl,
                                 CURLINFO info,
                                 void** value) const {
  // CURL uses "string" type for generic pointer info. Go figure.
  CHECK_EQ(CURLINFO_STRING, info & CURLINFO_TYPEMASK) << "Wrong option type";
  return curl_easy_getinfo(curl, info, value);
}

std::string CurlApi::EasyStrError(CURLcode code) const {
  return curl_easy_strerror(code);
}

CURLM* CurlApi::MultiInit() {
  return curl_multi_init();
}

CURLMcode CurlApi::MultiCleanup(CURLM* multi_handle) {
  return curl_multi_cleanup(multi_handle);
}

CURLMsg* CurlApi::MultiInfoRead(CURLM* multi_handle, int* msgs_in_queue) {
  return curl_multi_info_read(multi_handle, msgs_in_queue);
}

CURLMcode CurlApi::MultiAddHandle(CURLM* multi_handle, CURL* curl_handle) {
  return curl_multi_add_handle(multi_handle, curl_handle);
}

CURLMcode CurlApi::MultiRemoveHandle(CURLM* multi_handle, CURL* curl_handle) {
  return curl_multi_remove_handle(multi_handle, curl_handle);
}

CURLMcode CurlApi::MultiSetSocketCallback(CURLM* multi_handle,
                                          curl_socket_callback socket_callback,
                                          void* userp) {
  CURLMcode code =
      curl_multi_setopt(multi_handle, CURLMOPT_SOCKETFUNCTION, socket_callback);
  if (code != CURLM_OK)
    return code;
  return curl_multi_setopt(multi_handle, CURLMOPT_SOCKETDATA, userp);
}

CURLMcode CurlApi::MultiSetTimerCallback(
    CURLM* multi_handle,
    curl_multi_timer_callback timer_callback,
    void* userp) {
  CURLMcode code =
      curl_multi_setopt(multi_handle, CURLMOPT_TIMERFUNCTION, timer_callback);
  if (code != CURLM_OK)
    return code;
  return curl_multi_setopt(multi_handle, CURLMOPT_TIMERDATA, userp);
}

CURLMcode CurlApi::MultiAssign(CURLM* multi_handle,
                               curl_socket_t sockfd,
                               void* sockp) {
  return curl_multi_assign(multi_handle, sockfd, sockp);
}

CURLMcode CurlApi::MultiSocketAction(CURLM* multi_handle,
                                     curl_socket_t s,
                                     int ev_bitmask,
                                     int* running_handles) {
  return curl_multi_socket_action(multi_handle, s, ev_bitmask, running_handles);
}

std::string CurlApi::MultiStrError(CURLMcode code) const {
  return curl_multi_strerror(code);
}

CURLMcode CurlApi::MultiPerform(CURLM* multi_handle, int* running_handles) {
  return curl_multi_perform(multi_handle, running_handles);
}

CURLMcode CurlApi::MultiWait(CURLM* multi_handle,
                             curl_waitfd extra_fds[],
                             unsigned int extra_nfds,
                             int timeout_ms,
                             int* numfds) {
  return curl_multi_wait(multi_handle, extra_fds, extra_nfds, timeout_ms,
                         numfds);
}

}  // namespace http
}  // namespace brillo
