#include "aggregate_update_manager.hpp"

#include "common/start_lifetime_as.hpp"

#include <memory>

namespace pldm::fw_update
{

Response AggregateUpdateManager::handleRequest(
    mctp_eid_t eid, uint8_t command, const pldm_msg* request, size_t reqMsgLen)
{
    Response response;
    response = UpdateManager::handleRequest(eid, command, request, reqMsgLen);
    auto responseMsg = std::start_lifetime_as<pldm_msg>(response.data());
    if (responseMsg->payload[0] != PLDM_FWUP_COMMAND_NOT_EXPECTED)
    {
        return response;
    }
    for (auto& [_, updateManager] : updateManagers)
    {
        response =
            updateManager->handleRequest(eid, command, request, reqMsgLen);
        auto relayedResponseMsg = new (response.data()) pldm_msg;
        if (relayedResponseMsg->payload[0] != PLDM_FWUP_COMMAND_NOT_EXPECTED)
        {
            return response;
        }
    }
    return response;
}

void AggregateUpdateManager::createUpdateManager(
    const SoftwareIdentifier& softwareIdentifier,
    const Descriptors& descriptors, const ComponentInfo& componentInfo,
    const std::string& updateObjPath, const std::string& generatedId)
{
    auto eid = softwareIdentifier.first;

    descriptorMap[softwareIdentifier] =
        std::make_unique<Descriptors>(descriptors);
    componentInfoMap[softwareIdentifier] =
        std::make_unique<ComponentInfo>(componentInfo);

    updateManagers[softwareIdentifier] = std::make_unique<ItemUpdateManager>(
        eid, event, handler, instanceIdDb, updateObjPath, generatedId,
        *descriptorMap[softwareIdentifier],
        *componentInfoMap[softwareIdentifier]);
}

void AggregateUpdateManager::eraseUpdateManager(
    const SoftwareIdentifier& softwareIdentifier)
{
    updateManagers.erase(softwareIdentifier);
    descriptorMap.erase(softwareIdentifier);
    componentInfoMap.erase(softwareIdentifier);
}

void AggregateUpdateManager::eraseUpdateManagerIf(
    std::function<bool(const SoftwareIdentifier&)>&& predicate)
{
    for (auto it = updateManagers.begin(); it != updateManagers.end();)
    {
        if (predicate(it->first))
        {
            descriptorMap.erase(it->first);
            componentInfoMap.erase(it->first);
            it = updateManagers.erase(it);
        }
        else
        {
            ++it;
        }
    }
}

} // namespace pldm::fw_update
