#include "entity_manager_interface.hpp"

#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/async.hpp>
#include <sdbusplus/message/native_types.hpp>
#include <xyz/openbmc_project/Inventory/Item/client.hpp>

#include <algorithm>
#include <flat_map>
#include <utility>

namespace entity_manager
{

PHOSPHOR_LOG2_USING;

namespace rules_intf = sdbusplus::bus::match::rules;

using BasicVariantType =
    std::variant<std::vector<std::string>, std::vector<uint8_t>, std::string,
                 int64_t, uint64_t, double, int32_t, uint32_t, int16_t,
                 uint16_t, uint8_t, bool>;
using BaseConfigMap = std::flat_map<std::string, BasicVariantType>;
using ConfigData = std::flat_map<std::string, BaseConfigMap>;
using ManagedObjectType =
    std::flat_map<sdbusplus::message::object_path, ConfigData>;

EntityManagerInterface::EntityManagerInterface(
    sdbusplus::async::context& ctx, const interface_list_t& interfaceNames,
    Callback_t addedCallback, Callback_t removedCallback) :
    ctx(ctx), interfaceNames(interfaceNames),
    addedCallback(std::move(addedCallback)),
    removedCallback(std::move(removedCallback))
{
    ctx.spawn(handleInventoryAdded());
    ctx.spawn(handleInventoryRemoved());
}

auto EntityManagerInterface::handleInventoryGet() -> sdbusplus::async::task<>
{
    if (!addedCallback)
    {
        error("addedCallback is not set");
        co_return;
    }

    using InventoryIntf =
        sdbusplus::client::xyz::openbmc_project::inventory::Item<>;

    constexpr auto entityManager =
        sdbusplus::async::proxy()
            .service(serviceName)
            .path(InventoryIntf::namespace_path)
            .interface("org.freedesktop.DBus.ObjectManager");

    for (const auto& [objectPath, interfaceConfig] :
         co_await entityManager.call<ManagedObjectType>(ctx,
                                                        "GetManagedObjects"))
    {
        for (const auto& interfaceName : interfaceNames)
        {
            if (interfaceConfig.contains(interfaceName))
            {
                co_await addedCallback(objectPath, interfaceName);
            }
        }
    }

    co_return;
}

auto EntityManagerInterface::handleInventoryAdded() -> sdbusplus::async::task<>
{
    if (!addedCallback)
    {
        error("addedCallback is not set");
        co_return;
    }

    auto addedMatch = sdbusplus::async::match(
        ctx, rules_intf::interfacesAdded() + rules_intf::sender(serviceName));

    while (!ctx.stop_requested())
    {
        auto result = co_await addedMatch
                          .next<sdbusplus::message::object_path, ConfigData>();
        auto& [objectPath, inventoryData] = result;

        for (const auto& interfaceName : interfaceNames)
        {
            if (inventoryData.contains(interfaceName))
            {
                co_await addedCallback(objectPath, interfaceName);
            }
        }
    }

    co_return;
}

auto EntityManagerInterface::handleInventoryRemoved()
    -> sdbusplus::async::task<>
{
    if (!removedCallback)
    {
        error("removedCallback is not set");
        co_return;
    }

    auto removedMatch = sdbusplus::async::match(
        ctx, rules_intf::interfacesRemoved() + rules_intf::sender(serviceName));

    while (!ctx.stop_requested())
    {
        auto result =
            co_await removedMatch
                .next<sdbusplus::message::object_path, interface_list_t>();
        auto& [objectPath, interfaces] = result;

        for (const auto& interfaceName : interfaceNames)
        {
            if (std::ranges::find(interfaces, interfaceName) !=
                interfaces.end())
            {
                co_await removedCallback(objectPath, interfaceName);
            }
        }
    }

    co_return;
}

} // namespace entity_manager
