#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>

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 " << bytesRead << " bytes";
            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 " << &conn;
        return;
    }
    BMCWEB_LOG_DEBUG << "Remove connection " << &conn << " from obmc console";

    // 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 unix FD: " << unixfd << " 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 " << consoleService
                     << " Path " << 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 " << &conn << " opened";

    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 = " << consolePath
                     << " Request target = " << 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 " << &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
