#include "payload_cmds.hpp"

#include "main.hpp"
#include "sol/sol_manager.hpp"
#include "sol_cmds.hpp"

#include <ipmid/api.h>

#include <phosphor-logging/log.hpp>

namespace sol
{

namespace command
{

using namespace phosphor::logging;

std::vector<uint8_t> activatePayload(const std::vector<uint8_t>& inPayload,
                                     const message::Handler& handler)
{
    std::vector<uint8_t> outPayload(sizeof(ActivatePayloadResponse));
    auto request =
        reinterpret_cast<const ActivatePayloadRequest*>(inPayload.data());
    auto response =
        reinterpret_cast<ActivatePayloadResponse*>(outPayload.data());

    response->completionCode = IPMI_CC_OK;

    // SOL is the payload currently supported for activation.
    if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
    {
        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
        return outPayload;
    }

    if (!std::get<sol::Manager&>(singletonPool).enable)
    {
        response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
        return outPayload;
    }

    // Only one instance of SOL is currently supported.
    if (request->payloadInstance != 1)
    {
        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
        return outPayload;
    }

    auto session = std::get<session::Manager&>(singletonPool)
                       .getSession(handler.sessionID);

    if (!request->encryption && session->isCryptAlgoEnabled())
    {
        response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION;
        return outPayload;
    }

    // Is SOL Payload enabled for this user & channel.
    auto userId = ipmi::ipmiUserGetUserId(session->userName);
    ipmi::PayloadAccess payloadAccess = {};
    if ((ipmi::ipmiUserGetUserPayloadAccess(session->channelNum(), userId,
                                            payloadAccess) != IPMI_CC_OK) ||
        !(payloadAccess.stdPayloadEnables1[static_cast<uint8_t>(
            message::PayloadType::SOL)]))
    {
        response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
        return outPayload;
    }

    auto status = std::get<sol::Manager&>(singletonPool)
                      .isPayloadActive(request->payloadInstance);
    if (status)
    {
        response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
        return outPayload;
    }

    // Set the current command's socket channel to the session
    handler.setChannelInSession();

    // Start the SOL payload
    try
    {
        std::get<sol::Manager&>(singletonPool)
            .startPayloadInstance(request->payloadInstance, handler.sessionID);
    }
    catch (std::exception& e)
    {
        log<level::ERR>(e.what());
        response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
        return outPayload;
    }

    response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
    response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
    response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);

    // VLAN addressing is not used
    response->vlanNum = 0xFFFF;

    return outPayload;
}

std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload,
                                       const message::Handler& handler)
{
    std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
    auto request =
        reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data());
    auto response =
        reinterpret_cast<DeactivatePayloadResponse*>(outPayload.data());

    response->completionCode = IPMI_CC_OK;

    if (inPayload.size() != sizeof(DeactivatePayloadRequest))
    {
        response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
        return outPayload;
    }

    // SOL is the payload currently supported for deactivation
    if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
    {
        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
        return outPayload;
    }

    // Only one instance of SOL is supported
    if (request->payloadInstance != 1)
    {
        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
        return outPayload;
    }

    auto status = std::get<sol::Manager&>(singletonPool)
                      .isPayloadActive(request->payloadInstance);
    if (!status)
    {
        response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
        return outPayload;
    }

    try
    {
        auto& context = std::get<sol::Manager&>(singletonPool)
                            .getContext(request->payloadInstance);
        auto sessionID = context.sessionID;

        std::get<sol::Manager&>(singletonPool)
            .stopPayloadInstance(request->payloadInstance);

        try
        {
            activating(request->payloadInstance, sessionID);
        }
        catch (std::exception& e)
        {
            log<level::INFO>(e.what());
            /*
             * In case session has been closed (like in the case of inactivity
             * timeout), then activating function would throw an exception,
             * since sessionID is not found. IPMI success completion code is
             * returned, since the session is closed.
             */
            return outPayload;
        }

        auto check =
            std::get<session::Manager&>(singletonPool).stopSession(sessionID);
        if (!check)
        {
            response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
        }
    }
    catch (std::exception& e)
    {
        log<level::ERR>(e.what());
        response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
        return outPayload;
    }

    return outPayload;
}

std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
                                      const message::Handler& handler)
{
    std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
    auto request =
        reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
    auto response =
        reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data());

    // SOL is the payload currently supported for payload status
    if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
    {
        response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
        return outPayload;
    }

    response->completionCode = IPMI_CC_OK;
    response->capacity = MAX_PAYLOAD_INSTANCES;

    // Currently we support only one SOL session
    response->instance1 =
        std::get<sol::Manager&>(singletonPool).isPayloadActive(1);

    return outPayload;
}

std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
                                    const message::Handler& handler)
{
    std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
    auto request =
        reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
    auto response =
        reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());

    if (inPayload.size() != sizeof(GetPayloadInfoRequest))
    {
        response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
        return outPayload;
    }
    // SOL is the payload currently supported for payload status & only one
    // instance of SOL is supported.
    if (static_cast<uint8_t>(message::PayloadType::SOL) !=
            request->payloadType ||
        request->payloadInstance != 1)
    {
        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
        return outPayload;
    }
    auto status = std::get<sol::Manager&>(singletonPool)
                      .isPayloadActive(request->payloadInstance);

    if (status)
    {
        auto& context = std::get<sol::Manager&>(singletonPool)
                            .getContext(request->payloadInstance);
        response->sessionID = context.sessionID;
    }
    else
    {
        // No active payload - return session id as 0
        response->sessionID = 0;
    }
    response->completionCode = IPMI_CC_OK;
    return outPayload;
}

} // namespace command

} // namespace sol
