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

#include <sys/socket.h>

#include <boost/asio/local/stream_protocol.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/system/error_code.hpp>

#include <array>
#include <memory>
#include <string>
#include <string_view>

namespace crow
{
namespace obmc_console
{

// Update this value each time we add new console route.
static constexpr const uint maxSessions = 32;

class ConsoleHandler : public std::enable_shared_from_this<ConsoleHandler>
{
  public:
    ConsoleHandler(boost::asio::io_context& ioc,
                   crow::websocket::Connection& connIn) :
        hostSocket(ioc), conn(connIn)
    {}

    ~ConsoleHandler() = default;

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

    void doWrite()
    {
        if (doingWrite)
        {
            BMCWEB_LOG_DEBUG("Already writing.  Bailing out");
            return;
        }

        if (inputBuffer.empty())
        {
            BMCWEB_LOG_DEBUG("Outbuffer empty.  Bailing out");
            return;
        }

        doingWrite = true;
        hostSocket.async_write_some(
            boost::asio::buffer(inputBuffer.data(), inputBuffer.size()),
            [weak(weak_from_this())](const boost::beast::error_code& ec,
                                     std::size_t bytesWritten) {
                std::shared_ptr<ConsoleHandler> self = weak.lock();
                if (self == nullptr)
                {
                    return;
                }

                self->doingWrite = false;
                self->inputBuffer.erase(0, bytesWritten);

                if (ec == boost::asio::error::eof)
                {
                    self->conn.close("Error in reading to host port");
                    return;
                }
                if (ec)
                {
                    BMCWEB_LOG_ERROR("Error in host serial write {}",
                                     ec.message());
                    return;
                }
                self->doWrite();
            });
    }

    static void afterSendEx(const std::weak_ptr<ConsoleHandler>& weak)
    {
        std::shared_ptr<ConsoleHandler> self = weak.lock();
        if (self == nullptr)
        {
            return;
        }
        self->doRead();
    }

    void doRead()
    {
        BMCWEB_LOG_DEBUG("Reading from socket");
        hostSocket.async_read_some(
            boost::asio::buffer(outputBuffer),
            [this, weakSelf(weak_from_this())](
                const boost::system::error_code& ec, std::size_t bytesRead) {
                BMCWEB_LOG_DEBUG("read done.  Read {} bytes", bytesRead);
                std::shared_ptr<ConsoleHandler> self = weakSelf.lock();
                if (self == nullptr)
                {
                    return;
                }
                if (ec)
                {
                    BMCWEB_LOG_ERROR("Couldn't read from host serial port: {}",
                                     ec.message());
                    conn.close("Error connecting to host port");
                    return;
                }
                std::string_view payload(outputBuffer.data(), bytesRead);
                self->conn.sendEx(
                    crow::websocket::MessageType::Binary, payload,
                    std::bind_front(afterSendEx, weak_from_this()));
            });
    }

    bool connect(int fd)
    {
        boost::system::error_code ec;
        boost::asio::local::stream_protocol proto;

        hostSocket.assign(proto, fd, ec);

        if (ec)
        {
            BMCWEB_LOG_ERROR(
                "Failed to assign the DBUS socket Socket assign error: {}",
                ec.message());
            return false;
        }

        conn.resumeRead();
        doWrite();
        doRead();
        return true;
    }

    boost::asio::local::stream_protocol::socket hostSocket;

    std::array<char, 4096> outputBuffer{};

