/**
 *
 * 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 "unit/TestBase.h"

#include "c2/C2Agent.h"
#include "protocols/RESTProtocol.h"
#include "protocols/RESTSender.h"
#include "integration/HTTPIntegrationBase.h"
#include "integration/HTTPHandlers.h"
#include "minifi-cpp/io/ArchiveStream.h"
#include "unit/EmptyFlow.h"
#include "properties/Configuration.h"
#include "unit/Catch.h"

using namespace std::literals::chrono_literals;

namespace org::apache::nifi::minifi::test {

class VerifyDebugInfo : public VerifyC2Base {
 public:
  explicit VerifyDebugInfo(const std::filesystem::path& test_file_location, std::function<bool()> verify)
    : VerifyC2Base(test_file_location), verify_(std::move(verify)) {}

  void testSetup() override {
    LogTestController::getInstance().setTrace<minifi::c2::C2Agent>();
    LogTestController::getInstance().setDebug<minifi::c2::RESTSender>();
    LogTestController::getInstance().setDebug<minifi::c2::RESTProtocol>();
    VerifyC2Base::testSetup();
  }

  void runAssertions() override {
    REQUIRE(utils::verifyEventHappenedInPollTime(std::chrono::seconds(300), verify_));
  }

  void configureC2() override {
    VerifyC2Base::configureC2();
    configuration->set(org::apache::nifi::minifi::Configuration::nifi_c2_agent_heartbeat_period, "100");
  }

  std::function<bool()> verify_;
};

class C2DebugBundleHandler : public ServerAwareHandler {
 public:
  bool handlePost(CivetServer* /*server*/, struct mg_connection *conn) override {
    std::optional<std::string> file_content;
    mg_form_data_handler form_handler{};
    form_handler.field_found = field_found;
    form_handler.field_get = field_get;
    form_handler.user_data = &file_content;
    mg_handle_form_request(conn, &form_handler);
    REQUIRE(file_content);
    {
      std::lock_guard<std::mutex> lock(mtx_);
      bundles_.push_back(std::move(*file_content));
    }
    mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: "
                      "text/plain\r\nContent-Length: 0\r\nConnection: close\r\n\r\n");
    return true;
  }

  std::vector<std::string> getBundles() {
    std::lock_guard<std::mutex> lock(mtx_);
    return bundles_;
  }

 private:
  static int field_found(const char* key, const char* filename, char* /*path*/, size_t /*pathlen*/, void* user_data) {
    auto& file_content = *static_cast<std::optional<std::string>*>(user_data);
    if (!filename || std::string(filename) != "debug.tar.gz") {
      throw std::runtime_error("Unknown form entry: " + std::string{key});
    }
    if (file_content) {
      throw std::runtime_error("Debug archive has already been extracted: " + std::string{key});
    }
    return MG_FORM_FIELD_STORAGE_GET;
  }
  static int field_get(const char* /*key*/, const char* value, size_t valuelen, void* user_data) {
    auto& file_content = *static_cast<std::optional<std::string>*>(user_data);
    if (!file_content) {
      file_content = "";
    }
    (*file_content) += std::string(value, valuelen);
    return MG_FORM_FIELD_HANDLE_GET;
  }

  std::mutex mtx_;
  std::vector<std::string> bundles_;
};

class C2HeartbeatHandler : public ServerAwareHandler {
 public:
  bool handlePost(CivetServer* /*server*/, struct mg_connection *conn) override {
    if (response_) {
      mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: "
                      "text/plain\r\nContent-Length: %lu\r\nConnection: close\r\n\r\n",
                response_->length());
      mg_printf(conn, "%s", response_->c_str());
      response_.reset();
    } else {
      mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: "
                      "text/plain\r\nContent-Length: 0\r\nConnection: close\r\n\r\n");
    }

    return true;
  }

  void setC2RestResponse(const std::string& url) {
    response_ =
      R"({
        "operation" : "heartbeat",
        "requested_operations": [{
          "operation" : "transfer",
          "operationid" : "79",
          "name": "debug",
          "args": {"target": ")" + url + R"("}
        }]
      })";
  }

 private:
  std::optional<std::string> response_;
};

static std::string properties_file = "some.dummy.content = here\n";
static std::string c2_properties_file = "c2.dummy.content = content\n";
static std::string log_properties_file = "log.dummy.content = log\n";
static std::string extra_log_properties_file = "extra.log.dummy.content = extra\n";
static std::string flow_config_file = empty_flow;

