/**
 *
 * 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.
 */

#include <utility>
#include <vector>
#include <string>
#include "TestBase.h"
#include "Catch.h"
#include "client/HTTPClient.h"
#include "CivetServer.h"
#include "ConnectionCountingServer.h"
#include "magic_enum.hpp"
#include "utils/BaseHTTPClient.h"

using namespace std::literals::chrono_literals;

namespace org::apache::nifi::minifi::extensions::curl::testing {

TEST_CASE("HTTPClientTestChunkedResponse", "[basic]") {
  LogTestController::getInstance().setDebug<HTTPClient>();

  class Responder : public CivetHandler {
   public:
    static void send_response(struct mg_connection *conn) {
      mg_printf(conn, "HTTP/1.1 200 OK\r\n");
      mg_printf(conn, "Content-Type: application/octet-stream\r\n");
      mg_printf(conn, "Transfer-Encoding: chunked\r\n");
      mg_printf(conn, "X-Custom-Test: whatever\r\n");
      mg_printf(conn, "\r\n");
      mg_send_chunk(conn, "foo", 3U);
      mg_send_chunk(conn, "bar\r\n", 5U);
      mg_send_chunk(conn, "buzz", 4U);
      mg_send_chunk(conn, nullptr, 0U);
    }

    bool handleGet(CivetServer* /*server*/, struct mg_connection* conn) override {
      send_response(conn);
      return true;
    }

    bool handlePost(CivetServer* /*server*/, struct mg_connection* conn) override {
      mg_printf(conn, "HTTP/1.1 100 Continue\r\n\r\n");

      std::array<uint8_t, 16384U> buf{};
      while (mg_read(conn, buf.data(), buf.size()) > 0) {}

      send_response(conn);
      return true;
    }
  };

  std::vector<std::string> options;
  options.emplace_back("enable_keep_alive");
  options.emplace_back("yes");
  options.emplace_back("keep_alive_timeout_ms");
  options.emplace_back("15000");
  options.emplace_back("num_threads");
  options.emplace_back("1");
  options.emplace_back("listening_ports");
  options.emplace_back("0");

  CivetServer server(options);
  Responder responder;
  server.addHandler("**", responder);
  const auto& vec = server.getListeningPorts();
  REQUIRE(1 == vec.size());
  const std::string port = std::to_string(vec.at(0));

  HTTPClient client;
  client.initialize(utils::HttpRequestMethod::GET, "http://localhost:" + port + "/testytesttest", nullptr);

  REQUIRE(client.submit());

  const auto& headers = client.getResponseHeaderMap();
  REQUIRE("whatever" == headers.at("X-Custom-Test"));

  const std::vector<char>& response = client.getResponseBody();
  REQUIRE("foobar\r\nbuzz" == std::string(response.begin(), response.end()));

  LogTestController::getInstance().reset();
}

TEST_CASE("HTTPClient escape test") {
  HTTPClient client;
  CHECK(client.escape("Hello Günter") == "Hello%20G%C3%BCnter");
  CHECK(client.escape("шеллы") == "%D1%88%D0%B5%D0%BB%D0%BB%D1%8B");
}

TEST_CASE("HTTPClient isValidHttpHeaderField test") {
  CHECK_FALSE(HTTPClient::isValidHttpHeaderField(""));
  CHECK(HTTPClient::isValidHttpHeaderField("valid"));
  CHECK_FALSE(HTTPClient::isValidHttpHeaderField(" "));
  CHECK_FALSE(HTTPClient::isValidHttpHeaderField(std::string("invalid") + static_cast<char>(11) + "character"));
  CHECK_FALSE(HTTPClient::isValidHttpHeaderField(std::string("invalid") + static_cast<char>(128) + "character"));
  CHECK_FALSE(HTTPClient::isValidHttpHeaderField("contains:invalid"));
}

TEST_CASE("HTTPClient replaceInvalidCharactersInHttpHeaderFieldName test") {
  CHECK(HTTPClient::replaceInvalidCharactersInHttpHeaderFieldName("") == "X-MiNiFi-Empty-Attribute-Name");
  CHECK(HTTPClient::replaceInvalidCharactersInHttpHeaderFieldName("valid") == "valid");
  CHECK(HTTPClient::replaceInvalidCharactersInHttpHeaderFieldName(" ") == "-");
  CHECK(HTTPClient::replaceInvalidCharactersInHttpHeaderFieldName(std::string("invalid") + static_cast<char>(11) + "character") == "invalid-character");
  CHECK(HTTPClient::replaceInvalidCharactersInHttpHeaderFieldName(std::string("invalid") + static_cast<char>(128) + "character") == "invalid-character");
  CHECK(HTTPClient::replaceInvalidCharactersInHttpHeaderFieldName("contains:invalid") == "contains-invalid");
}

TEST_CASE("HTTPClient should be reusable", "[basic]") {
  LogTestController::getInstance().setDebug<HTTPClient>();

  ConnectionCountingServer keep_alive_server_;

  HTTPClient client;
  client.setKeepAliveProbe(KeepAliveProbeData{2s, 2s});
  client.initialize(utils::HttpRequestMethod::GET, "http://localhost:" + keep_alive_server_.getPort() + "/method", nullptr);

  std::vector<utils::HttpRequestMethod> methods = {
      utils::HttpRequestMethod::GET, utils::HttpRequestMethod::GET, utils::HttpRequestMethod::PUT, utils::HttpRequestMethod::GET,
      utils::HttpRequestMethod::GET, utils::HttpRequestMethod::POST, utils::HttpRequestMethod::POST, utils::HttpRequestMethod::PUT };
  uint64_t request_number = 0;
  for (const auto& method: methods) {
    client.set_request_method(method);
    if (method != utils::HttpRequestMethod::GET) {
      auto callback = std::make_unique<org::apache::nifi::minifi::utils::HTTPUploadByteArrayInputCallback>();
      std::string content = R"({ "content": "a" })";
      callback->write(content);
      client.setRequestHeader("Content-Length", std::to_string(content.size()));
      client.setContentType("application/json");
      client.setUploadCallback(std::move(callback));
    } else {
      client.setRequestHeader("Content-Length", std::to_string(0));
      client.setUploadCallback(nullptr);
    }

    REQUIRE(client.submit());
    const auto& headers = client.getResponseHeaderMap();
    REQUIRE(headers.contains("Response-number"));
    CHECK(std::to_string(request_number) == headers.at("Response-number"));
    const auto& response = client.getResponseBody();
    CHECK(std::string(magic_enum::enum_name(method)) + std::to_string(request_number) == std::string(response.begin(), response.end()));
    ++request_number;
  }

  CHECK(keep_alive_server_.getConnectionCounter() == 1);
  LogTestController::getInstance().reset();
}

#ifdef __linux__
TEST_CASE("SSL without SSLContextService", "[HTTPClient]") {
  HTTPClient client;
  client.initialize(utils::HttpRequestMethod::GET, "https://apache.org", nullptr);
  REQUIRE(client.submit());
}
#endif

}  // namespace org::apache::nifi::minifi::extensions::curl::testing
