// Copyright 2009 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifdef HAVE_CONFIG_H
#include <config.h>  // Must come first
#endif

#include <dlfcn.h>

#include <iostream>
#include <string>

#include "common/linux/libcurl_wrapper.h"
#include "common/using_std_string.h"

namespace google_breakpad {
LibcurlWrapper::LibcurlWrapper()
    : init_ok_(false),
      curl_lib_(nullptr),
      last_curl_error_(""),
      curl_(nullptr),
      formpost_(nullptr),
      lastptr_(nullptr),
      headerlist_(nullptr) {}

LibcurlWrapper::~LibcurlWrapper() {
  if (init_ok_) {
    (*easy_cleanup_)(curl_);
    (*global_cleanup_)();
    dlclose(curl_lib_);
  }
}

bool LibcurlWrapper::SetProxy(const string& proxy_host,
                              const string& proxy_userpwd) {
  if (!CheckInit()) return false;

  // Set proxy information if necessary.
  if (!proxy_host.empty()) {
    (*easy_setopt_)(curl_, CURLOPT_PROXY, proxy_host.c_str());
  } else {
    std::cout << "SetProxy called with empty proxy host.";
    return false;
  }
  if (!proxy_userpwd.empty()) {
    (*easy_setopt_)(curl_, CURLOPT_PROXYUSERPWD, proxy_userpwd.c_str());
  } else {
    std::cout << "SetProxy called with empty proxy username/password.";
    return false;
  }
  std::cout << "Set proxy host to " << proxy_host;
  return true;
}

bool LibcurlWrapper::AddFile(const string& upload_file_path,
                             const string& basename) {
  if (!CheckInit()) return false;

  std::cout << "Adding " << upload_file_path << " to form upload.";
  // Add form file.
  (*formadd_)(&formpost_, &lastptr_,
              CURLFORM_COPYNAME, basename.c_str(),
              CURLFORM_FILE, upload_file_path.c_str(),
              CURLFORM_END);

  return true;
}

// Callback to get the response data from server.
static size_t WriteCallback(void* ptr, size_t size,
                            size_t nmemb, void* userp) {
  if (!userp)
    return 0;

  string* response = reinterpret_cast<string*>(userp);
  size_t real_size = size * nmemb;
  response->append(reinterpret_cast<char*>(ptr), real_size);
  return real_size;
}

bool LibcurlWrapper::SendRequest(const string& url,
                                 const std::map<string, string>& parameters,
                                 long* http_status_code,
                                 string* http_header_data,
                                 string* http_response_data) {
  if (!CheckInit()) return false;

  std::map<string, string>::const_iterator iter = parameters.begin();
  for (; iter != parameters.end(); ++iter)
    (*formadd_)(&formpost_, &lastptr_,
                CURLFORM_COPYNAME, iter->first.c_str(),
                CURLFORM_COPYCONTENTS, iter->second.c_str(),
                CURLFORM_END);

  (*easy_setopt_)(curl_, CURLOPT_HTTPPOST, formpost_);

  return SendRequestInner(url, http_status_code, http_header_data,
                          http_response_data);
}

bool LibcurlWrapper::SendGetRequest(const string& url,
                                    long* http_status_code,
                                    string* http_header_data,
                                    string* http_response_data) {
  if (!CheckInit()) return false;

  (*easy_setopt_)(curl_, CURLOPT_HTTPGET, 1L);

  return SendRequestInner(url, http_status_code, http_header_data,
                          http_response_data);
}

bool LibcurlWrapper::SendPutRequest(const string& url,
                                    const string& path,
                                    long* http_status_code,
                                    string* http_header_data,
                                    string* http_response_data) {
  if (!CheckInit()) return false;

  FILE* file = fopen(path.c_str(), "rb");
  (*easy_setopt_)(curl_, CURLOPT_UPLOAD, 1L);
  (*easy_setopt_)(curl_, CURLOPT_PUT, 1L);
  (*easy_setopt_)(curl_, CURLOPT_READDATA, file);

  bool success = SendRequestInner(url, http_status_code, http_header_data,
                                  http_response_data);

  fclose(file);
  return success;
}

bool LibcurlWrapper::SendSimplePostRequest(const string& url,
                                           const string& body,
                                           const string& content_type,
                                           long* http_status_code,
                                           string* http_header_data,
                                           string* http_response_data) {
  if (!CheckInit()) return false;

  (*easy_setopt_)(curl_, CURLOPT_POSTFIELDSIZE, body.size());
  (*easy_setopt_)(curl_, CURLOPT_COPYPOSTFIELDS, body.c_str());

  if (!content_type.empty()) {
    string content_type_header = "Content-Type: " + content_type;
    headerlist_ = (*slist_append_)(
        headerlist_,
        content_type_header.c_str());
  }

  return SendRequestInner(url, http_status_code, http_header_data,
                          http_response_data);
}

bool LibcurlWrapper::Init() {
  // First check to see if libcurl was statically linked:
  curl_lib_ = dlopen(nullptr, RTLD_NOW);
  if (curl_lib_ &&
      (!dlsym(curl_lib_, "curl_easy_init") ||
      !dlsym(curl_lib_, "curl_easy_setopt"))) {
    // Not statically linked, try again below.
    dlerror();  // Clear dlerror before attempting to open libraries.
    dlclose(curl_lib_);
    curl_lib_ = nullptr;
  }
  if (!curl_lib_) {
    curl_lib_ = dlopen("libcurl.so", RTLD_NOW);
  }
  if (!curl_lib_) {
    curl_lib_ = dlopen("libcurl.so.4", RTLD_NOW);
  }
  if (!curl_lib_) {
    curl_lib_ = dlopen("libcurl.so.3", RTLD_NOW);
  }
  if (!curl_lib_) {
    std::cout << "Could not find libcurl via dlopen";
    return false;
  }

  if (!SetFunctionPointers()) {
    std::cout << "Could not find function pointers";
    return false;
  }

  curl_ = (*easy_init_)();

  last_curl_error_ = "No Error";

  if (!curl_) {
    dlclose(curl_lib_);
    std::cout << "Curl initialization failed";
    return false;
  }

  init_ok_ = true;
  return true;
}

#define SET_AND_CHECK_FUNCTION_POINTER(var, function_name, type) \
  var = reinterpret_cast<type>(dlsym(curl_lib_, function_name)); \
  if (!var) { \
    std::cout << "Could not find libcurl function " << function_name; \
    init_ok_ = false; \
    return false; \
  }

bool LibcurlWrapper::SetFunctionPointers() {

  SET_AND_CHECK_FUNCTION_POINTER(easy_init_,
                                 "curl_easy_init",
                                 CURL*(*)());

  SET_AND_CHECK_FUNCTION_POINTER(easy_setopt_,
                                 "curl_easy_setopt",
                                 CURLcode(*)(CURL*, CURLoption, ...));

  SET_AND_CHECK_FUNCTION_POINTER(formadd_, "curl_formadd",
      CURLFORMcode(*)(curl_httppost**, curl_httppost**, ...));

  SET_AND_CHECK_FUNCTION_POINTER(slist_append_, "curl_slist_append",
      curl_slist*(*)(curl_slist*, const char*));

  SET_AND_CHECK_FUNCTION_POINTER(easy_perform_,
                                 "curl_easy_perform",
                                 CURLcode(*)(CURL*));

  SET_AND_CHECK_FUNCTION_POINTER(easy_cleanup_,
                                 "curl_easy_cleanup",
                                 void(*)(CURL*));

  SET_AND_CHECK_FUNCTION_POINTER(easy_getinfo_,
                                 "curl_easy_getinfo",
                                 CURLcode(*)(CURL*, CURLINFO info, ...));

  SET_AND_CHECK_FUNCTION_POINTER(easy_reset_,
                                 "curl_easy_reset",
                                 void(*)(CURL*));

  SET_AND_CHECK_FUNCTION_POINTER(slist_free_all_,
                                 "curl_slist_free_all",
                                 void(*)(curl_slist*));

  SET_AND_CHECK_FUNCTION_POINTER(formfree_,
                                 "curl_formfree",
                                 void(*)(curl_httppost*));

  SET_AND_CHECK_FUNCTION_POINTER(global_cleanup_,
                                 "curl_global_cleanup",
                                 void(*)(void));
  return true;
}

bool LibcurlWrapper::SendRequestInner(const string& url,
                                      long* http_status_code,
                                      string* http_header_data,
                                      string* http_response_data) {
  string url_copy(url);
  (*easy_setopt_)(curl_, CURLOPT_URL, url_copy.c_str());

  // Disable 100-continue header.
  char buf[] = "Expect:";
  headerlist_ = (*slist_append_)(headerlist_, buf);
  (*easy_setopt_)(curl_, CURLOPT_HTTPHEADER, headerlist_);

  if (http_response_data != nullptr) {
    http_response_data->clear();
    (*easy_setopt_)(curl_, CURLOPT_WRITEFUNCTION, WriteCallback);
    (*easy_setopt_)(curl_, CURLOPT_WRITEDATA,
                    reinterpret_cast<void*>(http_response_data));
  }
  if (http_header_data != nullptr) {
    http_header_data->clear();
    (*easy_setopt_)(curl_, CURLOPT_HEADERFUNCTION, WriteCallback);
    (*easy_setopt_)(curl_, CURLOPT_HEADERDATA,
                    reinterpret_cast<void*>(http_header_data));
  }
  CURLcode err_code = CURLE_OK;
  err_code = (*easy_perform_)(curl_);
  easy_strerror_ = reinterpret_cast<const char* (*)(CURLcode)>
      (dlsym(curl_lib_, "curl_easy_strerror"));

  if (http_status_code != nullptr) {
    (*easy_getinfo_)(curl_, CURLINFO_RESPONSE_CODE, http_status_code);
  }

  if (err_code != CURLE_OK)
    fprintf(stderr, "Failed to send http request to %s, error: %s\n",
            url.c_str(),
            (*easy_strerror_)(err_code));

  Reset();

  return err_code == CURLE_OK;
}

void LibcurlWrapper::Reset() {
  if (headerlist_ != nullptr) {
    (*slist_free_all_)(headerlist_);
    headerlist_ = nullptr;
  }

  if (formpost_ != nullptr) {
    (*formfree_)(formpost_);
    formpost_ = nullptr;
  }

  (*easy_reset_)(curl_);
}

bool LibcurlWrapper::CheckInit() {
  if (!init_ok_) {
    std::cout << "LibcurlWrapper: You must call Init(), and have it return "
                 "'true' before invoking any other methods.\n";
    return false;
  }

  return true;
}

}  // namespace google_breakpad
