#include "base.hpp"

#include "common/utils.hpp"
#include "libpldmresponder/pdr.hpp"

#include <libpldm/base.h>
#include <libpldm/bios.h>
#include <libpldm/edac.h>
#include <libpldm/file.h>
#include <libpldm/fru.h>
#include <libpldm/platform.h>

#include <phosphor-logging/lg2.hpp>

#include <algorithm>
#include <array>
#include <bit>
#include <cstring>
#include <map>
#include <stdexcept>
#include <vector>

#ifdef OEM_IBM
#include <libpldm/oem/ibm/file_io.h>
#include <libpldm/oem/ibm/host.h>
#endif

PHOSPHOR_LOG2_USING;

namespace pldm
{
using Type = uint8_t;

namespace responder
{
using Cmd = std::vector<uint8_t>;

static const std::map<Type, Cmd> capabilities{
    {PLDM_BASE,
     {PLDM_GET_TID, PLDM_GET_PLDM_VERSION, PLDM_GET_PLDM_TYPES,
      PLDM_GET_PLDM_COMMANDS, PLDM_NEGOTIATE_TRANSFER_PARAMETERS,
      PLDM_MULTIPART_RECEIVE}},
    {PLDM_PLATFORM,
     {PLDM_GET_PDR, PLDM_SET_STATE_EFFECTER_STATES, PLDM_SET_EVENT_RECEIVER,
      PLDM_GET_SENSOR_READING, PLDM_GET_STATE_SENSOR_READINGS,
      PLDM_SET_NUMERIC_EFFECTER_VALUE, PLDM_GET_NUMERIC_EFFECTER_VALUE,
      PLDM_PLATFORM_EVENT_MESSAGE}},
    {PLDM_BIOS,
     {PLDM_GET_DATE_TIME, PLDM_SET_DATE_TIME, PLDM_GET_BIOS_TABLE,
      PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE,
      PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE, PLDM_SET_BIOS_TABLE}},
    {PLDM_FRU,
     {PLDM_GET_FRU_RECORD_TABLE_METADATA, PLDM_GET_FRU_RECORD_TABLE,
      PLDM_GET_FRU_RECORD_BY_OPTION}},
    {PLDM_FILE,
     {PLDM_FILE_CMD_DF_OPEN, PLDM_FILE_CMD_DF_CLOSE, PLDM_FILE_CMD_DF_READ}},
#ifdef OEM_IBM
    {PLDM_OEM,
     {PLDM_HOST_GET_ALERT_STATUS, PLDM_GET_FILE_TABLE, PLDM_READ_FILE,
      PLDM_WRITE_FILE, PLDM_READ_FILE_INTO_MEMORY, PLDM_WRITE_FILE_FROM_MEMORY,
      PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
      PLDM_NEW_FILE_AVAILABLE, PLDM_READ_FILE_BY_TYPE, PLDM_WRITE_FILE_BY_TYPE,
      PLDM_FILE_ACK}},
#endif
};

static const std::map<Type, ver32_t> versions{
    {PLDM_BASE, {0x00, 0xf0, 0xf0, 0xf1}},
    {PLDM_PLATFORM, {0x00, 0xf0, 0xf2, 0xf1}},
    {PLDM_BIOS, {0x00, 0xf0, 0xf0, 0xf1}},
    {PLDM_FRU, {0x00, 0xf0, 0xf0, 0xf1}},
    {PLDM_FILE, {0x00, 0xf0, 0xf0, 0xf1}},
#ifdef OEM_IBM
    {PLDM_OEM, {0x00, 0xf0, 0xf0, 0xf1}},
#endif
};

static const std::vector<Type> multipartSupportedTypes{
    PLDM_FILE,
};

namespace base
{
Response Handler::getPLDMTypes(const pldm_msg* request,
                               size_t /*payloadLength*/)
{
    // DSP0240 has this as a bitfield8[N], where N = 0 to 7
    std::array<bitfield8_t, 8> types{};
    for (const auto& type : capabilities)
    {
        auto index = type.first / 8;
        // <Type Number> = <Array Index> * 8 + <bit position>
        auto bit = type.first - (index * 8);
        types[index].byte |= 1 << bit;
    }

    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_TYPES_RESP_BYTES, 0);
    auto responsePtr = new (response.data()) pldm_msg;
    auto rc = encode_get_types_resp(request->hdr.instance_id, PLDM_SUCCESS,
                                    types.data(), responsePtr);
    if (rc != PLDM_SUCCESS)
    {
        return CmdHandler::ccOnlyResponse(request, rc);
    }

