#pragma once
#include "bmcweb_config.h"

#include "async_resp.hpp"
#include "authentication.hpp"
#include "complete_response_fields.hpp"
#include "http_response.hpp"
#include "http_utility.hpp"
#include "logging.hpp"
#include "mutual_tls.hpp"
#include "nghttp2_adapters.hpp"
#include "ssl_key_handler.hpp"
#include "utility.hpp"

#include <boost/algorithm/string/predicate.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/core/multi_buffer.hpp>
#include <boost/beast/http/error.hpp>
#include <boost/beast/http/parser.hpp>
#include <boost/beast/http/read.hpp>
#include <boost/beast/http/serializer.hpp>
#include <boost/beast/http/string_body.hpp>
#include <boost/beast/http/write.hpp>
#include <boost/beast/ssl/ssl_stream.hpp>
#include <boost/beast/websocket.hpp>

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

namespace crow
{

struct Http2StreamData
{
    crow::Request req{};
    crow::Response res{};
    size_t sentSofar = 0;
};

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

  public:
    HTTP2Connection(Adaptor&& adaptorIn, Handler* handlerIn,
                    std::function<std::string()>& getCachedDateStrF

                    ) :
        adaptor(std::move(adaptorIn)),

        ngSession(initializeNghttp2Session()),

        handler(handlerIn), getCachedDateStr(getCachedDateStrF)
    {}

    void start()
    {
        // Create the control stream
        streams.emplace(0, std::make_unique<Http2StreamData>());

        if (sendServerConnectionHeader() != 0)
        {
            BMCWEB_LOG_ERROR << "send_server_connection_header failed";
            return;
        }
        doRead();
    }

    int sendServerConnectionHeader()
    {
        BMCWEB_LOG_DEBUG << "send_server_connection_header()";

        uint32_t maxStreams = 4;
        std::array<nghttp2_settings_entry, 2> iv = {
            {{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, maxStreams},
             {NGHTTP2_SETTINGS_ENABLE_PUSH, 0}}};
        int rv = ngSession.submitSettings(iv);
        if (rv != 0)
        {
            BMCWEB_LOG_ERROR << "Fatal error: " << nghttp2_strerror(rv);
            return -1;
        }
        return 0;
    }

    static ssize_t fileReadCallback(nghttp2_session* /* session */,
                                    int32_t /* stream_id */, uint8_t* buf,
                                    size_t length, uint32_t* dataFlags,
                                    nghttp2_data_source* source,
                                    void* /*unused*/)
    {
        if (source == nullptr || source->ptr == nullptr)
        {
            BMCWEB_LOG_DEBUG << "Source was null???";
            return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
        }

        BMCWEB_LOG_DEBUG << "File read callback length: " << length;
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
        Http2StreamData* str = reinterpret_cast<Http2StreamData*>(source->ptr);
        crow::Response& res = str->res;

        BMCWEB_LOG_DEBUG << "total: " << res.body().size()
                         << " send_sofar: " << str->sentSofar;

        size_t toSend = std::min(res.body().size() - str->sentSofar, length);
        BMCWEB_LOG_DEBUG << "Copying " << toSend << " bytes to buf";

        std::string::iterator bodyBegin = res.body().begin();
        std::advance(bodyBegin, str->sentSofar);

        memcpy(buf, &*bodyBegin, toSend);
        str->sentSofar += toSend;

        if (str->sentSofar >= res.body().size())
        {
            BMCWEB_LOG_DEBUG << "Setting OEF flag";
            *dataFlags |= NGHTTP2_DATA_FLAG_EOF;
            //*dataFlags |= NGHTTP2_DATA_FLAG_NO_COPY;
        }
        return static_cast<ssize_t>(toSend);
    }

    nghttp2_nv headerFromStringViews(std::string_view name,
                                     std::string_view value)
    {
        uint8_t* nameData = std::bit_cast<uint8_t*>(name.data());
        uint8_t* valueData = std::bit_cast<uint8_t*>(value.data());
        return {nameData, valueData, name.size(), value.size(),
                NGHTTP2_NV_FLAG_NONE};
    }

