#ifndef THIRD_PARTY_GBMCWEB_HTTP_HTTP_SERVER_H_
#define THIRD_PARTY_GBMCWEB_HTTP_HTTP_SERVER_H_

#ifdef BMCWEB_ENABLE_GRPC
#include "absl/log/log.h"
#include "bmcweb_authorizer_singleton.h"
#endif

#include <chrono>  // NOLINT
#include <csignal>
#include <cstdint>
#include <ctime>
#include <functional>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>

#include "boost/asio/ip/address.hpp"  // NOLINT
#include "boost/asio/ip/tcp.hpp"  // NOLINT
#include "boost/asio/signal_set.hpp"  // NOLINT
#include "boost/asio/ssl/context.hpp"  // NOLINT
#include "boost/asio/steady_timer.hpp"  // NOLINT
#include "boost/beast/ssl/ssl_stream.hpp"  // NOLINT
#include "http_connection.hpp"
#include "logging.hpp"

namespace crow {

template <typename Handler, typename Adaptor = boost::asio::ip::tcp::socket>
class Server {
 public:
  Server(Handler* handlerIn,
         std::unique_ptr<boost::asio::ip::tcp::acceptor>&& acceptorIn,
         std::shared_ptr<boost::asio::ssl::context> adaptorCtxIn,
         std::shared_ptr<boost::asio::io_context> io =
             std::make_shared<boost::asio::io_context>())
      : ioService(std::move(io)),
        acceptor(std::move(acceptorIn)),
        signals(*ioService, SIGHUP, SIGINT),
        handler(handlerIn),
        adaptorCtx(std::move(adaptorCtxIn)) {}

  Server(Handler* handlerIn, const std::string& bindaddr, uint16_t port,
         const std::shared_ptr<boost::asio::ssl::context>& adaptorCtxIn,
         const std::shared_ptr<boost::asio::io_context>& io =
             std::make_shared<boost::asio::io_context>())
      : Server(handlerIn,
               std::make_unique<boost::asio::ip::tcp::acceptor>(
                   *io, boost::asio::ip::tcp::endpoint(
                            boost::asio::ip::make_address(bindaddr), port)),
               adaptorCtxIn, io) {}

  Server(Handler* handlerIn, int existingSocket,
         const std::shared_ptr<boost::asio::ssl::context>& adaptorCtxIn,
         const std::shared_ptr<boost::asio::io_context>& io =
             std::make_shared<boost::asio::io_context>())
      : Server(handlerIn,
               std::make_unique<boost::asio::ip::tcp::acceptor>(
                   *io, boost::asio::ip::tcp::v6(), existingSocket),
               adaptorCtxIn, io) {}

  ~Server() { stop(); }
  Server(const Server&) = default;
  Server& operator=(const Server&) = default;
  Server(Server&&) noexcept = default;
  Server& operator=(Server&&) noexcept = default;

  void updateDateStr() {
    time_t last_time_t = time(nullptr);
    tm my_tm{};

    gmtime_r(&last_time_t, &my_tm);

    dateStr.resize(100);
    size_t date_str_sz =
        strftime(&dateStr[0], 99, "%a, %d %b %Y %H:%M:%S GMT", &my_tm);
    dateStr.resize(date_str_sz);
  }

  void run() {
    loadCertificate();
    updateDateStr();

    getCachedDateStr = [this]() -> std::string {
      static std::chrono::time_point<std::chrono::steady_clock> lastDateUpdate =
          std::chrono::steady_clock::now();
      if (std::chrono::steady_clock::now() - lastDateUpdate >=
          std::chrono::seconds(10)) {
        lastDateUpdate = std::chrono::steady_clock::now();
        updateDateStr();
      }
      return this->dateStr;
    };

    BMCWEB_LOG_INFO << "bmcweb server is running, local endpoint "
                    << acceptor->local_endpoint().address().to_string();
    startAsyncWaitForSignal();
    doAccept();
  }

