/**
 *
 * 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 <signal.h>
#include <sys/stat.h>
#include <chrono>
#include <thread>
#include <filesystem>
#undef NDEBUG
#include <cassert>
#include <utility>
#include <memory>
#include <string>
#include "properties/Configure.h"
#include "io/tls/TLSSocket.h"
#include "SimpleSSLTestServer.h"

namespace minifi = org::apache::nifi::minifi;

class SimpleSSLTestServerTLSv1  : public SimpleSSLTestServer {
 public:
  SimpleSSLTestServerTLSv1(int port, const std::filesystem::path& key_dir)
      : SimpleSSLTestServer(TLSv1_server_method(), port, key_dir) {
  }
};

class SimpleSSLTestServerTLSv1_1  : public SimpleSSLTestServer {
 public:
  SimpleSSLTestServerTLSv1_1(int port, const std::filesystem::path& key_dir)
      : SimpleSSLTestServer(TLSv1_1_server_method(), port, key_dir) {
  }
};

class SimpleSSLTestServerTLSv1_2  : public SimpleSSLTestServer {
 public:
  SimpleSSLTestServerTLSv1_2(int port, const std::filesystem::path& key_dir)
      : SimpleSSLTestServer(TLSv1_2_server_method(), port, key_dir) {
  }
};

class TLSClientSocketSupportedProtocolsTest {
 public:
  explicit TLSClientSocketSupportedProtocolsTest(const std::filesystem::path& key_dir)
      : key_dir_(key_dir), configuration_(std::make_shared<minifi::Configure>()) {
  }

  void run() {
    configureSecurity();

    verifyTLSClientSocketExclusiveCompatibilityWithTLSv1_2();
  }


 protected:
  void configureSecurity() {
    host_ = minifi::io::Socket::getMyHostName();
    if (!key_dir_.empty()) {
      configuration_->set(minifi::Configure::nifi_remote_input_secure, "true");
      configuration_->set(minifi::Configure::nifi_security_client_certificate, (key_dir_ / "cn.crt.pem").string());
      configuration_->set(minifi::Configure::nifi_security_client_private_key, (key_dir_ / "cn.ckey.pem").string());
      configuration_->set(minifi::Configure::nifi_security_client_pass_phrase, (key_dir_ / "cn.pass").string());
      configuration_->set(minifi::Configure::nifi_security_client_ca_certificate, (key_dir_ / "nifi-cert.pem").string());
      configuration_->set(minifi::Configure::nifi_default_directory, key_dir_.string());
    }
  }

  void verifyTLSClientSocketExclusiveCompatibilityWithTLSv1_2() {
    verifyTLSProtocolCompatibility<SimpleSSLTestServerTLSv1>(false);
    verifyTLSProtocolCompatibility<SimpleSSLTestServerTLSv1_1>(false);
    verifyTLSProtocolCompatibility<SimpleSSLTestServerTLSv1_2>(true);
  }

  template <class TLSTestSever>
  void verifyTLSProtocolCompatibility(const bool should_be_compatible) {
    // bind to random port
    TLSTestSever server(0, key_dir_);
    server.waitForConnection();

    int port = server.getPort();

    const auto socket_context = std::make_shared<minifi::io::TLSContext>(configuration_);
    client_socket_ = std::make_unique<minifi::io::TLSSocket>(socket_context, host_, port, 0);
    const bool client_initialized_successfully = (client_socket_->initialize() == 0);
    assert(client_initialized_successfully == should_be_compatible);
    server.shutdownServer();
    assert(server.hadConnection() == should_be_compatible);
  }

 protected:
    std::unique_ptr<minifi::io::TLSSocket> client_socket_;
    std::string host_;
    std::filesystem::path key_dir_;
    std::shared_ptr<minifi::Configure> configuration_;
};

static void sigpipe_handle(int) {
}

int main(int argc, char **argv) {
  std::string key_dir;
  if (argc > 1) {
    key_dir = argv[1];
  }
#ifndef WIN32
  signal(SIGPIPE, sigpipe_handle);
#endif

  TLSClientSocketSupportedProtocolsTest client_socket_supported_protocols_verifier(key_dir);

  client_socket_supported_protocols_verifier.run();

  return 0;
}