    int sendResponse(Response& completedRes, int32_t streamId)
    {
        BMCWEB_LOG_DEBUG << "send_response stream_id:" << streamId;

        auto it = streams.find(streamId);
        if (it == streams.end())
        {
            close();
            return -1;
        }
        Response& thisRes = it->second->res;
        thisRes = std::move(completedRes);
        crow::Request& thisReq = it->second->req;
        std::vector<nghttp2_nv> hdr;

        completeResponseFields(thisReq, thisRes);
        thisRes.addHeader(boost::beast::http::field::date, getCachedDateStr());

        boost::beast::http::fields& fields = thisRes.stringResponse->base();
        std::string code = std::to_string(thisRes.stringResponse->result_int());
        hdr.emplace_back(headerFromStringViews(":status", code));
        for (const boost::beast::http::fields::value_type& header : fields)
        {
            hdr.emplace_back(
                headerFromStringViews(header.name_string(), header.value()));
        }
        Http2StreamData* streamPtr = it->second.get();
        streamPtr->sentSofar = 0;

        nghttp2_data_provider dataPrd{
            .source{
                .ptr = streamPtr,
            },
            .read_callback = fileReadCallback,
        };

        int rv = ngSession.submitResponse(streamId, hdr, &dataPrd);
        if (rv != 0)
        {
            BMCWEB_LOG_ERROR << "Fatal error: " << nghttp2_strerror(rv);
            close();
            return -1;
        }
        ngSession.send();

        return 0;
    }

    nghttp2_session initializeNghttp2Session()
    {
        nghttp2_session_callbacks callbacks;
        callbacks.setOnFrameRecvCallback(onFrameRecvCallbackStatic);
        callbacks.setOnStreamCloseCallback(onStreamCloseCallbackStatic);
        callbacks.setOnHeaderCallback(onHeaderCallbackStatic);
        callbacks.setOnBeginHeadersCallback(onBeginHeadersCallbackStatic);
        callbacks.setSendCallback(onSendCallbackStatic);

        nghttp2_session session(callbacks);
        session.setUserData(this);

        return session;
    }

    int onRequestRecv(int32_t streamId)
    {
        BMCWEB_LOG_DEBUG << "on_request_recv";

        auto it = streams.find(streamId);
        if (it == streams.end())
        {
            close();
            return -1;
        }

        crow::Request& thisReq = it->second->req;
        BMCWEB_LOG_DEBUG << "Handling " << &thisReq << " \""
                         << thisReq.url().encoded_path() << "\"";

        crow::Response& thisRes = it->second->res;

        thisRes.setCompleteRequestHandler(
            [this, streamId](Response& completeRes) {
            BMCWEB_LOG_DEBUG << "res.completeRequestHandler called";
            if (sendResponse(completeRes, streamId) != 0)
            {
                close();
                return;
            }
        });
        auto asyncResp =
            std::make_shared<bmcweb::AsyncResp>(std::move(it->second->res));
        handler->handle(thisReq, asyncResp);

        return 0;
    }

    int onFrameRecvCallback(const nghttp2_frame& frame)
    {
        BMCWEB_LOG_DEBUG << "frame type " << static_cast<int>(frame.hd.type);
        switch (frame.hd.type)
        {
            case NGHTTP2_DATA:
            case NGHTTP2_HEADERS:
                // Check that the client request has finished
                if ((frame.hd.flags & NGHTTP2_FLAG_END_STREAM) != 0)
                {
                    return onRequestRecv(frame.hd.stream_id);
                }
                break;
            default:
                break;
        }
        return 0;
    }

