#include "inventory_manager.hpp"

#include "common/utils.hpp"
#include "xyz/openbmc_project/Software/Version/server.hpp"

#include <libpldm/firmware_update.h>

#include <phosphor-logging/lg2.hpp>

#include <functional>

PHOSPHOR_LOG2_USING;

namespace pldm
{
namespace fw_update
{
void InventoryManager::discoverFDs(const std::vector<mctp_eid_t>& eids,
                                   const int retriesLeft)
{
    for (const auto& eid : eids)
    {
        auto instanceIdResult = instanceIdDb.next(eid);
        if (!instanceIdResult)
        {
            error("Instance ID allocation failed for EID {EID}", "EID",
                  unsigned(eid));
            throw pldm::InstanceIdError(instanceIdResult.error());
        }
        auto instanceId = instanceIdResult.value();
        Request requestMsg(
            sizeof(pldm_msg_hdr) + PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES);
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
        auto rc = encode_query_device_identifiers_req(
            instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, request);
        if (rc)
        {
            instanceIdDb.free(eid, instanceId);
            error(
                "encode_query_device_identifiers_req failed, EID={EID}, RC = {RC}",
                "EID", unsigned(eid), "RC", rc);
            continue;
        }

        rc = handler.registerRequest(
            eid, instanceId, PLDM_FWUP, PLDM_QUERY_DEVICE_IDENTIFIERS,
            std::move(requestMsg),
            std::move(std::bind_front(&InventoryManager::queryDeviceIdentifiers,
                                      this, retriesLeft)));
        if (rc)
        {
            error(
                "Failed to send QueryDeviceIdentifiers request, EID={EID}, RC = {RC}",
                "EID", unsigned(eid), "RC", rc);
        }
        else
        {
            info(
                "Sent QueryDeviceIdentifiers request, EID={EID}, retries remaining: {RETRY}",
                "EID", unsigned(eid), "RETRY", unsigned(retriesLeft));
        }
    }
}

void InventoryManager::queryDeviceIdentifiers(
    const int retriesLeft, mctp_eid_t eid, const pldm_msg* response,
    size_t respMsgLen)
{
    if (response == nullptr || !respMsgLen)
    {
        if (retriesLeft > 0)
        {
            error("No response received for QueryDeviceIdentifiers, EID={EID}. "
                  "We really want this. Retries remaining: {RETRY}",
                  "EID", unsigned(eid), "RETRY", unsigned(retriesLeft));
            discoverFDs({eid}, retriesLeft - 1);
        }
        else
        {
            error(
                "No response received for QueryDeviceIdentifiers, EID={EID}. No more retries remaining. Womp womp.",
                "EID", unsigned(eid));
        }
        return;
    }

    uint8_t completionCode = PLDM_SUCCESS;
    uint32_t deviceIdentifiersLen = 0;
    uint8_t descriptorCount = 0;
    uint8_t* descriptorPtr = nullptr;

    auto rc = decode_query_device_identifiers_resp(
        response, respMsgLen, &completionCode, &deviceIdentifiersLen,
        &descriptorCount, &descriptorPtr);
    if (rc)
    {
        error(
            "Decoding QueryDeviceIdentifiers response failed, EID={EID}, RC = {RC}",
            "EID", unsigned(eid), "RC", rc);
        return;
    }

    if (completionCode)
    {
        error(
            "QueryDeviceIdentifiers response failed with error completion code, EID={EID}, CC = {CC}",
            "EID", unsigned(eid), "CC", unsigned(completionCode));
        return;
    }

    Descriptors descriptors{};
    while (descriptorCount-- && (deviceIdentifiersLen > 0))
    {
        uint16_t descriptorType = 0;
        variable_field descriptorData{};

        rc = decode_descriptor_type_length_value(
            descriptorPtr, deviceIdentifiersLen, &descriptorType,
            &descriptorData);
        if (rc)
        {
            error(
                "Decoding descriptor type, length and value failed, EID={EID}, RC = {RC}",
                "EID", unsigned(eid), "RC", rc);
            return;
        }

        if (descriptorType != PLDM_FWUP_VENDOR_DEFINED)
        {
            std::vector<uint8_t> descData(
                descriptorData.ptr, descriptorData.ptr + descriptorData.length);
            descriptors.emplace(descriptorType, std::move(descData));
        }
        else
        {
            uint8_t descriptorTitleStrType = 0;
            variable_field descriptorTitleStr{};
            variable_field vendorDefinedDescriptorData{};

            rc = decode_vendor_defined_descriptor_value(
                descriptorData.ptr, descriptorData.length,
                &descriptorTitleStrType, &descriptorTitleStr,
                &vendorDefinedDescriptorData);
            if (rc)
            {
                error(
                    "Decoding Vendor-defined descriptor value failed, EID={EID}, RC = {RC}",
                    "EID", unsigned(eid), "RC", rc);
                return;
            }

            auto vendorDefinedDescriptorTitleStr =
                utils::toString(descriptorTitleStr);
            std::vector<uint8_t> vendorDescData(
                vendorDefinedDescriptorData.ptr,
                vendorDefinedDescriptorData.ptr +
                    vendorDefinedDescriptorData.length);
            descriptors.emplace(descriptorType,
                                std::make_tuple(vendorDefinedDescriptorTitleStr,
                                                vendorDescData));
        }
        auto nextDescriptorOffset =
            sizeof(pldm_descriptor_tlv().descriptor_type) +
            sizeof(pldm_descriptor_tlv().descriptor_length) +
            descriptorData.length;
        descriptorPtr += nextDescriptorOffset;
        deviceIdentifiersLen -= nextDescriptorOffset;
    }

    info("EID: {EID} Descriptors:", "EID", unsigned(eid));
    for (const auto& [descriptor_type, descriptor] : descriptors)
    {
        if (std::holds_alternative<DescriptorData>(descriptor))
        {
            const auto desc = std::get<DescriptorData>(descriptor);
            std::stringstream ss;
            ss << std::hex << std::setfill('0');
            for (const auto& byte : desc)
            {
                ss << std::setw(2) << static_cast<int>(byte);
            }
            info("Descriptor type: {TYPE}, descriptor: {DESC}", "TYPE",
                 descriptor_type, "DESC", ss.str());
        }
        else
        {
            const auto [desc_title, desc] =
                std::get<VendorDefinedDescriptorInfo>(descriptor);
            std::stringstream ss;
            ss << std::hex << std::setfill('0');
            for (const auto& byte : desc)
            {
                ss << std::setw(2) << static_cast<int>(byte);
            }
            info("Descriptor type: {TYPE}, descriptor: {DESC_TITLE} {DESC}",
                 "TYPE", descriptor_type, "DESC_TITLE", desc_title, "DESC",
                 ss.str());
        }
    }
    descriptorMap.emplace(eid, std::move(descriptors));

    // Send GetFirmwareParameters request
    sendGetFirmwareParametersRequest(retriesLeft, eid);
}

void InventoryManager::sendGetFirmwareParametersRequest(const int retriesLeft,
                                                        mctp_eid_t eid)
{
    auto instanceIdResult = instanceIdDb.next(eid);
    if (!instanceIdResult)
    {
        error("Instance ID allocation failed for EID {EID}", "EID",
              unsigned(eid));
        throw pldm::InstanceIdError(instanceIdResult.error());
    }
    auto instanceId = instanceIdResult.value();
    Request requestMsg(
        sizeof(pldm_msg_hdr) + PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES);
    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
    auto rc = encode_get_firmware_parameters_req(
        instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, request);
    if (rc)
    {
        instanceIdDb.free(eid, instanceId);
        error("encode_get_firmware_parameters_req failed, EID={EID}, RC = {RC}",
              "EID", unsigned(eid), "RC", rc);
        return;
    }

    rc = handler.registerRequest(
        eid, instanceId, PLDM_FWUP, PLDM_GET_FIRMWARE_PARAMETERS,
        std::move(requestMsg),
        std::move(std::bind_front(&InventoryManager::getFirmwareParameters,
                                  this, retriesLeft)));
    if (rc)
    {
        error(
            "Failed to send GetFirmwareParameters request, EID={EID}, RC = {RC}",
            "EID", unsigned(eid), "RC", rc);
    }
    else
    {
        info(
            "Sent GetFirmwareParameters request, EID={EID}, retries remaining: {RETRY}",
            "EID", unsigned(eid), "RETRY", unsigned(retriesLeft));
    }
}

void InventoryManager::getFirmwareParameters(
    const int retriesLeft, mctp_eid_t eid, const pldm_msg* response,
    size_t respMsgLen)
{
    if (response == nullptr || !respMsgLen)
    {
        if (retriesLeft > 0)
        {
            error("No response received for GetFirmwareParameters, EID={EID}. "
                  "We really want this. Retries remaining: {RETRY}",
                  "EID", unsigned(eid), "RETRY", unsigned(retriesLeft));
            sendGetFirmwareParametersRequest(retriesLeft - 1, eid);
        }
        else
        {
            error(
                "No response received for GetFirmwareParameters, EID={EID}. No more retries remaining. Womp womp.",
                "EID", unsigned(eid));
        }
        descriptorMap.erase(eid);
        return;
    }

    pldm_get_firmware_parameters_resp fwParams{};
    variable_field activeCompImageSetVerStr{};
    variable_field pendingCompImageSetVerStr{};
    variable_field compParamTable{};

    auto rc = decode_get_firmware_parameters_resp(
        response, respMsgLen, &fwParams, &activeCompImageSetVerStr,
        &pendingCompImageSetVerStr, &compParamTable);
    if (rc)
    {
        error(
            "Decoding GetFirmwareParameters response failed, EID={EID}, RC = {RC}",
            "EID", unsigned(eid), "RC", rc);
        return;
    }

    if (fwParams.completion_code)
    {
        error(
            "GetFirmwareParameters response failed with error completion code, EID={EID}, CC = {CC}",
            "EID", unsigned(eid), "CC", unsigned(fwParams.completion_code));
        return;
    }

    auto compParamPtr = compParamTable.ptr;
    auto compParamTableLen = compParamTable.length;
    pldm_component_parameter_entry compEntry{};
    variable_field activeCompVerStr{};
    variable_field pendingCompVerStr{};

    ComponentInfo componentInfo{};
    while (fwParams.comp_count-- && (compParamTableLen > 0))
    {
        auto rc = decode_get_firmware_parameters_resp_comp_entry(
            compParamPtr, compParamTableLen, &compEntry, &activeCompVerStr,
            &pendingCompVerStr);
        if (rc)
        {
            error(
                "Decoding component parameter table entry failed, EID={EID}, RC = {RC}",
                "EID", unsigned(eid), "RC", rc);
            return;
        }

        auto compClassification = compEntry.comp_classification;
        auto compIdentifier = compEntry.comp_identifier;
        componentInfo.emplace(
            std::make_pair(compClassification, compIdentifier),
            compEntry.comp_classification_index);
        compParamPtr += sizeof(pldm_component_parameter_entry) +
                        activeCompVerStr.length + pendingCompVerStr.length;
        compParamTableLen -= sizeof(pldm_component_parameter_entry) +
                             activeCompVerStr.length + pendingCompVerStr.length;
    }
    info("EID: {EID} Components:", "EID", unsigned(eid));
    for (const auto& [comp_key, comp_class_index] : componentInfo)
    {
        const auto& [comp_class, comp_identifier] = comp_key;
        info(
            "Classification: {CLASS} Identifier: {IDENT} Classification index: {CLASS_INDEX}",
            "CLASS", unsigned(comp_class), "IDENT", unsigned(comp_identifier),
            "CLASS_INDEX", unsigned(comp_class_index));
    }
    componentInfoMap.emplace(eid, std::move(componentInfo));
}

} // namespace fw_update

} // namespace pldm