    return response;
}

Response Handler::getPLDMCommands(const pldm_msg* request, size_t payloadLength)
{
    ver32_t version{};
    Type type;

    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_RESP_BYTES, 0);
    auto responsePtr = new (response.data()) pldm_msg;

    auto rc = decode_get_commands_req(request, payloadLength, &type, &version);

    if (rc != PLDM_SUCCESS)
    {
        return CmdHandler::ccOnlyResponse(request, rc);
    }

    // DSP0240 has this as a bitfield8[N], where N = 0 to 31
    std::array<bitfield8_t, 32> cmds{};
    if (!capabilities.contains(type))
    {
        return CmdHandler::ccOnlyResponse(request,
                                          PLDM_ERROR_INVALID_PLDM_TYPE);
    }

    for (const auto& cmd : capabilities.at(type))
    {
        auto index = cmd / 8;
        // <Type Number> = <Array Index> * 8 + <bit position>
        auto bit = cmd - (index * 8);
        cmds[index].byte |= 1 << bit;
    }

    rc = encode_get_commands_resp(request->hdr.instance_id, PLDM_SUCCESS,
                                  cmds.data(), responsePtr);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    return response;
}

Response Handler::getPLDMVersion(const pldm_msg* request, size_t payloadLength)
{
    uint32_t transferHandle;
    Type type;
    uint8_t transferFlag;
    constexpr size_t checksumLen = sizeof(uint32_t);

    // Generate the response with 32bit checksum appended
    Response response(
        sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES + checksumLen, 0);
    auto responsePtr = new (response.data()) pldm_msg;

    uint8_t rc = decode_get_version_req(request, payloadLength, &transferHandle,
                                        &transferFlag, &type);

    if (rc != PLDM_SUCCESS)
    {
        return CmdHandler::ccOnlyResponse(request, rc);
    }

    ver32_t version{};
    auto search = versions.find(type);

    if (search == versions.end())
    {
        return CmdHandler::ccOnlyResponse(request,
                                          PLDM_ERROR_INVALID_PLDM_TYPE);
    }

    memcpy(&version, &(search->second), sizeof(version));
    rc = encode_get_version_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
                                 PLDM_START_AND_END, &version,
                                 sizeof(pldm_version), responsePtr);

    // Calculate the crc32
    uint32_t checksum = pldm_edac_crc32(&version, sizeof(version));
    checksum = htole32(checksum);
    memcpy(response.data() + sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES,
           &checksum, checksumLen);

    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    return response;
}

void Handler::_processSetEventReceiver(sdeventplus::source::EventBase&
                                       /*source */)
{
    survEvent.reset();
    oemPlatformHandler->processSetEventReceiver();
}

Response Handler::getTID(const pldm_msg* request, size_t /*payloadLength*/)
{
    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES, 0);
    auto responsePtr = new (response.data()) pldm_msg;
    auto rc = encode_get_tid_resp(request->hdr.instance_id, PLDM_SUCCESS,
                                  TERMINUS_ID, responsePtr);
    if (rc != PLDM_SUCCESS)
    {
        return ccOnlyResponse(request, rc);
    }

    if (oemPlatformHandler)
    {
        survEvent = std::make_unique<sdeventplus::source::Defer>(
            event, [this](sdeventplus::source::EventBase& source) {
                this->_processSetEventReceiver(source);
            });
    }

    return response;
}

