#pragma once
#include "app.hpp"
#include "async_resp.hpp"
#include "websocket.hpp"

#include <sys/socket.h>

#include <boost/container/flat_map.hpp>

namespace crow
{
namespace obmc_kvm
{

static constexpr const uint maxSessions = 4;

class KvmSession : public std::enable_shared_from_this<KvmSession>
{
  public:
    explicit KvmSession(crow::websocket::Connection& connIn) :
        conn(connIn), hostSocket(conn.getIoContext())
    {
        boost::asio::ip::tcp::endpoint endpoint(
            boost::asio::ip::make_address("127.0.0.1"), 5900);
        hostSocket.async_connect(
            endpoint, [this, &connIn](const boost::system::error_code& ec) {
            if (ec)
            {
                BMCWEB_LOG_ERROR(
                    "conn:{}, Couldn't connect to KVM socket port: {}",
                    logPtr(&conn), ec);
                if (ec != boost::asio::error::operation_aborted)
                {
                    connIn.close("Error in connecting to KVM port");
                }
                return;
            }

            doRead();
        });
    }

    void onMessage(const std::string& data)
    {
        if (data.length() > inputBuffer.capacity())
        {
            BMCWEB_LOG_ERROR("conn:{}, Buffer overrun when writing {} bytes",
                             logPtr(&conn), data.length());
            conn.close("Buffer overrun");
            return;
        }

        BMCWEB_LOG_DEBUG("conn:{}, Read {} bytes from websocket", logPtr(&conn),
                         data.size());
        size_t copied = boost::asio::buffer_copy(
            inputBuffer.prepare(data.size()), boost::asio::buffer(data));
        BMCWEB_LOG_DEBUG("conn:{}, Committing {} bytes from websocket",
                         logPtr(&conn), copied);
        inputBuffer.commit(copied);

        BMCWEB_LOG_DEBUG("conn:{}, inputbuffer size {}", logPtr(&conn),
                         inputBuffer.size());
        doWrite();
    }

  protected:
    void doRead()
    {
        std::size_t bytes = outputBuffer.capacity() - outputBuffer.size();
        BMCWEB_LOG_DEBUG("conn:{}, Reading {} from kvm socket", logPtr(&conn),
                         bytes);
        hostSocket.async_read_some(
            outputBuffer.prepare(outputBuffer.capacity() - outputBuffer.size()),
            [this, weak(weak_from_this())](const boost::system::error_code& ec,
                                           std::size_t bytesRead) {
            auto self = weak.lock();
            if (self == nullptr)
            {
                return;
            }
            BMCWEB_LOG_DEBUG("conn:{}, read done.  Read {} bytes",
                             logPtr(&conn), bytesRead);
            if (ec)
            {
                BMCWEB_LOG_ERROR(
                    "conn:{}, Couldn't read from KVM socket port: {}",
                    logPtr(&conn), ec);
                if (ec != boost::asio::error::operation_aborted)
                {
                    conn.close("Error in connecting to KVM port");
                }
                return;
            }

            outputBuffer.commit(bytesRead);
            std::string_view payload(
                static_cast<const char*>(outputBuffer.data().data()),
                bytesRead);
            BMCWEB_LOG_DEBUG("conn:{}, Sending payload size {}", logPtr(&conn),
                             payload.size());
            conn.sendBinary(payload);
            outputBuffer.consume(bytesRead);

            doRead();
        });
    }

    void doWrite()
    {
        if (doingWrite)
        {
            BMCWEB_LOG_DEBUG("conn:{}, Already writing.  Bailing out",
                             logPtr(&conn));
            return;
        }
        if (inputBuffer.size() == 0)
        {
            BMCWEB_LOG_DEBUG("conn:{}, inputBuffer empty.  Bailing out",
                             logPtr(&conn));
            return;
        }

        doingWrite = true;
        hostSocket.async_write_some(
            inputBuffer.data(),
            [this, weak(weak_from_this())](const boost::system::error_code& ec,
                                           std::size_t bytesWritten) {
            auto self = weak.lock();
            if (self == nullptr)
            {
                return;
            }
            BMCWEB_LOG_DEBUG("conn:{}, Wrote {}bytes", logPtr(&conn),
                             bytesWritten);
            doingWrite = false;
            inputBuffer.consume(bytesWritten);

            if (ec == boost::asio::error::eof)
            {
                conn.close("KVM socket port closed");
                return;
            }
            if (ec)
            {
                BMCWEB_LOG_ERROR("conn:{}, Error in KVM socket write {}",
                                 logPtr(&conn), ec);
                if (ec != boost::asio::error::operation_aborted)
                {
                    conn.close("Error in reading to host port");
                }
                return;
            }

            doWrite();
        });
    }

    crow::websocket::Connection& conn;
    boost::asio::ip::tcp::socket hostSocket;
    boost::beast::flat_static_buffer<1024UL * 50UL> outputBuffer;
    boost::beast::flat_static_buffer<1024UL> inputBuffer;
    bool doingWrite{false};
};

using SessionMap = boost::container::flat_map<crow::websocket::Connection*,
                                              std::shared_ptr<KvmSession>>;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static SessionMap sessions;

inline void requestRoutes(App& app)
{
    sessions.reserve(maxSessions);

    BMCWEB_ROUTE(app, "/kvm/0")
        .privileges({{"ConfigureComponents", "ConfigureManager"}})
        .websocket()
        .onopen([](crow::websocket::Connection& conn) {
        BMCWEB_LOG_DEBUG("Connection {} opened", logPtr(&conn));

        if (sessions.size() == maxSessions)
        {
            conn.close("Max sessions are already connected");
            return;
        }

        sessions[&conn] = std::make_shared<KvmSession>(conn);
    })
        .onclose([](crow::websocket::Connection& conn, const std::string&) {
        sessions.erase(&conn);
    })
        .onmessage([](crow::websocket::Connection& conn,
                      const std::string& data, bool) {
        if (sessions[&conn])
        {
            sessions[&conn]->onMessage(data);
        }
    });
}

} // namespace obmc_kvm
} // namespace crow
