/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 LIBMINIFI_INCLUDE_UTILS_BaseHTTPClient_H_
#define LIBMINIFI_INCLUDE_UTILS_BaseHTTPClient_H_
#include "ByteArrayCallback.h"
#include "controllers/SSLContextService.h"
namespace org {
namespace apache {
namespace nifi {
namespace minifi {
namespace utils {

struct HTTPProxy {
  std::string host;
  std::string username;
  std::string password;
  int port;
};

struct HTTPUploadCallback {
  HTTPUploadCallback() {
    stop = false;
    ptr = nullptr;
    pos = 0;
  }
  std::mutex mutex;
  std::atomic<bool> stop;
  ByteInputCallBack *ptr;
  size_t pos;

  size_t getPos() {
    std::lock_guard<std::mutex> lock(mutex);
    return pos;
  }
};

struct HTTPReadCallback {
  HTTPReadCallback() {
    stop = false;
    ptr = nullptr;
    pos = 0;
  }
  std::mutex mutex;
  std::atomic<bool> stop;
  ByteOutputCallback *ptr;
  size_t pos;

  size_t getPos() {
    std::lock_guard<std::mutex> lock(mutex);
    return pos;
  }
};

struct HTTPHeaderResponse {
 public:

  HTTPHeaderResponse(int max)
      : max_tokens_(max) {
  }

  void append(const std::string &header) {
    if (max_tokens_ == -1 || (int32_t)header_tokens_.size() <= max_tokens_) {
      header_tokens_.push_back(header);
    }
  }

  void append(const std::string &key, const std::string &value) {
    header_mapping_[key].append(value);
  }

  int32_t max_tokens_;
  std::vector<std::string> header_tokens_;
  std::map<std::string, std::string> header_mapping_;

  static size_t receive_headers(void *buffer, size_t size, size_t nmemb, void *userp) {
    HTTPHeaderResponse *pHeaders = (HTTPHeaderResponse *) (userp);
    int result = 0;
    if (pHeaders != NULL) {
      std::string s = "";
      s.append((char*) buffer, size * nmemb);
      pHeaders->append(s);
      result = size * nmemb;
    }
    return result;
  }
};

/**
 * HTTP Response object
 */
class HTTPRequestResponse {

  std::vector<char> data;
  std::condition_variable space_available_;
  std::mutex data_mutex_;

  size_t max_queue;

 public:

  const std::vector<char> &getData() {
    return data;
  }

  HTTPRequestResponse(const HTTPRequestResponse &other)
      : max_queue(other.max_queue) {

  }

  HTTPRequestResponse(size_t max)
      : max_queue(max) {

  }
  /**
   * Receive HTTP Response.
   */
  static size_t recieve_write(char * data, size_t size, size_t nmemb, void * p) {
    HTTPReadCallback *callback = static_cast<HTTPReadCallback*>(p);
    if (callback->stop)
      return 0x10000000;
    callback->ptr->write(data, (size * nmemb));
    return (size * nmemb);
  }

  /**
   * Callback for post, put, and patch operations
   * @param buffer
   * @param size size of buffer
   * @param nitems items to add
   * @param insteam input stream object.
   */

  static size_t send_write(char * data, size_t size, size_t nmemb, void * p) {
    if (p != 0) {
      HTTPUploadCallback *callback = (HTTPUploadCallback*) p;
      if (callback->stop)
        return 0x10000000;
      size_t buffer_size = callback->ptr->getBufferSize();
      if (callback->getPos() <= buffer_size) {
        size_t len = buffer_size - callback->pos;
        if (len <= 0)
        {
          return 0;
        }
        char *ptr = callback->ptr->getBuffer(callback->getPos());

        if (ptr == nullptr) {
          return 0;
        }
        if (len > size * nmemb)
          len = size * nmemb;
        auto strr = std::string(ptr,len);
        memcpy(data, ptr, len);
        callback->pos += len;
        callback->ptr->seek(callback->getPos());
        return len;
      }
    } else {
      return 0x10000000;
    }
    return 0;
  }

  int read_data(uint8_t *buf, size_t size) {
    size_t size_to_read = size;
    if (size_to_read > data.size()) {
      size_to_read = data.size();
    }
    memcpy(buf, data.data(), size_to_read);
    return size_to_read;
  }

  size_t write_content(char* ptr, size_t size, size_t nmemb) {

    if (data.size() + (size * nmemb) > max_queue) {
      std::unique_lock<std::mutex> lock(data_mutex_);
      space_available_.wait(lock, [&] {return data.size() + (size*nmemb) < max_queue;});
    }
    data.insert(data.end(), ptr, ptr + size * nmemb);
    return size * nmemb;
  }

};

class BaseHTTPClient {
 public:
  explicit BaseHTTPClient(const std::string &url, const std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service = nullptr) {
    response_code = -1;
  }

  explicit BaseHTTPClient() {
    response_code = -1;
  }

  virtual ~BaseHTTPClient() {
  }

  virtual void setVerbose() {
  }

  virtual void initialize(const std::string &method, const std::string url = "", const std::shared_ptr<minifi::controllers::SSLContextService> ssl_context_service = nullptr) {
  }

  virtual void setConnectionTimeout(int64_t timeout) {
  }

  virtual void setReadTimeout(int64_t timeout) {
  }

  virtual void setUploadCallback(HTTPUploadCallback *callbackObj) {
  }

  virtual void setContentType(std::string content_type) {
  }

  virtual std::string escape(std::string string_to_escape) {
    return "";
  }

  virtual void setPostFields(std::string input) {
  }

  virtual bool submit() {
    return false;
  }

  virtual int64_t &getResponseCode() {
    return response_code;
  }

  virtual const char *getContentType() {
    return "";
  }

  virtual const std::vector<char> &getResponseBody() {
    return response_body_;
  }

  virtual void appendHeader(const std::string &new_header) {

  }

  virtual void set_request_method(const std::string method) {
  }

  virtual void setUseChunkedEncoding() {
  }

  virtual void setDisablePeerVerification() {
  }

  virtual void setHTTPProxy(const utils::HTTPProxy &proxy) {
  }

  virtual void setDisableHostVerification() {
  }

  virtual const std::vector<std::string> &getHeaders() {
    return headers_;

  }

  virtual const std::map<std::string, std::string> &getParsedHeaders() {
    return header_mapping_;
  }

 protected:
  int64_t response_code;
  std::vector<char> response_body_;
  std::vector<std::string> headers_;
  std::map<std::string, std::string> header_mapping_;

  virtual inline bool matches(const std::string &value, const std::string &sregex) {
    return false;
  }

};

extern std::string get_token(utils::BaseHTTPClient *client, std::string username, std::string password);

extern void parse_url(std::string *url, std::string *host, int *port, std::string *protocol);
extern void parse_url(std::string *url, std::string *host, int *port, std::string *protocol, std::string *path, std::string *query);
} /* namespace utils */
} /* namespace minifi */
} /* namespace nifi */
} /* namespace apache */
} /* namespace org */

#endif /* LIBMINIFI_INCLUDE_UTILS_BaseHTTPClient_H_ */
