#include "command_table.hpp"

#include "main.hpp"
#include "message_handler.hpp"
#include "message_parsers.hpp"
#include "sessions_manager.hpp"

#include <ipmid/types.hpp>
#include <main.hpp>
#include <phosphor-logging/lg2.hpp>
#include <user_channel/user_layer.hpp>

#include <iomanip>

namespace command
{

void Table::registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry)
{
    auto& command = commandTable[inCommand.command];

    if (command)
    {
        lg2::debug("Already Registered: {COMMAND}", "COMMAND",
                   inCommand.command);
        return;
    }

    command = std::move(entry);
}

void Table::executeCommand(uint32_t inCommand,
                           std::vector<uint8_t>& commandData,
                           std::shared_ptr<message::Handler> handler)
{
    using namespace std::chrono_literals;

    auto iterator = commandTable.find(inCommand);

    if (iterator == commandTable.end())
    {
        CommandID command(inCommand);

        // Do not forward any session zero commands to ipmid
        if (handler->sessionID == session::sessionZero)
        {
            lg2::info(
                "Table: refuse to forward session-zero command: lun: {LUN}, netFn: {NETFN}, command: {COMMAND}",
                "LUN", command.lun(), "NETFN", command.netFn(), "COMMAND",
                command.cmd());
            return;
        }
        std::shared_ptr<session::Session> session =
            session::Manager::get().getSession(handler->sessionID);

        // Ignore messages that are not part of an active session
        auto state = static_cast<session::State>(session->state());
        if (state != session::State::active)
        {
            return;
        }

        auto bus = getSdBus();
        // forward the request onto the main ipmi queue
        using IpmiDbusRspType = std::tuple<uint8_t, uint8_t, uint8_t, uint8_t,
                                           std::vector<uint8_t>>;
        uint8_t lun = command.lun();
        uint8_t netFn = command.netFn();
        uint8_t cmd = command.cmd();

        std::map<std::string, ipmi::Value> options = {
            {"userId", ipmi::Value(static_cast<int>(
                           ipmi::ipmiUserGetUserId(session->userName)))},
            {"privilege",
             ipmi::Value(static_cast<int>(session->currentPrivilege()))},
            {"currentSessionId",
             ipmi::Value(static_cast<uint32_t>(session->getBMCSessionID()))},
        };
        bus->async_method_call(
            [handler, this](const boost::system::error_code& ec,
                            const IpmiDbusRspType& response) {
            if (!ec)
            {
                const uint8_t& cc = std::get<3>(response);
                const std::vector<uint8_t>& responseData =
                    std::get<4>(response);
                std::vector<uint8_t> payload;
                payload.reserve(1 + responseData.size());
                payload.push_back(cc);
                payload.insert(payload.end(), responseData.begin(),
                               responseData.end());
                handler->outPayload = std::move(payload);
            }
            else
            {
                std::vector<uint8_t> payload;
                payload.push_back(IPMI_CC_UNSPECIFIED_ERROR);
                handler->outPayload = std::move(payload);
            }
            },
            "xyz.openbmc_project.Ipmi.Host", "/xyz/openbmc_project/Ipmi",
            "xyz.openbmc_project.Ipmi.Server", "execute", netFn, lun, cmd,
            commandData, options);
    }
    else
    {
        auto start = std::chrono::steady_clock::now();

        // Ignore messages that are not part of an active/pre-active session
        if (handler->sessionID != session::sessionZero)
        {
            std::shared_ptr<session::Session> session =
                session::Manager::get().getSession(handler->sessionID);
            auto state = static_cast<session::State>(session->state());
            if ((state != session::State::setupInProgress) &&
                (state != session::State::active))
            {
                return;
            }
        }

        handler->outPayload = iterator->second->executeCommand(commandData,
                                                               handler);

        auto end = std::chrono::steady_clock::now();

        std::chrono::duration<size_t> elapsedSeconds =
            std::chrono::duration_cast<std::chrono::seconds>(end - start);

        // If command time execution time exceeds 2 seconds, log a time
        // exceeded message
        if (elapsedSeconds > 2s)
        {
            lg2::error("IPMI command timed out: {DELAY}", "DELAY",
                       elapsedSeconds.count());
        }
    }
}

std::vector<uint8_t>
    NetIpmidEntry::executeCommand(std::vector<uint8_t>& commandData,
                                  std::shared_ptr<message::Handler> handler)
{
    std::vector<uint8_t> errResponse;

    // Check if the command qualifies to be run prior to establishing a session
    if (!sessionless && (handler->sessionID == session::sessionZero))
    {
        errResponse.resize(1);
        errResponse[0] = IPMI_CC_INSUFFICIENT_PRIVILEGE;
        lg2::info(
            "Table: Insufficient privilege for command: lun: {LUN}, netFn: {NETFN}, command: {COMMAND}",
            "LUN", command.lun(), "NETFN", command.netFn(), "COMMAND",
            command.cmd());
        return errResponse;
    }

    return functor(commandData, handler);
}

} // namespace command
