#pragma once
#include "bmcweb_config.h"

#include "async_resp.hpp"
#include "authentication.hpp"
#include "complete_response_fields.hpp"
#include "http2_connection.hpp"
#include "http_body.hpp"
#include "http_response.hpp"
#include "http_utility.hpp"
#include "logging.hpp"
#include "mutual_tls.hpp"
#include "ssl_key_handler.hpp"
#include "str_utility.hpp"
#include "utility.hpp"

#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/beast/_experimental/test/stream.hpp>
#include <boost/beast/core/buffers_generator.hpp>
#include <boost/beast/core/flat_static_buffer.hpp>
#include <boost/beast/http/error.hpp>
#include <boost/beast/http/message_generator.hpp>
#include <boost/beast/http/parser.hpp>
#include <boost/beast/http/read.hpp>
#include <boost/beast/http/write.hpp>
#include <boost/beast/websocket.hpp>

#include <atomic>
#include <chrono>
#include <memory>
#include <vector>

namespace crow
{

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

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

constexpr uint64_t loggedOutPostBodyLimit = 4096U;

constexpr uint32_t httpHeaderLimit = 8192U;

template <typename>
struct IsTls : std::false_type
{};

template <typename T>
struct IsTls<boost::asio::ssl::stream<T>> : std::true_type
{};

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)
    {
        initParser();

        connectionCount++;

        BMCWEB_LOG_DEBUG("{} Connection created, total {}", logPtr(this),
                         connectionCount);
    }

    ~Connection()
    {
        res.releaseCompleteRequestHandler();
        cancelDeadlineTimer();

        connectionCount--;
        BMCWEB_LOG_DEBUG("{} Connection closed, total {}", logPtr(this),
                         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)
    {
        BMCWEB_LOG_DEBUG("{} tlsVerifyCallback called with preverified {}",
                         logPtr(this), preverified);
        if (preverified)
        {
            mtlsSession = verifyMtlsUser(ip, ctx);
            if (mtlsSession)
            {
                BMCWEB_LOG_DEBUG("{} Generated TLS session: {}", logPtr(this),
                                 mtlsSession->uniqueId);
            }
        }
        const persistent_data::AuthConfigMethods& c =
            persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
        if (c.tlsStrict)
        {
            BMCWEB_LOG_DEBUG(
                "{} TLS is in strict mode, returning preverified as is.",
                logPtr(this));
            return preverified;
        }
        // If tls strict mode is disabled
        // We always return true to allow full auth flow for resources that
        // don't require auth
        return true;
    }

    bool prepareMutualTls()
    {
        if constexpr (IsTls<Adaptor>::value)
        {
            BMCWEB_LOG_DEBUG("prepareMutualTls");

            constexpr std::string_view id = "bmcweb";

            const char* idPtr = id.data();
            const auto* idCPtr = std::bit_cast<const unsigned char*>(idPtr);
            auto idLen = static_cast<unsigned int>(id.length());
            int ret = SSL_set_session_id_context(adaptor.native_handle(),
                                                 idCPtr, idLen);
            if (ret == 0)
            {
                BMCWEB_LOG_ERROR("{} failed to set SSL id", logPtr(this));
                return false;
            }

            BMCWEB_LOG_DEBUG("set_verify_callback");

            boost::system::error_code ec;
            adaptor.set_verify_callback(
                std::bind_front(&self_type::tlsVerifyCallback, this), ec);
            if (ec)
            {
                BMCWEB_LOG_ERROR("Failed to set verify callback {}", ec);
                return false;
            }
        }

        return true;
    }

    void start()
    {
        BMCWEB_LOG_DEBUG("{} Connection started, total {}", logPtr(this),
                         connectionCount);
        if (connectionCount >= 200)
        {
            BMCWEB_LOG_CRITICAL("{} Max connection count exceeded.",
                                logPtr(this));
            return;
        }

        if constexpr (BMCWEB_MUTUAL_TLS_AUTH)
        {
            if (!prepareMutualTls())
            {
                BMCWEB_LOG_ERROR("{} Failed to prepare mTLS", logPtr(this));
                return;
            }
        }

        startDeadline();

        readClientIp();

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

    void afterSslHandshake()
    {
        // If http2 is enabled, negotiate the protocol
        if constexpr (BMCWEB_EXPERIMENTAL_HTTP2)
        {
            const unsigned char* alpn = nullptr;
            unsigned int alpnlen = 0;
            SSL_get0_alpn_selected(adaptor.native_handle(), &alpn, &alpnlen);
            if (alpn != nullptr)
            {
                std::string_view selectedProtocol(
                    std::bit_cast<const char*>(alpn), alpnlen);
                BMCWEB_LOG_DEBUG("ALPN selected protocol \"{}\" len: {}",
                                 selectedProtocol, alpnlen);
                if (selectedProtocol == "h2")
                {
                    auto http2 =
                        std::make_shared<HTTP2Connection<Adaptor, Handler>>(
                            std::move(adaptor), handler, getCachedDateStr);
                    http2->start();
                    return;
                }
            }
        }

        doReadHeaders();
    }

    void initParser()
    {
        boost::beast::http::request_parser<bmcweb::HttpBody>& instance =
            parser.emplace(std::piecewise_construct, std::make_tuple());

        // reset header limit for newly created parser
        instance.header_limit(httpHeaderLimit);

        // Initially set no body limit. We don't yet know if the user is
        // authenticated.
        instance.body_limit(boost::none);
    }

    void handle()
    {
        std::error_code reqEc;
        if (!parser)
        {
            return;
        }
        req = std::make_shared<crow::Request>(parser->release(), reqEc);
        if (reqEc)
        {
            BMCWEB_LOG_DEBUG("Request failed to construct{}", reqEc.message());
            res.result(boost::beast::http::status::bad_request);
            completeRequest(res);
            return;
        }
        req->session = userSession;
        accept = req->getHeaderValue("Accept");
        // Fetch the client IP address
        req->ipAddress = ip;

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

        BMCWEB_LOG_INFO("Request:  {} HTTP/{}.{} {} {} {}", logPtr(this),
                        req->version() / 10, req->version() % 10,
                        req->methodString(), req->target(),
                        req->ipAddress.to_string());

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

        if (res.completed)
        {
            completeRequest(res);
            return;
        }
        keepAlive = req->keepAlive();
        if constexpr (!std::is_same_v<Adaptor, boost::beast::test::stream>)
        {
            if constexpr (!BMCWEB_INSECURE_DISABLE_AUTH)
            {
                if (!crow::authentication::isOnAllowlist(req->url().path(),
                                                         req->method()) &&
                    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;
                }
            }
        }
        auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
        BMCWEB_LOG_DEBUG("Setting completion handler");
        asyncResp->res.setCompleteRequestHandler(
            [self(shared_from_this())](crow::Response& thisRes) {
                self->completeRequest(thisRes);
            });
        bool isSse =
            isContentTypeAllowed(req->getHeaderValue("Accept"),
                                 http_helpers::ContentType::EventStream, false);
        std::string_view upgradeType(
            req->getHeaderValue(boost::beast::http::field::upgrade));
        if ((req->isUpgrade() &&
             bmcweb::asciiIEquals(upgradeType, "websocket")) ||
            isSse)
        {
            asyncResp->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(req, asyncResp, std::move(adaptor));
            return;
        }
        std::string_view expected =
            req->getHeaderValue(boost::beast::http::field::if_none_match);
        if (!expected.empty())
        {
            res.setExpectedHash(expected);
        }
        handler->handle(req, asyncResp);
    }

    void hardClose()
    {
        if (mtlsSession != nullptr)
        {
            BMCWEB_LOG_DEBUG("{} Removing TLS session: {}", logPtr(this),
                             mtlsSession->uniqueId);
            persistent_data::SessionStore::getInstance().removeSession(
                mtlsSession);
        }
        BMCWEB_LOG_DEBUG("{} Closing socket", logPtr(this));
        boost::beast::get_lowest_layer(adaptor).close();
    }

    void tlsShutdownComplete(const std::shared_ptr<self_type>& self,
                             const boost::system::error_code& ec)
    {
        if (ec)
        {
            BMCWEB_LOG_WARNING("{} Failed to shut down TLS cleanly {}",
                               logPtr(self.get()), ec);
        }
        self->hardClose();
    }

    void gracefulClose()
    {
        BMCWEB_LOG_DEBUG("{} Socket close requested", logPtr(this));

        if constexpr (IsTls<Adaptor>::value)
        {
            adaptor.async_shutdown(std::bind_front(
                &self_type::tlsShutdownComplete, this, shared_from_this()));
        }
        else
        {
            hardClose();
        }
    }

    void completeRequest(crow::Response& thisRes)
    {
        res = std::move(thisRes);
        res.keepAlive(keepAlive);

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

        doWrite();

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

    void readClientIp()
    {
        boost::system::error_code ec;

        if constexpr (!std::is_same_v<Adaptor, boost::beast::test::stream>)
        {
            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;
            }
            ip = endpoint.address();
        }
    }

  private:
    uint64_t getContentLengthLimit()
    {
        if constexpr (!BMCWEB_INSECURE_DISABLE_AUTH)
        {
            if (userSession == nullptr)
            {
                return loggedOutPostBodyLimit;
            }
        }

        return httpReqBodyLimit;
    }

    // Returns true if content length was within limits
    // Returns false if content length error has been returned
    bool handleContentLengthError()
    {
        if (!parser)
        {
            BMCWEB_LOG_CRITICAL("Parser was null");
            return false;
        }
        const boost::optional<uint64_t> contentLength =
            parser->content_length();
        if (!contentLength)
        {
            BMCWEB_LOG_DEBUG("{} No content length available", logPtr(this));
            return true;
        }

        uint64_t maxAllowedContentLength = getContentLengthLimit();

        if (*contentLength > maxAllowedContentLength)
        {
            // If the users content limit is between the logged in
            // and logged out limits They probably just didn't log
            // in
            if (*contentLength > loggedOutPostBodyLimit &&
                *contentLength < httpReqBodyLimit)
            {
                BMCWEB_LOG_DEBUG(
                    "{} Content length {} valid, but greater than logged out"
                    " limit of {}. Setting unauthorized",
                    logPtr(this), *contentLength, loggedOutPostBodyLimit);
                res.result(boost::beast::http::status::unauthorized);
            }
            else
            {
                // Otherwise they're over both limits, so inform
                // them
                BMCWEB_LOG_DEBUG(
                    "{} Content length {} was greater than global limit {}."
                    " Setting payload too large",
                    logPtr(this), *contentLength, httpReqBodyLimit);
                res.result(boost::beast::http::status::payload_too_large);
            }

            keepAlive = false;
            doWrite();
            return false;
        }

        return true;
    }

    void afterReadHeaders(const std::shared_ptr<self_type>& /*self*/,
                          const boost::system::error_code& ec,
                          std::size_t bytesTransferred)
    {
        BMCWEB_LOG_DEBUG("{} async_read_header {} Bytes", logPtr(this),
                         bytesTransferred);

        if (ec)
        {
            cancelDeadlineTimer();

            if (ec == boost::beast::http::error::header_limit)
            {
                BMCWEB_LOG_ERROR("{} Header field too large, closing",
                                 logPtr(this), ec.message());

                res.result(boost::beast::http::status::
                               request_header_fields_too_large);
                keepAlive = false;
                doWrite();
                return;
            }
            if (ec == boost::beast::http::error::end_of_stream)
            {
                BMCWEB_LOG_WARNING("{} End of stream, closing {}", logPtr(this),
                                   ec);
                hardClose();
                return;
            }

            BMCWEB_LOG_DEBUG("{} Closing socket due to read error {}",
                             logPtr(this), ec.message());
            gracefulClose();

            return;
        }

        if (!parser)
        {
            BMCWEB_LOG_ERROR("Parser was unexpectedly null");
            return;
        }

        constexpr bool isTest =
            std::is_same_v<Adaptor, boost::beast::test::stream>;

        if constexpr (!BMCWEB_INSECURE_DISABLE_AUTH && !isTest)
        {
            boost::beast::http::verb method = parser->get().method();
            userSession = crow::authentication::authenticate(
                ip, res, method, parser->get().base(), mtlsSession);
        }

        std::string_view expect =
            parser->get()[boost::beast::http::field::expect];
        if (bmcweb::asciiIEquals(expect, "100-continue"))
        {
            res.result(boost::beast::http::status::continue_);
            doWrite();
            return;
        }

        if (!handleContentLengthError())
        {
            return;
        }

        parser->body_limit(getContentLengthLimit());

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

        doRead();
    }

    void doReadHeaders()
    {
        BMCWEB_LOG_DEBUG("{} doReadHeaders", logPtr(this));
        if (!parser)
        {
            BMCWEB_LOG_CRITICAL("Parser was not initialized.");
            return;
        }
        // Clean up any previous Connection.
        boost::beast::http::async_read_header(
            adaptor, buffer, *parser,
            std::bind_front(&self_type::afterReadHeaders, this,
                            shared_from_this()));
    }

    void afterRead(const std::shared_ptr<self_type>& /*self*/,
                   const boost::system::error_code& ec,
                   std::size_t bytesTransferred)
    {
        BMCWEB_LOG_DEBUG("{} async_read_some {} Bytes", logPtr(this),
                         bytesTransferred);

        if (ec)
        {
            BMCWEB_LOG_ERROR("{} Error while reading: {}", logPtr(this),
                             ec.message());
            if (ec == boost::beast::http::error::body_limit)
            {
                if (handleContentLengthError())
                {
                    BMCWEB_LOG_CRITICAL("Body length limit reached, "
                                        "but no content-length "
                                        "available?  Should never happen");
                    res.result(
                        boost::beast::http::status::internal_server_error);
                    keepAlive = false;
                    doWrite();
                }
                return;
            }

            gracefulClose();
            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)
        {
            BMCWEB_LOG_ERROR("Parser was unexpectedly null");
            return;
        }
        if (!parser->is_done())
        {
            doRead();
            return;
        }

        cancelDeadlineTimer();
        handle();
    }

    void doRead()
    {
        BMCWEB_LOG_DEBUG("{} doRead", logPtr(this));
        if (!parser)
        {
            return;
        }
        startDeadline();
        boost::beast::http::async_read_some(
            adaptor, buffer, *parser,
            std::bind_front(&self_type::afterRead, this, shared_from_this()));
    }

    void afterDoWrite(const std::shared_ptr<self_type>& /*self*/,
                      const boost::system::error_code& ec,
                      std::size_t bytesTransferred)
    {
        BMCWEB_LOG_DEBUG("{} async_write wrote {} bytes, ec={}", logPtr(this),
                         bytesTransferred, ec);

        cancelDeadlineTimer();

        if (ec == boost::system::errc::operation_would_block ||
            ec == boost::system::errc::resource_unavailable_try_again)
        {
            doWrite();
            return;
        }
        if (ec)
        {
            BMCWEB_LOG_DEBUG("{} from write(2)", logPtr(this));
            return;
        }

        if (res.result() == boost::beast::http::status::continue_)
        {
            // Reset the result to ok
            res.result(boost::beast::http::status::ok);
            doRead();
            return;
        }

        if (!keepAlive)
        {
            BMCWEB_LOG_DEBUG("{} keepalive not set.  Closing socket",
                             logPtr(this));

            gracefulClose();
            return;
        }

        BMCWEB_LOG_DEBUG("{} Clearing response", logPtr(this));
        res.clear();
        initParser();

        userSession = nullptr;

        req->clear();
        doReadHeaders();
    }

    void doWrite()
    {
        BMCWEB_LOG_DEBUG("{} doWrite", logPtr(this));
        res.preparePayload();

        startDeadline();
        boost::beast::async_write(
            adaptor,
            boost::beast::http::message_generator(std::move(res.response)),
            std::bind_front(&self_type::afterDoWrite, this,
                            shared_from_this()));
    }

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

    void afterTimerWait(const std::weak_ptr<self_type>& weakSelf,
                        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 = weakSelf.lock();
        if (!self)
        {
            if (ec == boost::asio::error::operation_aborted)
            {
                BMCWEB_LOG_DEBUG(
                    "{} Timer canceled on connection being destroyed",
                    logPtr(self.get()));
            }
            else
            {
                BMCWEB_LOG_CRITICAL("{} Failed to capture connection",
                                    logPtr(self.get()));
            }
            return;
        }

        self->timerStarted = false;

        if (ec)
        {
            if (ec == boost::asio::error::operation_aborted)
            {
                BMCWEB_LOG_DEBUG("{} Timer canceled", logPtr(self.get()));
                return;
            }
            BMCWEB_LOG_CRITICAL("{} Timer failed {}", logPtr(self.get()), ec);
        }

        BMCWEB_LOG_WARNING("{} Connection timed out, hard closing",
                           logPtr(self.get()));

        self->hardClose();
    }

    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>> weakSelf = weak_from_this();
        timer.expires_after(timeout);
        timer.async_wait(std::bind_front(&self_type::afterTimerWait, this,
                                         weak_from_this()));

        timerStarted = true;
        BMCWEB_LOG_DEBUG("{} timer started", logPtr(this));
    }

    Adaptor adaptor;
    Handler* handler;

    boost::asio::ip::address ip;

    // Making this a std::optional allows it to be efficiently destroyed and
    // re-created on Connection reset
    std::optional<boost::beast::http::request_parser<bmcweb::HttpBody>> parser;

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

    std::shared_ptr<crow::Request> req;
    std::string accept;

    crow::Response res;

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

    boost::asio::steady_timer timer;

    bool keepAlive = true;

    bool timerStarted = false;

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

    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