Response Handler::getNegotiateTransferParam(
    pldm_tid_t tid, const pldm_msg* request, size_t payloadLength)
{
    struct pldm_base_negotiate_transfer_params_resp resp_payload_struct = {};
    struct pldm_base_negotiate_transfer_params_req decoded_req;
    Response response(sizeof(pldm_msg_hdr) +
                          PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES,
                      0);
    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());

    int rc = decode_pldm_base_negotiate_transfer_params_req(
        request, payloadLength, &decoded_req);
    if (rc != 0)
    {
        return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
    }

    // Part size should be a power of 2 and greater than PLDM_MIN_PART_SIZE
    if ((decoded_req.requester_part_size < PLDM_MIN_PART_SIZE) ||
        !std::has_single_bit(decoded_req.requester_part_size))
    {
        return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
    }

    // Only check the multipart types supported by the responder
    for (const auto& type : multipartSupportedTypes)
    {
        if (type > PLDM_TYPES_MAX)
        {
            error("Invalid type '{TYPE}'", "TYPE", type);
            return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
        }

        // In the decoded_req.requester_protocol_support array, pldm type is
        // array_index * 8 + bit
        auto index = type / 8;
        auto bit = type % 8;

        if (decoded_req.requester_protocol_support[index].byte & (1 << bit))
        {
            std::map<uint8_t, uint16_t>& type_map_for_tid =
                negotiatedPartSizes[tid];
            type_map_for_tid[type] =
                std::min(decoded_req.requester_part_size,
                         (uint16_t)PLDM_RESPONDER_PART_SIZE);

            info(
                "Multipart negotiated for tid:'{TID}' type:'{TYPE}' size:'{SIZE}'",
                "TID", tid, "TYPE", type, "SIZE",
                (uint16_t)type_map_for_tid[type]);
        }

        resp_payload_struct.responder_protocol_support[index].byte |=
            static_cast<uint8_t>(1 << bit);
    }

    resp_payload_struct.completion_code = PLDM_SUCCESS;
    resp_payload_struct.responder_part_size = PLDM_RESPONDER_PART_SIZE;

    size_t respPayloadLength =
        PLDM_BASE_NEGOTIATE_TRANSFER_PARAMETERS_RESP_BYTES;
    rc = encode_pldm_base_negotiate_transfer_params_resp(
        request->hdr.instance_id, &resp_payload_struct, responsePtr,
        &respPayloadLength);
    if (rc != 0)
    {
        return ccOnlyResponse(request, PLDM_ERROR);
    }

    return response;
}

uint16_t Handler::getNegotiatedPartSize(pldm_tid_t tid, uint8_t pldmType)
{
    auto tid_it = negotiatedPartSizes.find(tid);
    if (tid_it == negotiatedPartSizes.end())
    {
        return PLDM_MIN_PART_SIZE;
    }

    auto type_it = tid_it->second.find(pldmType);
    if (type_it == tid_it->second.end())
    {
        return PLDM_MIN_PART_SIZE;
    }

    return type_it->second;
}

Response Handler::getMultipartReceive(pldm_tid_t tid, const pldm_msg* request,
                                      size_t payloadLength)
{
    if (payloadLength != PLDM_MULTIPART_RECEIVE_REQ_BYTES)
    {
        error("Invalid MultipartReceive request length. Received: '{LEN}'",
              "LEN", payloadLength);
        return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
    }

    // First byte in the payload is the sub PLDM type.
    uint8_t pldmType = *request->payload;

    auto it = multipartReceivehandlers.find(pldmType);
    if (it == multipartReceivehandlers.end())
    {
        error("No multipart receive handler registered for PLDM type '{TYPE}'",
              "TYPE", pldmType);
        return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
    }

    return it->second->handleMultipartReceive(tid, request, payloadLength);
}

void Handler::registerMultipartReceiveHandler(uint8_t pldmType,
                                              CmdHandler* handler)
{
    multipartReceivehandlers.emplace(pldmType, handler);
}

} // namespace base
} // namespace responder
} // namespace pldm