TEST_CASE("C2DebugBundleTest", "[c2test]") {
  TestController controller;

  C2HeartbeatHandler heartbeat_handler;
  C2AcknowledgeHandler ack_handler;
  C2DebugBundleHandler bundle_handler;

  std::filesystem::path home_dir = controller.createTempDirectory();
  minifi::utils::file::PathUtils::create_dir(home_dir / "conf");
  minifi::utils::file::PathUtils::create_dir(home_dir / "conf" / "minifi.properties.d");
  minifi::utils::file::PathUtils::create_dir(home_dir / "conf" / "minifi-log.properties.d");
  std::ofstream{home_dir / "conf" / "minifi.properties", std::ios::binary} << properties_file;
  std::ofstream{home_dir / "conf" / "minifi.properties.d" / "90_c2.properties", std::ios::binary} << c2_properties_file;
  std::ofstream{home_dir / "conf" / "minifi-log.properties", std::ios::binary} << log_properties_file;
  std::ofstream{home_dir / "conf" / "minifi-log.properties.d" / "99_c2.properties", std::ios::binary} << extra_log_properties_file;
  std::ofstream{home_dir / "conf" / "config.yml", std::ios::binary} << flow_config_file;

  VerifyDebugInfo harness(home_dir / "conf" / "config.yml", [&]() -> bool {
    if (!ack_handler.isAcknowledged("79")) {
      return false;
    }
    auto bundles = bundle_handler.getBundles();
    REQUIRE(bundles.size() == 1);
    // verify the bundle
    auto bundle_stream = std::make_shared<minifi::io::BufferStream>();
    bundle_stream->write(reinterpret_cast<const uint8_t*>(bundles[0].data()), bundles[0].length());
    auto archive_provider = core::ClassLoader::getDefaultClassLoader().instantiate<minifi::io::ArchiveStreamProvider>(
        "ArchiveStreamProvider", "ArchiveStreamProvider");
    REQUIRE(archive_provider);
    auto decompressor = archive_provider->createReadStream(bundle_stream);
    REQUIRE(decompressor);
    std::map<std::string, std::string> archive_content;
    while (auto info = decompressor->nextEntry()) {
      std::string file_content;
      file_content.resize(info->size);
      REQUIRE(decompressor->read(as_writable_bytes(std::span(file_content))) ==
              file_content.length());
      archive_content[info->filename] = std::move(file_content);
    }
    CHECK(archive_content["minifi.properties"] == properties_file);
    CHECK(archive_content["minifi.properties.d/90_c2.properties"] == c2_properties_file);
    CHECK(archive_content["minifi-log.properties"] == log_properties_file);
    CHECK(archive_content["minifi-log.properties.d/99_c2.properties"] == extra_log_properties_file);
    CHECK(archive_content["config.yml"] == flow_config_file);
    auto log_gz = archive_content["minifi.log.gz"];
    auto log_stream = std::make_shared<minifi::io::BufferStream>();
    {
      minifi::io::ZlibDecompressStream log_decompressor(gsl::make_not_null(log_stream.get()));
      log_decompressor.write(reinterpret_cast<const uint8_t*>(log_gz.data()), log_gz.length());
    }
    std::string log_text;
    log_text.resize(log_stream->size());
    log_stream->read(as_writable_bytes(std::span(log_text)));
    CHECK(log_text.find("Tis but a scratch") != std::string::npos);
    CHECK(archive_content["manifest.json"].find("minifi-archive-extensions") != std::string::npos);
    return true;
  });

  harness.getLoggerProperties()->loadConfigureFile(home_dir / "conf" / "minifi-log.properties");
  harness.getConfiguration()->loadConfigureFile(home_dir / "conf" / "minifi.properties");
  harness.setUrl("http://localhost:0/heartbeat", &heartbeat_handler);
  harness.setUrl("http://localhost:0/acknowledge", &ack_handler);
  harness.setUrl("http://localhost:0/debug_bundle", &bundle_handler);
  harness.setC2Url("/heartbeat", "/acknowledge");

  heartbeat_handler.setC2RestResponse("http://localhost:" + harness.getWebPort() + "/debug_bundle");

  logging::LoggerFactory<C2HeartbeatHandler>::getLogger()->log_error("Tis but a scratch");

  harness.run();
}

TEST_CASE("Test that the debug bundle operation works when config.yml does not exist", "[c2test]") {
  TestController controller;

  C2HeartbeatHandler heartbeat_handler;
  C2AcknowledgeHandler ack_handler;
  C2DebugBundleHandler bundle_handler;

  std::filesystem::path home_dir = controller.createTempDirectory();
  minifi::utils::file::PathUtils::create_dir(home_dir / "conf");
  std::ofstream{home_dir / "conf" / "minifi.properties", std::ios::binary} << properties_file;
  std::ofstream{home_dir / "conf" / "minifi-log.properties", std::ios::binary} << log_properties_file;

  VerifyDebugInfo harness(home_dir / "conf" / "config.yml", [&]() -> bool {
    if (!ack_handler.isAcknowledged("79")) {
      return false;
    }
    auto bundles = bundle_handler.getBundles();
    REQUIRE(bundles.size() == 1);
    return true;
  });

  harness.getConfiguration()->loadConfigureFile(home_dir / "conf" / "minifi.properties");
  harness.getLoggerProperties()->loadConfigureFile(home_dir / "conf" / "minifi-log.properties");
  harness.setUrl("http://localhost:0/heartbeat", &heartbeat_handler);
  harness.setUrl("http://localhost:0/acknowledge", &ack_handler);
  harness.setUrl("http://localhost:0/debug_bundle", &bundle_handler);
  harness.setC2Url("/heartbeat", "/acknowledge");

  heartbeat_handler.setC2RestResponse("http://localhost:" + harness.getWebPort() + "/debug_bundle");

  harness.run();
}

}  // namespace org::apache::nifi::minifi::test