    std::string inputBuffer;
    bool doingWrite = false;
    crow::websocket::Connection& conn;
};

using ObmcConsoleMap = boost::container::flat_map<
    crow::websocket::Connection*, std::shared_ptr<ConsoleHandler>, std::less<>,
    std::vector<std::pair<crow::websocket::Connection*,
                          std::shared_ptr<ConsoleHandler>>>>;

inline ObmcConsoleMap& getConsoleHandlerMap()
{
    static ObmcConsoleMap map;
    return map;
}

// Remove connection from the connection map and if connection map is empty
// then remove the handler from handlers map.
inline void onClose(crow::websocket::Connection& conn, const std::string& err)
{
    BMCWEB_LOG_INFO("Closing websocket. Reason: {}", err);

    auto iter = getConsoleHandlerMap().find(&conn);
    if (iter == getConsoleHandlerMap().end())
    {
        BMCWEB_LOG_CRITICAL("Unable to find connection {}", logPtr(&conn));
        return;
    }
    BMCWEB_LOG_DEBUG("Remove connection {} from obmc console", logPtr(&conn));

    // Removed last connection so remove the path
    getConsoleHandlerMap().erase(iter);
}

inline void connectConsoleSocket(crow::websocket::Connection& conn,
                                 const boost::system::error_code& ec,
                                 const sdbusplus::message::unix_fd& unixfd)
{
    if (ec)
    {
        BMCWEB_LOG_ERROR(
            "Failed to call console Connect() method DBUS error: {}",
            ec.message());
        conn.close("Failed to connect");
        return;
    }

    // Look up the handler
    auto iter = getConsoleHandlerMap().find(&conn);
    if (iter == getConsoleHandlerMap().end())
    {
        BMCWEB_LOG_ERROR("Connection was already closed");
        return;
    }

    int fd = dup(unixfd);
    if (fd == -1)
    {
        BMCWEB_LOG_ERROR("Failed to dup the DBUS unixfd error: {}",
                         strerror(errno));
        conn.close("Internal error");
        return;
    }

    BMCWEB_LOG_DEBUG("Console duped FD: {}", fd);

    if (!iter->second->connect(fd))
    {
        close(fd);
        conn.close("Internal Error");
    }
}

inline void processConsoleObject(
    crow::websocket::Connection& conn, const std::string& consoleObjPath,
    const boost::system::error_code& ec,
    const ::dbus::utility::MapperGetObject& objInfo)
{
    // Look up the handler
    auto iter = getConsoleHandlerMap().find(&conn);
    if (iter == getConsoleHandlerMap().end())
    {
        BMCWEB_LOG_ERROR("Connection was already closed");
        return;
    }

    if (ec)
    {
        BMCWEB_LOG_WARNING("getDbusObject() for consoles failed. DBUS error:{}",
                           ec.message());
        conn.close("getDbusObject() for consoles failed.");
        return;
    }

    const auto valueIface = objInfo.begin();
    if (valueIface == objInfo.end())
    {
        BMCWEB_LOG_WARNING("getDbusObject() returned unexpected size: {}",
                           objInfo.size());
        conn.close("getDbusObject() returned unexpected size");
        return;
    }

    const std::string& consoleService = valueIface->first;
    BMCWEB_LOG_DEBUG("Looking up unixFD for Service {} Path {}", consoleService,
                     consoleObjPath);
    // Call Connect() method to get the unix FD
    crow::connections::systemBus->async_method_call(
        [&conn](const boost::system::error_code& ec1,
                const sdbusplus::message::unix_fd& unixfd) {
            connectConsoleSocket(conn, ec1, unixfd);
        },
        consoleService, consoleObjPath, "xyz.openbmc_project.Console.Access",
        "Connect");
}

// Query consoles from DBUS and find the matching to the
// rules string.
inline void onOpen(crow::websocket::Connection& conn)
{
    std::string consoleLeaf;

    BMCWEB_LOG_DEBUG("Connection {} opened", logPtr(&conn));

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

    std::shared_ptr<ConsoleHandler> handler =
        std::make_shared<ConsoleHandler>(conn.getIoContext(), conn);
    getConsoleHandlerMap().emplace(&conn, handler);

    conn.deferRead();

    // Keep old path for backward compatibility
    if (conn.url().path() == "/console0")
    {
        consoleLeaf = "default";
    }
    else
    {
        // Get the console id from console router path and prepare the console
        // object path and console service.
        consoleLeaf = conn.url().segments().back();
    }
    std::string consolePath =
        sdbusplus::message::object_path("/xyz/openbmc_project/console") /
        consoleLeaf;

    BMCWEB_LOG_DEBUG("Console Object path = {} Request target = {}",
                     consolePath, conn.url().path());

    // mapper call lambda
    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Console.Access"};

    dbus::utility::getDbusObject(
        consolePath, interfaces,
        [&conn, consolePath](const boost::system::error_code& ec,
                             const ::dbus::utility::MapperGetObject& objInfo) {
            processConsoleObject(conn, consolePath, ec, objInfo);
        });
}

inline void onMessage(crow::websocket::Connection& conn,
                      const std::string& data, bool /*isBinary*/)
{
    auto handler = getConsoleHandlerMap().find(&conn);
    if (handler == getConsoleHandlerMap().end())
    {
        BMCWEB_LOG_CRITICAL("Unable to find connection {}", logPtr(&conn));
        return;
    }
    handler->second->inputBuffer += data;
    handler->second->doWrite();
}

inline void requestRoutes(App& app)
{
    BMCWEB_ROUTE(app, "/console0")
        .privileges({{"OpenBMCHostConsole"}})
        .websocket()
        .onopen(onOpen)
        .onclose(onClose)
        .onmessage(onMessage);

    BMCWEB_ROUTE(app, "/console/<str>")
        .privileges({{"OpenBMCHostConsole"}})
        .websocket()
        .onopen(onOpen)
        .onclose(onClose)
        .onmessage(onMessage);
}
} // namespace obmc_console
} // namespace crow
