#pragma once

extern "C"
{
#include <nghttp2/nghttp2.h>
}

#include "logging.hpp"

#include <span>

/* This file contains RAII compatible adapters for nghttp2 structures.  They
 * attempt to be as close to a direct call as possible, while keeping the RAII
 * lifetime safety for the various classes.*/

struct nghttp2_session;

struct nghttp2_session_callbacks
{
    friend nghttp2_session;
    nghttp2_session_callbacks()
    {
        nghttp2_session_callbacks_new(&ptr);
    }

    ~nghttp2_session_callbacks()
    {
        nghttp2_session_callbacks_del(ptr);
    }

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

    void setSendCallback(nghttp2_send_callback sendCallback)
    {
        nghttp2_session_callbacks_set_send_callback(ptr, sendCallback);
    }

    void setOnFrameRecvCallback(nghttp2_on_frame_recv_callback recvCallback)
    {
        nghttp2_session_callbacks_set_on_frame_recv_callback(ptr, recvCallback);
    }

    void setOnStreamCloseCallback(nghttp2_on_stream_close_callback onClose)
    {
        nghttp2_session_callbacks_set_on_stream_close_callback(ptr, onClose);
    }

    void setOnHeaderCallback(nghttp2_on_header_callback onHeader)
    {
        nghttp2_session_callbacks_set_on_header_callback(ptr, onHeader);
    }

    void setOnBeginHeadersCallback(
        nghttp2_on_begin_headers_callback onBeginHeaders)
    {
        nghttp2_session_callbacks_set_on_begin_headers_callback(ptr,
                                                                onBeginHeaders);
    }

    void setSendDataCallback(nghttp2_send_data_callback onSendData)
    {
        nghttp2_session_callbacks_set_send_data_callback(ptr, onSendData);
    }
    void setBeforeFrameSendCallback(
        nghttp2_before_frame_send_callback beforeSendFrame)
    {
        nghttp2_session_callbacks_set_before_frame_send_callback(
            ptr, beforeSendFrame);
    }
    void
        setAfterFrameSendCallback(nghttp2_on_frame_send_callback afterSendFrame)
    {
        nghttp2_session_callbacks_set_on_frame_send_callback(ptr,
                                                             afterSendFrame);
    }
    void setAfterFrameNoSendCallback(
        nghttp2_on_frame_not_send_callback afterSendFrame)
    {
        nghttp2_session_callbacks_set_on_frame_not_send_callback(
            ptr, afterSendFrame);
    }

    void setOnDataChunkRecvCallback(
        nghttp2_on_data_chunk_recv_callback afterDataChunkRecv)
    {
        nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
            ptr, afterDataChunkRecv);
    }

  private:
    nghttp2_session_callbacks* get()
    {
        return ptr;
    }

    nghttp2_session_callbacks* ptr = nullptr;
};

struct nghttp2_session
{
    explicit nghttp2_session(nghttp2_session_callbacks& callbacks)
    {
        if (nghttp2_session_server_new(&ptr, callbacks.get(), nullptr) != 0)
        {
            BMCWEB_LOG_ERROR("nghttp2_session_server_new failed");
            return;
        }
    }

    ~nghttp2_session()
    {
        nghttp2_session_del(ptr);
    }

    // explicitly uncopyable
    nghttp2_session(const nghttp2_session&) = delete;
    nghttp2_session& operator=(const nghttp2_session&) = delete;

    nghttp2_session(nghttp2_session&& other) noexcept : ptr(other.ptr)
    {
        other.ptr = nullptr;
    }

    nghttp2_session& operator=(nghttp2_session&& other) noexcept = delete;

    int submitSettings(std::span<nghttp2_settings_entry> iv)
    {
        return nghttp2_submit_settings(ptr, NGHTTP2_FLAG_NONE, iv.data(),
                                       iv.size());
    }
    void setUserData(void* object)
    {
        nghttp2_session_set_user_data(ptr, object);
    }

    ssize_t memRecv(std::span<const uint8_t> buffer)
    {
        return nghttp2_session_mem_recv(ptr, buffer.data(), buffer.size());
    }

    std::span<const uint8_t> memSend()
    {
        const uint8_t* bytes = nullptr;
        ssize_t size = nghttp2_session_mem_send(ptr, &bytes);
        return {bytes, static_cast<size_t>(size)};
    }

    int submitResponse(int32_t streamId, std::span<const nghttp2_nv> headers,
                       const nghttp2_data_provider* dataPrd)
    {
        return nghttp2_submit_response(ptr, streamId, headers.data(),
                                       headers.size(), dataPrd);
    }

  private:
    nghttp2_session* ptr = nullptr;
};

class nghttp2_hd_inflater
{
    nghttp2_hd_inflater* ptr = nullptr;

  public:
    nghttp2_hd_inflater()
    {
        if (nghttp2_hd_inflate_new(&ptr) != 0)
        {
            BMCWEB_LOG_ERROR("nghttp2_hd_inflater_new failed");
        }
    }

    ssize_t hd2(nghttp2_nv* nvOut, int* inflateFlags, const uint8_t* in,
                size_t inlen, int inFinal)
    {
        return nghttp2_hd_inflate_hd2(ptr, nvOut, inflateFlags, in, inlen,
                                      inFinal);
    }

    int endHeaders()
    {
        return nghttp2_hd_inflate_end_headers(ptr);
    }

    nghttp2_hd_inflater(const nghttp2_hd_inflater&) = delete;
    nghttp2_hd_inflater& operator=(const nghttp2_hd_inflater&) = delete;
    nghttp2_hd_inflater& operator=(nghttp2_hd_inflater&&) = delete;
    nghttp2_hd_inflater(nghttp2_hd_inflater&& other) = delete;

    ~nghttp2_hd_inflater()
    {
        if (ptr != nullptr)
        {
            nghttp2_hd_inflate_del(ptr);
        }
    }
};
