/*
 * client.h
 *
 *  Created on: 2021年8月16日
 *      Author: pengzc
 */

#ifndef JNI_HTTP_CLIENT_H_
#define JNI_HTTP_CLIENT_H_

#include <cstdlib>
#include <cctype>
#include <string>
#include "http_request.h"
#include "http_response.h"
#include "curl/curl.h"
#include <system/Thread.h>
#include <functional>

namespace base {

class HttpClient {
public:
  HttpClient();
  virtual ~HttpClient();

  typedef std::function<int (int64_t dltotal,
      int64_t dlnow, int64_t ultotal, int64_t ulnow)> ProgressCallback;

  HttpResponse Do(const HttpRequest& request);
  HttpResponse Do(const HttpRequest& request, ProgressCallback progress);
  HttpResponse Do(const HttpRequest& request, const std::string& save_path,
      ProgressCallback progress);

  /**
   * 连接超时
   */
  HttpClient& SetConnectionTimeout(int ms);
  /**
   * 总超时
   */
  HttpClient& SetTimeout(int ms);

  /**
   * 速度低于bytes/s，持续seconds，中止执行
   */
  HttpClient& SetLowSpeedLimit(int bytes, int seconds);

  void SetCAInfoFilePath(const std::string& caInfoFilePath);

  void SetSSLVerify(bool verify);

  /**
   * 终止请求
   */
  void Abort();

  void SetDebug(bool debug);

private:
  static ::size_t curl_response_write_callback(void *data, ::size_t size,
      ::size_t nmemb, void *userdata);
  static ::size_t header_callback(void *data, ::size_t size, ::size_t nmemb,
      void *userdata);

  static int curl_progress_callback(void *clientp, curl_off_t dltotal,
      curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);

  static int debug_trace(CURL *handle, curl_infotype type, char *data, ::size_t size,
      void *userp);

private:
  CURL* curl_;
  int connection_timeout_;
  int timeout_;
  std::string ca_info_file_path_;
  bool ssl_verify_;
  bool aborted_;
  ProgressCallback progress_callback_;
  Mutex do_mutex_;

  struct {
    int bytes;
    int seconds;
  }low_speed_limit_;

  bool debug_;
};

} /* namespace base */

#endif /* JNI_HTTP_CLIENT_H_ */
