#ifndef THIRD_PARTY_GBMCWEB_HTTP_HTTP_CONNECTION_H_
#define THIRD_PARTY_GBMCWEB_HTTP_HTTP_CONNECTION_H_

#include <array>
#include <charconv>
#include <chrono>  // NOLINT
#include <cstddef>
#include <cstdint>
#include <filesystem>  // NOLINT
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <tuple>
#include <utility>

#include "boost/algorithm/string/predicate.hpp"  // NOLINT
#include "boost/asio/io_context.hpp"  // NOLINT
#include "boost/asio/io_context_strand.hpp"  // NOLINT
#include "boost/asio/ip/tcp.hpp"  // NOLINT
#include "boost/asio/post.hpp"  // NOLINT
#include "boost/asio/socket_base.hpp"  // NOLINT
#include "boost/asio/ssl/stream.hpp"  // NOLINT
#include "boost/asio/steady_timer.hpp"  // NOLINT
#include "boost/beast/core/flat_static_buffer.hpp"  // NOLINT
#include "boost/beast/http/error.hpp"  // NOLINT
#include "boost/beast/http/parser.hpp"  // NOLINT
#include "boost/beast/http/read.hpp"  // NOLINT
#include "boost/beast/http/serializer.hpp"  // NOLINT
#include "boost/beast/http/write.hpp"  // NOLINT
#include "boost/beast/ssl/ssl_stream.hpp"  // NOLINT
#include "boost/beast/websocket.hpp"  // NOLINT
#include "bmcweb_config.h"
#include "http_request.hpp"
#include "http_response.hpp"
#include "logging.hpp"
#include "mutual_tls.hpp"
#include "async_resp.hpp"
#include "authentication.hpp"
#include "forward_unauthorized.hpp"
#include "http_utility.hpp"
#include "json_html_serializer.hpp"
#include "security_headers.hpp"
#include "sessions.hpp"
#include "ssl_key_handler.hpp"
#include <nlohmann/json.hpp>

