#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,
    const ConditionPaths& conditionPathPair, const std::string& conditionArg,
    std::function<void()> taskCompletionCallback)
{
    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], conditionPathPair, conditionArg,
        std::move(taskCompletionCallback));
}

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
