/**
 *
 * 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 EXTENSIONS_HTTPCURL_TESTS_HTTPINTEGRATIONBASE_H
#define EXTENSIONS_HTTPCURL_TESTS_HTTPINTEGRATIONBASE_H

#include "CivetServer.h"
#include "integration/IntegrationBase.h"
#include "c2/C2Agent.h"
#include "protocols/RESTSender.h"
#include "ServerAwareHandler.h"
#include "TestBase.h"
#include "TestServer.h"

int log_message(const struct mg_connection *conn, const char *message) {
  puts(message);
  return 1;
}

int ssl_enable(void* /*ssl_context*/, void* /*user_data*/) {
  return 0;
}

class HTTPIntegrationBase : public IntegrationBase {
public:
  explicit HTTPIntegrationBase(uint64_t waitTime = DEFAULT_WAITTIME_MSECS)
      : IntegrationBase(waitTime),
        server(nullptr) {
  }

  void setUrl(const std::string &url, ServerAwareHandler *handler);

  void shutdownBeforeFlowController() override {
    server.reset();
  }

  std::string getWebPort() {
    std::string ret_val = port;
    if (ret_val.back() == 's') {
      ret_val = ret_val.substr(0, ret_val.size() - 1);
    }
    return ret_val;
  }

  std::string getC2RestUrl() const {
    std::string c2_rest_url;
    configuration->get("nifi.c2.rest.url", c2_rest_url);
    return c2_rest_url;
  }

 protected:
  std::unique_ptr<TestServer> server;
};

void HTTPIntegrationBase::setUrl(const std::string &url, ServerAwareHandler *handler) {
  parse_http_components(url, port, scheme, path);
  CivetCallbacks callback{};
  if (server) {
    server->addHandler(path, handler);
    return;
  }
  if (scheme == "https" && !key_dir.empty()) {
    std::string cert = key_dir + "nifi-cert.pem";
    memset(&callback, 0, sizeof(callback));
    callback.init_ssl = ssl_enable;
    port += "s";
    callback.log_message = log_message;
    server = utils::make_unique<TestServer>(port, path, handler, &callback, cert, cert);
  } else {
    server = utils::make_unique<TestServer>(port, path, handler);
  }
  bool secure{false};
  if (port == "0" || port == "0s") {
    secure = (port == "0s");
    port = std::to_string(server->getListeningPorts()[0]);
    if (secure) {
      port += "s";
    }
  }
  std::string c2_url = std::string("http") + (secure ? "s" : "") + "://localhost:" + getWebPort() + path;
  configuration->set("nifi.c2.rest.url", c2_url);
  configuration->set("nifi.c2.rest.url.ack", c2_url);
}

class VerifyC2Base : public HTTPIntegrationBase {
public:
  void testSetup() override {
    LogTestController::getInstance().setDebug<utils::HTTPClient>();
    LogTestController::getInstance().setDebug<LogTestController>();
  }

  void configureC2() override {
    configuration->set("nifi.c2.agent.protocol.class", "RESTSender");
    configuration->set("nifi.c2.enable", "true");
    configuration->set("nifi.c2.agent.class", "test");
    configuration->set("nifi.c2.agent.heartbeat.period", "1000");
    configuration->set("nifi.c2.root.classes", "DeviceInfoNode,AgentInformation,FlowInformation");
  }

  void cleanup() override {
    LogTestController::getInstance().reset();
  }
};

class VerifyC2Describe : public VerifyC2Base {
 public:
  void testSetup() override {
    LogTestController::getInstance().setTrace<minifi::c2::C2Agent>();
    LogTestController::getInstance().setDebug<minifi::c2::RESTSender>();
    LogTestController::getInstance().setInfo<minifi::FlowController>();
    VerifyC2Base::testSetup();
  }

  void configureFullHeartbeat() override {
    configuration->set("nifi.c2.full.heartbeat", "false");
  }

  void runAssertions() override {
  }
};

class VerifyC2Update : public HTTPIntegrationBase {
public:
  explicit VerifyC2Update(uint64_t waitTime)
      : HTTPIntegrationBase(waitTime) {
  }

  void testSetup() override {
    LogTestController::getInstance().setInfo<minifi::FlowController>();
    LogTestController::getInstance().setDebug<minifi::utils::HTTPClient>();
    LogTestController::getInstance().setDebug<minifi::c2::RESTSender>();
    LogTestController::getInstance().setDebug<minifi::c2::C2Agent>();
  }

  void configureC2() override {
    configuration->set("nifi.c2.agent.protocol.class", "RESTSender");
    configuration->set("nifi.c2.enable", "true");
    configuration->set("nifi.c2.agent.class", "test");
    configuration->set("nifi.c2.agent.heartbeat.period", "1000");
  }

  void cleanup() override {
    LogTestController::getInstance().reset();
  }

  void runAssertions() override {
    assert(LogTestController::getInstance().contains("Starting to reload Flow Controller with flow control name MiNiFi Flow, version"));
  }
};

class VerifyC2UpdateAgent : public VerifyC2Update {
 public:
  explicit VerifyC2UpdateAgent(uint64_t waitTime)
      : VerifyC2Update(waitTime) {
  }

  void configureC2() override {
    VerifyC2Update::configureC2();
    configuration->set("nifi.c2.agent.update.allow","true");
    configuration->set("c2.agent.update.command", "echo \"verification command\"");
  }

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

  void runAssertions() override {
    assert(LogTestController::getInstance().contains("removing file"));
    assert(LogTestController::getInstance().contains("May not have command processor"));
  }
};

class VerifyC2FailedUpdate : public VerifyC2Update {
public:
  explicit VerifyC2FailedUpdate(uint64_t waitTime)
      : VerifyC2Update(waitTime) {
  }

  void testSetup() override {
    LogTestController::getInstance().setInfo<minifi::FlowController>();
    LogTestController::getInstance().setDebug<minifi::c2::C2Agent>();
    utils::file::FileUtils::create_dir("content_repository");
  }

  void runAssertions() override {
    assert(LogTestController::getInstance().contains("Invalid configuration payload"));
    assert(LogTestController::getInstance().contains("update failed"));
  }

  void cleanup() override {
    utils::file::FileUtils::delete_dir("content_repository", true);
    VerifyC2Update::cleanup();
  }
};
#endif  // EXTENSIONS_HTTPCURL_TESTS_HTTPINTEGRATIONBASE_H