namespace crow {

inline void prettyPrintJson(crow::Response& res) {
  json_html_util::dumpHtml(res.body(), res.jsonValue);

  res.addHeader(boost::beast::http::field::content_type,
                "text/html;charset=UTF-8");
}

// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static int connectionCount = 0;

// request body limit size set by the bmcwebHttpReqBodyLimitMb option
constexpr uint64_t httpReqBodyLimit =
    1024UL * 1024UL * bmcwebHttpReqBodyLimitMb;

constexpr uint64_t loggedOutPostBodyLimit = 4096;

constexpr uint32_t httpHeaderLimit = 8192;

template <typename Adaptor, typename Handler>
class Connection
    : public std::enable_shared_from_this<Connection<Adaptor, Handler>> {
  using self_type = Connection<Adaptor, Handler>;

 public:
  Connection(Handler* handlerIn, boost::asio::steady_timer&& timerIn,
             std::function<std::string()>& getCachedDateStrF, Adaptor adaptorIn)
      : adaptor(std::move(adaptorIn)),
        handler(handlerIn),
        timer(std::move(timerIn)),
        getCachedDateStr(getCachedDateStrF) {
    parser.emplace(std::piecewise_construct, std::make_tuple());
    parser->body_limit(httpReqBodyLimit);
    parser->header_limit(httpHeaderLimit);

#ifdef BMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION
    prepareMutualTls();
#endif  // BMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION

    connectionCount++;

    BMCWEB_LOG_DEBUG << this << " Connection open, total " << connectionCount;
  }

  ~Connection() {
    res.setCompleteRequestHandler(nullptr);
    cancelDeadlineTimer();

    connectionCount--;
    BMCWEB_LOG_DEBUG << this << " Connection closed, total " << connectionCount;
  }

  Connection(const Connection&) = delete;
  Connection(Connection&&) = delete;
  Connection& operator=(const Connection&) = delete;
  Connection& operator=(Connection&&) = delete;

  bool tlsVerifyCallback(bool preverified,
                         boost::asio::ssl::verify_context& ctx) {
    // We always return true to allow full auth flow for resources that
    // don't require auth
    if (preverified) {
      mtlsSession = verifyMtlsUser(req->ipAddress, ctx);
      if (mtlsSession) {
        BMCWEB_LOG_DEBUG << this << " Generating TLS session: "
                         << mtlsSession->uniqueId;
      }
    }
    return true;
  }

  void prepareMutualTls() {
    std::error_code error;
    std::filesystem::path ca_path(ensuressl::trustStorePath);
    auto ca_available = !std::filesystem::is_empty(ca_path, error);
    ca_available = ca_available && !error;
    if (ca_available && persistent_data::SessionStore::getInstance()
                            .getAuthMethodsConfig()
                            .tls) {
      adaptor.set_verify_mode(boost::asio::ssl::verify_peer);
      std::string id = "bmcweb";

      const char* c_str = id.c_str();
      // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
      const auto* id_c = reinterpret_cast<const unsigned char*>(c_str);
      int ret =
          SSL_set_session_id_context(adaptor.native_handle(), id_c,
                                     static_cast<unsigned int>(id.length()));
      if (ret == 0) {
        BMCWEB_LOG_ERROR << this << " failed to set SSL id";
      }
    }

    adaptor.set_verify_callback(
        std::bind_front(&self_type::tlsVerifyCallback, this));
  }

  Adaptor& socket() { return adaptor; }

  void start() {
    if (connectionCount >= 100) {
      BMCWEB_LOG_CRITICAL << this << "Max connection count exceeded.";
      return;
    }

    startDeadline();

    // TODO(ed) Abstract this to a more clever class with the idea of an
    // asynchronous "start"
    if constexpr (std::is_same_v<Adaptor, boost::beast::ssl_stream<
                                              boost::asio::ip::tcp::socket>>) {
      adaptor.async_handshake(boost::asio::ssl::stream_base::server,
                              [this, self(shared_from_this())](
                                  const boost::system::error_code& ec) {
                                if (ec) {
                                  return;
                                }
                                doReadHeaders();
                              });
    } else {
      doReadHeaders();
    }
  }

  void handle() {
    std::error_code req_ec;
    crow::Request& this_req = req.emplace(parser->release(), req_ec);
    if (req_ec) {
      BMCWEB_LOG_DEBUG << "Request failed to construct" << req_ec;
      res.result(boost::beast::http::status::bad_request);
      completeRequest(res);
      return;
    }

    int64_t max_age_sec = 0;
    std::string_view max_age_sec_str =
        this_req.getHeaderValue(bmcweb::BMCWEB_HINT_MAX_AGE_SEC);
    if (!max_age_sec_str.empty()) {
      std::from_chars(max_age_sec_str.data(),
                      max_age_sec_str.data() + max_age_sec_str.size(),
                      max_age_sec);
    }

    BMCWEB_LOG_ALWAYS << "=> Connection: handle: target: " << this_req.target()
                      << " max_age_sec_str: " << max_age_sec_str
                      << " max_age_sec: " << max_age_sec;

    this_req.session = userSession;

    // Fetch the client IP address
    readClientIp();

    // Check for HTTP version 1.1.
    if (this_req.version() == 11) {
      if (this_req.getHeaderValue(boost::beast::http::field::host).empty()) {
        res.result(boost::beast::http::status::bad_request);
        completeRequest(res);
        return;
      }
    }

    BMCWEB_LOG_INFO << "Request: "
                    << " " << this << " HTTP/" << this_req.version() / 10 << "."
                    << this_req.version() % 10 << ' ' << this_req.methodString()
                    << " " << this_req.target() << " "
                    << this_req.ipAddress.to_string();

    std::string uri_string = static_cast<std::string>(this_req.target());
    res.requestStartTime(uri_string);
    res.startTimetrace("BMCWEB");
    res.isAliveHelper = [this]() -> bool { return isAlive(); };

    this_req.ioService = static_cast<decltype(this_req.ioService)>(
        &adaptor.get_executor().context());

    if (res.completed) {
      completeRequest(res);
      return;
    }
    keepAlive = this_req.keepAlive();
#ifndef BMCWEB_INSECURE_DISABLE_AUTHX
    if (!crow::authentication::isOnAllowlist(req->url().buffer(),
                                             req->method()) &&
        this_req.session == nullptr) {
      BMCWEB_LOG_WARNING << "Authentication failed";
      forward_unauthorized::sendUnauthorized(
          req->url().encoded_path(), req->getHeaderValue("X-Requested-With"),
          req->getHeaderValue("Accept"), res);
      completeRequest(res);
      return;
    }
#endif  // BMCWEB_INSECURE_DISABLE_AUTHX

    auto async_resp = std::make_shared<bmcweb::AsyncResp>(nullptr);
    async_resp->hintMaxAgeSec =
        max_age_sec;  // TODO: Remove after g3 managedStore dependency merges
    async_resp->hintCacheMaxAgeSec = max_age_sec;

    BMCWEB_LOG_DEBUG << "Setting completion handler: " << " hintMaxAgeSec: "
                     << async_resp->hintCacheMaxAgeSec.value();
    async_resp->res.setCompleteRequestHandler(
        [self(shared_from_this())](crow::Response& thisRes) {
          self->completeRequest(thisRes);
        });

    if (this_req.isUpgrade() &&
        boost::iequals(
            this_req.getHeaderValue(boost::beast::http::field::upgrade),
            "websocket")) {
      async_resp->res.setCompleteRequestHandler(
          [self(shared_from_this())](crow::Response& thisRes) {
            if (thisRes.result() != boost::beast::http::status::ok) {
              // When any error occurs before handle upgradation,
              // the result in response will be set to respective
              // error. By default the Result will be OK (200),
              // which implies successful handle upgrade. Response
              // needs to be sent over this connection only on
              // failure.
              self->completeRequest(thisRes);
              return;
            }
          });
      handler->handleUpgrade(this_req, async_resp, std::move(adaptor));
      return;
    }
    std::string_view expected =
        req->getHeaderValue(boost::beast::http::field::if_none_match);
    if (!expected.empty()) {
      res.setExpectedHash(expected);
    }
    async_resp->res.startTimetrace("LOCAL");
    // Only post to strand for GET requests.
    if (this_req.method() == boost::beast::http::verb::get) {
      auto strand = std::make_shared<boost::asio::io_context::strand>(
          *this_req.ioService);
      async_resp->strand_ = strand;
      boost::asio::post(*strand, [this, this_req{std::move(this_req)},
                                  async_resp{std::move(async_resp)}]() mutable {
        handler->handle(this_req, async_resp);
        async_resp->res.endTimetrace("LOCAL");
      });
      return;
    }
    handler->handle(this_req, async_resp);
    async_resp->res.endTimetrace("LOCAL");
  }

  bool isAlive() {
    if constexpr (std::is_same_v<Adaptor, boost::beast::ssl_stream<
                                              boost::asio::ip::tcp::socket>>) {
      return adaptor.next_layer().is_open();
    } else {
      return adaptor.is_open();
    }
  }

  // Set the socket to use a keepAlive. ONLY CALL THIS DURING SOCKET ACCEPT
  void setKeepAlive() {
    // Sets SO_KEEPALIVE. For more info see
    // https://beta.boost.org/doc/libs/1_82_0/doc/html/boost_asio/reference/socket_base/keep_alive.html
    boost::asio::socket_base::keep_alive option(true);
    if constexpr (std::is_same_v<Adaptor, boost::beast::ssl_stream<
                                              boost::asio::ip::tcp::socket>>) {
      adaptor.next_layer().set_option(option);
    } else {
      adaptor.set_option(option);
    }
  }

  void close() {
    if constexpr (std::is_same_v<Adaptor, boost::beast::ssl_stream<
                                              boost::asio::ip::tcp::socket>>) {
      adaptor.next_layer().close();
      if (mtlsSession != nullptr) {
        BMCWEB_LOG_DEBUG << this
                         << " Removing TLS session: " << mtlsSession->uniqueId;
        persistent_data::SessionStore::getInstance().removeSession(mtlsSession);
      }
    } else {
      adaptor.close();
    }
  }

  void completeRequest(crow::Response& thisRes) {
    if (!req) {
      return;
    }
    res = std::move(thisRes);
    res.keepAlive(keepAlive);

    BMCWEB_LOG_INFO << "Response: " << this << ' ' << req->url().encoded_path()
                    << ' ' << res.resultInt() << " keepalive=" << keepAlive;

    addSecurityHeaders(*req, res);

    crow::authentication::cleanupTempSession(*req);

    if (!isAlive()) {
      // BMCWEB_LOG_DEBUG << this << " delete (socket is closed) " <<
      // isReading
      // << ' ' << isWriting;
      // delete this;

      // delete lambda with self shared_ptr
      // to enable connection destruction
      res.setCompleteRequestHandler(nullptr);
      return;
    }

    res.setHashAndHandleNotModified();

    if (res.body().empty() && !res.jsonValue.empty()) {
      using http_helpers::ContentType;
      std::array<ContentType, 3> allowed{ContentType::CBOR, ContentType::JSON,
                                         ContentType::HTML};
      ContentType prefered =
          getPreferedContentType(req->getHeaderValue("Accept"), allowed);

      if (prefered == ContentType::HTML) {
        prettyPrintJson(res);
      } else if (prefered == ContentType::CBOR) {
        res.addHeader(boost::beast::http::field::content_type,
                      "application/cbor");
        nlohmann::json::to_cbor(res.jsonValue, res.body());
      } else {
        // Technically prefered could also be NoMatch here, but we'd
        // like to default to something rather than return 400 for
        // backward compatibility.
        res.addHeader(boost::beast::http::field::content_type,
                      "application/json");
        res.body() = res.jsonValue.dump(
            2, ' ', true, nlohmann::json::error_handler_t::replace);
      }
    }

    if (res.resultInt() >= 400 && res.body().empty()) {
      res.body() = std::string(res.reason());
    }

    if (res.result() == boost::beast::http::status::no_content) {
      // Boost beast throws if content is provided on a no-content
      // response.  Ideally, this would never happen, but in the case that
      // it does, we don't want to throw.
      BMCWEB_LOG_CRITICAL
          << this << " Response content provided but code was no-content";
      res.body().clear();
    }

    res.addHeader(boost::beast::http::field::date, getCachedDateStr());

    res.endTimetrace("BMCWEB");
    res.requestEndTime();
    res.updateTraceInManagedStore();

    doWrite(res);

    // delete lambda with self shared_ptr
    // to enable connection destruction
    res.setCompleteRequestHandler(nullptr);
  }

  void readClientIp() {
    boost::asio::ip::address ip;
    boost::system::error_code ec = getClientIp(ip);
    if (ec) {
      return;
    }
    req->ipAddress = ip;
  }

  boost::system::error_code getClientIp(boost::asio::ip::address& ip) {
    boost::system::error_code ec;
    BMCWEB_LOG_DEBUG << "Fetch the client IP address";
    boost::asio::ip::tcp::endpoint endpoint =
        boost::beast::get_lowest_layer(adaptor).remote_endpoint(ec);

    if (ec) {
      // If remote endpoint fails keep going. "ClientOriginIPAddress"
      // will be empty.
      BMCWEB_LOG_ERROR << "Failed to get the client's IP Address. ec : " << ec;
      return ec;
    }
    ip = endpoint.address();
    return ec;
  }

 private:
  void doReadHeaders() {
    BMCWEB_LOG_DEBUG << this << " doReadHeaders";

    // Clean up any previous Connection.
    boost::beast::http::async_read_header(
        adaptor, buffer, *parser,
        [this, self(shared_from_this())](const boost::system::error_code& ec,
                                         std::size_t bytesTransferred) {
          BMCWEB_LOG_DEBUG << this << " async_read_header " << bytesTransferred
                           << " Bytes";
          bool errorWhileReading = false;
          if (ec) {
            errorWhileReading = true;
            if (ec == boost::beast::http::error::end_of_stream) {
              BMCWEB_LOG_WARNING << this
                                 << " Error while reading: " << ec.message();
            } else {
              BMCWEB_LOG_ERROR << this
                               << " Error while reading: " << ec.message();
            }
          } else {
            // if the adaptor isn't open anymore, and wasn't handed to a
            // websocket, treat as an error
            if (!isAlive() &&
                !boost::beast::websocket::is_upgrade(parser->get())) {
              errorWhileReading = true;
            }
          }

          cancelDeadlineTimer();

          if (errorWhileReading) {
            close();
            BMCWEB_LOG_DEBUG << this << " from read(1)";
            return;
          }

          readClientIp();

          boost::asio::ip::address ip;
          if (getClientIp(ip)) {
            BMCWEB_LOG_DEBUG << "Unable to get client IP";
          }
#ifndef BMCWEB_INSECURE_DISABLE_AUTHX
          boost::beast::http::verb method = parser->get().method();
          userSession = crow::authentication::authenticate(
              ip, res, method, parser->get().base(), mtlsSession);

          bool loggedIn = userSession != nullptr;
          if (!loggedIn) {
            const boost::optional<uint64_t> contentLength =
                parser->content_length();
            if (contentLength && *contentLength > loggedOutPostBodyLimit) {
              BMCWEB_LOG_DEBUG << "Content length greater than limit "
                               << *contentLength;
              close();
              return;
            }

            BMCWEB_LOG_DEBUG << "Starting quick deadline";
          }
#endif  // BMCWEB_INSECURE_DISABLE_AUTHX

          if (parser->is_done()) {
            handle();
            return;
          }

          doRead();
        });
  }

  void doRead() {
    BMCWEB_LOG_DEBUG << this << " doRead";
    startDeadline();
    boost::beast::http::async_read_some(
        adaptor, buffer, *parser,
        [this, self(shared_from_this())](const boost::system::error_code& ec,
                                         std::size_t bytesTransferred) {
          BMCWEB_LOG_DEBUG << this << " async_read_some " << bytesTransferred
                           << " Bytes";

          if (ec) {
            BMCWEB_LOG_ERROR << this
                             << " Error while reading: " << ec.message();
            close();
            BMCWEB_LOG_DEBUG << this << " from read(1)";
            return;
          }

          // If the user is logged in, allow them to send files incrementally
          // one piece at a time. If authentication is disabled then there is
          // no user session hence always allow to send one piece at a time.
          if (userSession != nullptr) {
            cancelDeadlineTimer();
          }
          if (!parser->is_done()) {
            doRead();
            return;
          }

          cancelDeadlineTimer();
          handle();
        });
  }

  void doWrite(crow::Response& thisRes) {
    BMCWEB_LOG_DEBUG << this << " doWrite";
    thisRes.preparePayload();
    serializer.emplace(*thisRes.stringResponse);
    startDeadline();
    boost::beast::http::async_write(
        adaptor, *serializer,
        [this, self(shared_from_this())](const boost::system::error_code& ec,
                                         std::size_t bytesTransferred) {
          BMCWEB_LOG_DEBUG << this << " async_write " << bytesTransferred
                           << " bytes";

          cancelDeadlineTimer();

          if (ec) {
            BMCWEB_LOG_DEBUG << this << " from write(2)";
            return;
          }
          if (!keepAlive) {
            close();
            BMCWEB_LOG_DEBUG << this << " from write(1)";
            return;
          }

          serializer.reset();
          BMCWEB_LOG_DEBUG << this << " Clearing response";
          res.clear();
          parser.emplace(std::piecewise_construct, std::make_tuple());
          parser->body_limit(httpReqBodyLimit);  // reset body limit for
                                                 // newly created parser
          buffer.consume(buffer.size());

          userSession = nullptr;

          // Destroy the Request via the std::optional
          req.reset();
          doReadHeaders();
        });
  }

  void cancelDeadlineTimer() { timer.cancel(); }

  void startDeadline() {
    // Timer is already started so no further action is required.
    if (timerStarted) {
      return;
    }

    std::chrono::seconds timeout(15);

    std::weak_ptr<Connection<Adaptor, Handler>> weak_self = weak_from_this();
    timer.expires_after(timeout);
    timer.async_wait([weak_self](const boost::system::error_code ec) {
      // Note, we are ignoring other types of errors here;  If the timer
      // failed for any reason, we should still close the connection
      std::shared_ptr<Connection<Adaptor, Handler>> self = weak_self.lock();
      if (!self) {
        BMCWEB_LOG_CRITICAL << self << " Failed to capture connection";
        return;
      }

      self->timerStarted = false;

      if (ec == boost::asio::error::operation_aborted) {
        // Canceled wait means the path succeeded.
        return;
      }
      if (ec) {
        BMCWEB_LOG_CRITICAL << self << " timer failed " << ec;
      }

      BMCWEB_LOG_WARNING << self << "Connection timed out, closing";

      self->close();
    });

    timerStarted = true;
    BMCWEB_LOG_DEBUG << this << " timer started";
  }

  Adaptor adaptor;   // NOLINT
  Handler* handler;  // NOLINT
  // Making this a std::optional allows it to be efficiently destroyed and
  // re-created on Connection reset
  std::optional<
      boost::beast::http::request_parser<boost::beast::http::string_body>>
      parser;  // NOLINT

  boost::beast::flat_static_buffer<8192> buffer;  // NOLINT

  std::optional<
      boost::beast::http::response_serializer<boost::beast::http::string_body>>
      serializer;  // NOLINT

  std::optional<crow::Request> req;  // NOLINT
  crow::Response res;                // NOLINT

  std::shared_ptr<persistent_data::UserSession> userSession;  // NOLINT
  std::shared_ptr<persistent_data::UserSession> mtlsSession;  // NOLINT

  boost::asio::steady_timer timer;  // NOLINT

  bool keepAlive = true;  // NOLINT

  bool timerStarted = false;  // NOLINT

  std::function<std::string()>& getCachedDateStr;  // NOLINT

  using std::enable_shared_from_this<
      Connection<Adaptor, Handler>>::shared_from_this;

  using std::enable_shared_from_this<
      Connection<Adaptor, Handler>>::weak_from_this;
};
}  // namespace crow

#endif  // THIRD_PARTY_GBMCWEB_HTTP_HTTP_CONNECTION_H_