  void loadCertificate() {
#ifdef BMCWEB_ENABLE_SSL
    namespace fs = std::filesystem;
    // Cleanup older certificate file existing in the system
    fs::path oldCert = "/home/root/server.pem";
    if (fs::exists(oldCert)) {
      fs::remove("/home/root/server.pem");
    }
    fs::path certPath = "/etc/ssl/certs/https/";
    // if path does not exist create the path so that
    // self signed certificate can be created in the
    // path
    if (!fs::exists(certPath)) {
      fs::create_directories(certPath);
    }
    fs::path certFile = certPath / "server.pem";
    BMCWEB_LOG_INFO << "Building SSL Context file=" << certFile.string();
    std::string sslPemFile(certFile);
    ensuressl::ensureOpensslKeyPresentAndValid(sslPemFile);
    std::shared_ptr<boost::asio::ssl::context> sslContext =
        ensuressl::getSslContext(sslPemFile);
    adaptorCtx = sslContext;
    handler->ssl(std::move(sslContext));
#endif
  }

  void startAsyncWaitForSignal() {
    signals.async_wait([this](const boost::system::error_code& ec,
                              int signalNo) {
      if (ec) {
        BMCWEB_LOG_INFO << "Error in signal handler" << ec.message();
      } else {
        if (signalNo == SIGHUP) {
          BMCWEB_LOG_INFO << "Receivied reload signal";

#ifdef BMCWEB_ENABLE_GRPC
          constexpr const char* persistentBasePrivilegesFolder =
              "/var/google/authz_policies";
          constexpr const char* rofsBasePrivilegesFolder =
              "/usr/share/redfish_privileges";
          ::milotic::authz::BmcWebAuthorizerSingleton& authorizer =
              ::milotic::authz::BmcWebAuthorizerSingleton::GetInstance();
          // Check persistent data first
          authorizer.SetBasePrivilegesFolder(persistentBasePrivilegesFolder);
          // If privilege registry does not exist, check rofs
          if (!authorizer.IsBasePrivilegeRegistryFound()) {
            LOG(WARNING) << "Could not find Privilege Registry at "
                            "/var/google/authz_policies";
            authorizer.SetBasePrivilegesFolder(rofsBasePrivilegesFolder);
          }

          // reload authz config
          authorizer.ReloadConfiguration();
#endif

          loadCertificate();
          boost::system::error_code ec2;
          // NOLINTNEXTLINE(bugprone-unused-return-value)
          acceptor->cancel(ec2);
          if (ec2) {
            BMCWEB_LOG_ERROR << "Error while canceling async operations:"
                             << ec2.message();
          }
          this->startAsyncWaitForSignal();
        } else {
          stop();
        }
      }
    });
  }

  void stop() { ioService->stop(); }

  void doAccept() {
    boost::asio::steady_timer timer(*ioService);
    std::shared_ptr<Connection<Adaptor, Handler>> connection;
    if constexpr (std::is_same<Adaptor,
                               boost::beast::ssl_stream<
                                   boost::asio::ip::tcp::socket>>::value) {
      connection = std::make_shared<Connection<Adaptor, Handler>>(
          handler, std::move(timer), getCachedDateStr,
          Adaptor(*ioService, *adaptorCtx));
    } else {
      connection = std::make_shared<Connection<Adaptor, Handler>>(
          handler, std::move(timer), getCachedDateStr, Adaptor(*ioService));
    }
    acceptor->async_accept(
        boost::beast::get_lowest_layer(connection->socket()),
        [this, connection](const boost::system::error_code& ec) {
          if (!ec) {
            connection->setKeepAlive();
            boost::asio::post(*this->ioService,
                              [connection] { connection->start(); });
          }
          doAccept();
        });
  }

 private:
  std::shared_ptr<boost::asio::io_context> ioService;        // NOLINT
  std::function<std::string()> getCachedDateStr;             // NOLINT
  std::unique_ptr<boost::asio::ip::tcp::acceptor> acceptor;  // NOLINT
  boost::asio::signal_set signals;                           // NOLINT

  std::string dateStr;  // NOLINT

  Handler* handler;  // NOLINT

  std::shared_ptr<boost::asio::ssl::context> adaptorCtx;  // NOLINT
};
}  // namespace crow

#endif  // THIRD_PARTY_GBMCWEB_HTTP_HTTP_SERVER_H_