    static int onFrameRecvCallbackStatic(nghttp2_session* /* session */,
                                         const nghttp2_frame* frame,
                                         void* userData)
    {
        BMCWEB_LOG_DEBUG << "on_frame_recv_callback";
        if (userData == nullptr)
        {
            BMCWEB_LOG_CRITICAL << "user data was null?";
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        if (frame == nullptr)
        {
            BMCWEB_LOG_CRITICAL << "frame was null?";
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        return userPtrToSelf(userData).onFrameRecvCallback(*frame);
    }

    static self_type& userPtrToSelf(void* userData)
    {
        // This method exists to keep the unsafe reinterpret cast in one
        // place.
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
        return *reinterpret_cast<self_type*>(userData);
    }

    static int onStreamCloseCallbackStatic(nghttp2_session* /* session */,
                                           int32_t streamId,
                                           uint32_t /*unused*/, void* userData)
    {
        BMCWEB_LOG_DEBUG << "on_stream_close_callback stream " << streamId;
        if (userData == nullptr)
        {
            BMCWEB_LOG_CRITICAL << "user data was null?";
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        auto stream = userPtrToSelf(userData).streams.find(streamId);
        if (stream == userPtrToSelf(userData).streams.end())
        {
            return -1;
        }

        userPtrToSelf(userData).streams.erase(streamId);
        return 0;
    }

    int onHeaderCallback(const nghttp2_frame& frame,
                         std::span<const uint8_t> name,
                         std::span<const uint8_t> value)
    {
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
        std::string_view nameSv(reinterpret_cast<const char*>(name.data()),
                                name.size());
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
        std::string_view valueSv(reinterpret_cast<const char*>(value.data()),
                                 value.size());

        BMCWEB_LOG_DEBUG << "on_header_callback name: " << nameSv << " value "
                         << valueSv;

        switch (frame.hd.type)
        {
            case NGHTTP2_HEADERS:
                if (frame.headers.cat != NGHTTP2_HCAT_REQUEST)
                {
                    break;
                }
                auto thisStream = streams.find(frame.hd.stream_id);
                if (thisStream == streams.end())
                {
                    BMCWEB_LOG_ERROR << "Unknown stream" << frame.hd.stream_id;
                    close();
                    return -1;
                }

                crow::Request& thisReq = thisStream->second->req;

                if (nameSv == ":path")
                {
                    thisReq.target(valueSv);
                }
                else if (nameSv == ":method")
                {
                    boost::beast::http::verb verb =
                        boost::beast::http::string_to_verb(valueSv);
                    if (verb == boost::beast::http::verb::unknown)
                    {
                        BMCWEB_LOG_ERROR << "Unknown http verb " << valueSv;
                        close();
                        return -1;
                    }
                    thisReq.req.method(verb);
                }
                else if (nameSv == ":scheme")
                {
                    // Nothing to check on scheme
                }
                else
                {
                    thisReq.req.set(nameSv, valueSv);
                }
                break;
        }
        return 0;
    }

    static int onHeaderCallbackStatic(nghttp2_session* /* session */,
                                      const nghttp2_frame* frame,
                                      const uint8_t* name, size_t namelen,
                                      const uint8_t* value, size_t vallen,
                                      uint8_t /* flags */, void* userData)
    {
        if (userData == nullptr)
        {
            BMCWEB_LOG_CRITICAL << "user data was null?";
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        if (frame == nullptr)
        {
            BMCWEB_LOG_CRITICAL << "frame was null?";
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        if (name == nullptr)
        {
            BMCWEB_LOG_CRITICAL << "name was null?";
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        if (value == nullptr)
        {
            BMCWEB_LOG_CRITICAL << "value was null?";
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        return userPtrToSelf(userData).onHeaderCallback(*frame, {name, namelen},
                                                        {value, vallen});
    }

    int onBeginHeadersCallback(const nghttp2_frame& frame)
    {
        if (frame.hd.type == NGHTTP2_HEADERS &&
            frame.headers.cat == NGHTTP2_HCAT_REQUEST)
        {
            BMCWEB_LOG_DEBUG << "create stream for id " << frame.hd.stream_id;

            std::pair<boost::container::flat_map<
                          int32_t, std::unique_ptr<Http2StreamData>>::iterator,
                      bool>
                stream = streams.emplace(frame.hd.stream_id,
                                         std::make_unique<Http2StreamData>());
            // http2 is by definition always tls
            stream.first->second->req.isSecure = true;
        }
        return 0;
    }

    static int onBeginHeadersCallbackStatic(nghttp2_session* /* session */,
                                            const nghttp2_frame* frame,
                                            void* userData)
    {
        BMCWEB_LOG_DEBUG << "on_begin_headers_callback";
        if (userData == nullptr)
        {
            BMCWEB_LOG_CRITICAL << "user data was null?";
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        if (frame == nullptr)
        {
            BMCWEB_LOG_CRITICAL << "frame was null?";
            return NGHTTP2_ERR_CALLBACK_FAILURE;
        }
        return userPtrToSelf(userData).onBeginHeadersCallback(*frame);
    }

    static void afterWriteBuffer(const std::shared_ptr<self_type>& self,
                                 const boost::system::error_code& ec,
                                 size_t sendLength)
    {
        self->isWriting = false;
        BMCWEB_LOG_DEBUG << "Sent " << sendLength;
        if (ec)
        {
            self->close();
            return;
        }
        self->sendBuffer.consume(sendLength);
        self->writeBuffer();
    }

    void writeBuffer()
    {
        if (isWriting)
        {
            return;
        }
        if (sendBuffer.size() <= 0)
        {
            return;
        }
        isWriting = true;
        adaptor.async_write_some(
            sendBuffer.data(),
            std::bind_front(afterWriteBuffer, shared_from_this()));
    }

    ssize_t onSendCallback(nghttp2_session* /*session */, const uint8_t* data,
                           size_t length, int /* flags */)
    {
        BMCWEB_LOG_DEBUG << "On send callback size=" << length;
        size_t copied = boost::asio::buffer_copy(
            sendBuffer.prepare(length), boost::asio::buffer(data, length));
        sendBuffer.commit(copied);
        writeBuffer();
        return static_cast<ssize_t>(length);
    }

    static ssize_t onSendCallbackStatic(nghttp2_session* session,
                                        const uint8_t* data, size_t length,
                                        int flags /* flags */, void* userData)
    {
        return userPtrToSelf(userData).onSendCallback(session, data, length,
                                                      flags);
    }

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

    void doRead()
    {
        BMCWEB_LOG_DEBUG << this << " doRead";
        adaptor.async_read_some(
            inBuffer.prepare(8192),
            [this, self(shared_from_this())](
                const boost::system::error_code& ec, 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;
            }
            inBuffer.commit(bytesTransferred);

            size_t consumed = 0;
            for (const auto bufferIt : inBuffer.data())
            {
                std::span<const uint8_t> bufferSpan{
                    std::bit_cast<const uint8_t*>(bufferIt.data()),
                    bufferIt.size()};
                BMCWEB_LOG_DEBUG << "http2 is getting " << bufferSpan.size()
                                 << " bytes";
                ssize_t readLen = ngSession.memRecv(bufferSpan);
                if (readLen <= 0)
                {
                    BMCWEB_LOG_ERROR << "nghttp2_session_mem_recv returned "
                                     << readLen;
                    close();
                    return;
                }
                consumed += static_cast<size_t>(readLen);
            }
            inBuffer.consume(consumed);

            doRead();
            });
    }

    // A mapping from http2 stream ID to Stream Data
    boost::container::flat_map<int32_t, std::unique_ptr<Http2StreamData>>
        streams;

    boost::beast::multi_buffer sendBuffer;
    boost::beast::multi_buffer inBuffer;

    Adaptor adaptor;
    bool isWriting = false;

    nghttp2_session ngSession;

    Handler* handler;
    std::function<std::string()>& getCachedDateStr;

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

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