// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVELOPER_DEBUG_SHARED_CURL_H_
#define SRC_DEVELOPER_DEBUG_SHARED_CURL_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <curl/curl.h>

#include "lib/fit/function.h"
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/ref_counted.h"
#include "src/lib/fxl/memory/ref_ptr.h"

namespace debug_ipc {

// To use Curl, one must add something like the following to the beginning of their main() function
// (and include necessary header files).
//     Curl::GlobalInit();
//     auto deferred_cleanup = fit::defer([]{ Curl::GlobalCleanup(); });
// This is due to the thread-unsafety of curl_global_init() and curl_global_cleanup(), see
// https://curl.se/libcurl/c/curl_global_init.html and
// https://curl.se/libcurl/c/curl_global_cleanup.html.
//
// Curl must be constructed through fxl::MakeRefCounted<Curl>().
//
// Example usage:
//     int main() {
//       Curl::GlobalInit();
//       auto deferred_cleanup = fit::defer([]{ Curl::GlobalCleanup(); });
//
//       // do something else and maybe spawn some threads
//
//       auto curl = fxl::MakeRefCounted<Curl>();
//       // curl->......
//
//     }
class Curl : public fxl::RefCountedThreadSafe<Curl> {
 public:
  class Error {
   public:
    explicit Error(CURLcode code) : code_(code) {}

    Error& operator=(CURLcode code) {
      code_ = code;
      return *this;
    }

    bool operator==(const Error& other) const { return other.code_ == code_; }

    explicit operator CURLcode() const { return code_; }
    explicit operator bool() const { return code_ != CURLE_OK; }

    std::string ToString() const { return curl_easy_strerror(code_); }

   private:
    CURLcode code_;
  };

  // Escapes URL strings (converts all letters consider illegal in URLs to their %XX versions)
  static std::string Escape(const std::string& input);

  // Must be called before any threads are spawned and creation of Curl object.
  static void GlobalInit();
  // Need to be called after all threads are joined for resource cleanup.
  static void GlobalCleanup();

  // Callback when we receive data from libcurl. The return value should be the number of bytes
  // successfully processed (i.e. if we are passing this data to the write() syscall and it returns
  // a short bytes written count, we should as well).
  using DataCallback = fit::function<size_t(const std::string&)>;

  Error SetURL(const std::string& url) {
    return Error(curl_easy_setopt(curl_, CURLOPT_URL, url.c_str()));
  }

  const std::string& post_data() { return post_data_; }
  void set_post_data(const std::string& data) { post_data_ = data; }
  void set_post_data(const std::map<std::string, std::string>& items);

  std::vector<std::string>& headers() { return headers_; }
  bool& get_body() { return get_body_; }

  void set_data_callback(DataCallback handler) { data_callback_ = std::move(handler); }
  void set_header_callback(DataCallback handler) { header_callback_ = std::move(handler); }

  // Run the curl request synchronously.
  Error Perform();

  // Run the curl request asynchronously. Invoke the callback when done.
  void Perform(fit::callback<void(Curl*, Error)> cb);

  // Get the response code from the request. Undefined if the request hasn't
  // run.
  long ResponseCode();

 private:
  class Impl;

  Curl();
  ~Curl();
  void FreeSList();
  void PrepareToPerform();

  fxl::RefPtr<Impl> impl_;
  CURL* curl_ = nullptr;
  struct curl_slist* slist_ = nullptr;
  bool get_body_ = true;

  std::string post_data_;
  fxl::RefPtr<Curl> self_ref_;
  std::vector<std::string> headers_;
  fit::callback<void(Curl*, Error)> multi_cb_;
  DataCallback header_callback_ = [](const std::string& data) { return data.size(); };
  DataCallback data_callback_ = [](const std::string& data) { return data.size(); };

  FRIEND_REF_COUNTED_THREAD_SAFE(Curl);
  FRIEND_MAKE_REF_COUNTED(Curl);
};

}  // namespace debug_ipc

#endif  // SRC_DEVELOPER_DEBUG_SHARED_CURL_H_
