#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;
    for (auto& [_, updateManager] : updateManagers)
    {
        response =
            updateManager->handleRequest(eid, command, request, reqMsgLen);
        auto relayedResponseMsg =
            std::start_lifetime_as<pldm_msg>(response.data());
        if (relayedResponseMsg->payload[0] != PLDM_FWUP_COMMAND_NOT_EXPECTED)
        {
            return response;
        }
    }
    return UpdateManager::handleRequest(eid, command, request, reqMsgLen);
}

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
