/*
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef HTTP_REQUEST_H
#define HTTP_REQUEST_H

#include <curl/curl.h>
#include <functional>
#include <map>
#include <memory>
#include <string>
#include "url.h"
#include "utils.h"

namespace http {

class Request {
 public:
  enum class UploadStatus {
    CONTINUE,
    DONE,
    ABORT
  };

  using Headers = std::multimap<std::string, std::string>;
  using QueryStringParams = std::multimap<std::string, std::string>;
  using UploadFn = std::function<UploadStatus(char *, size_t, size_t *)>;
  using DownloadFn = std::function<void(void *, size_t)>;
  using ProgressFn = std::function<bool(curl_off_t,
                                        curl_off_t,
                                        curl_off_t,
                                        curl_off_t)>;
  using Ptr = std::unique_ptr<Request>;
  using Factory = std::function<Ptr(const Url &)>;

  Request(std::shared_ptr<CURL> handle, const Url &url);
  virtual ~Request();

  CURLcode Get();
  CURLcode Get(DownloadFn download_fn);
  CURLcode Post(UploadFn upload_fn);
  CURLcode Post(const char *data, curl_off_t data_len);

  void Reset();

  const std::string &user_agent() const { return user_agent_; }
  void set_user_agent(const std::string &user_agent) {
    user_agent_ = user_agent;
  }

  const Url &url() const { return url_; }
  void set_url(const Url &url) { url_ = url; }

  Headers &headers() { return headers_; }
  void set_header(Headers::key_type name, Headers::mapped_type value);
  void add_header(Headers::key_type name, Headers::mapped_type value);
  void clear_header(Headers::key_type name);
  void clear_headers();

  QueryStringParams &params() { return params_; }
  void set_param(QueryStringParams::key_type name,
                 QueryStringParams::mapped_type value);
  void add_param(QueryStringParams::key_type name,
                 QueryStringParams::mapped_type value);
  void clear_param(QueryStringParams::key_type name);
  void clear_params();

  // Caller retains ownership
  void set_progress_fn(ProgressFn progress_fn) { progress_fn_ = progress_fn; }
  void clear_progress_fn() { progress_fn_ = nullptr; }

  // Request timeout
  void set_timeout_millis(long millis);

  void UpdateUrl();

 private:
  void CommonSetup();

  CURLcode Execute();

  // owned
  std::shared_ptr<CURL> handle_;
  struct curl_slist *curl_headers_;
  Url url_;

  std::string user_agent_;
  Headers headers_;
  QueryStringParams params_;
  ProgressFn progress_fn_;

  DISALLOW_COPY_AND_ASSIGN(Request);
};

}  // namespace http

#endif  // HTTP_REQUEST_H
