#include "software_manager.hpp"

#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/async.hpp>
#include <sdbusplus/async/context.hpp>
#include <sdbusplus/bus.hpp>
#include <xyz/openbmc_project/Association/Definitions/server.hpp>
#include <xyz/openbmc_project/ObjectMapper/client.hpp>
#include <xyz/openbmc_project/Software/Version/client.hpp>
#include <xyz/openbmc_project/State/Host/client.hpp>

#include <cstdint>

PHOSPHOR_LOG2_USING;

using namespace phosphor::software::manager;

SoftwareManager::SoftwareManager(sdbusplus::async::context& ctx,
                                 const std::string& serviceNameSuffix) :
    ctx(ctx), serviceNameSuffix(serviceNameSuffix),
    manager(ctx, sdbusplus::client::xyz::openbmc_project::software::Version<>::
                     namespace_path)
{
    const std::string serviceNameFull =
        "xyz.openbmc_project.Software." + serviceNameSuffix;

    debug("requesting dbus name {BUSNAME}", "BUSNAME", serviceNameFull);

    ctx.request_name(serviceNameFull.c_str());

    debug("Initialized SoftwareManager");
}

// NOLINTBEGIN(readability-static-accessed-through-instance)
sdbusplus::async::task<> SoftwareManager::initDevices(
    const std::vector<std::string>& configurationInterfaces)
// NOLINTEND(readability-static-accessed-through-instance)
{
    auto client = sdbusplus::client::xyz::openbmc_project::ObjectMapper<>(ctx)
                      .service("xyz.openbmc_project.ObjectMapper")
                      .path("/xyz/openbmc_project/object_mapper");

    auto res = co_await client.get_sub_tree("/xyz/openbmc_project/inventory", 0,
                                            configurationInterfaces);

    for (auto& iface : configurationInterfaces)
    {
        debug("[config] looking for dbus interface {INTF}", "INTF", iface);
    }

    for (auto& [path, v] : res)
    {
        for (auto& [service, interfaceNames] : v)
        {
            std::string interfaceFound;

            for (std::string& interfaceName : interfaceNames)
            {
                for (auto& iface : configurationInterfaces)
                {
                    if (interfaceName == iface)
                    {
                        interfaceFound = interfaceName;
                    }
                }
            }

            if (interfaceFound.empty())
            {
                continue;
            }

            debug(
                "[config] found configuration interface at {SERVICE}, {OBJPATH}",
                "SERVICE", service, "OBJPATH", path);

            auto client =
                sdbusplus::async::proxy().service(service).path(path).interface(
                    "org.freedesktop.DBus.Properties");

            uint64_t vendorIANA = 0;
            std::string compatible{};
            std::string emConfigType{};
            std::string emConfigName{};

            const std::string ifaceFwInfoDef = interfaceFound + ".FirmwareInfo";

            try
            {
                {
                    auto propVendorIANA =
                        co_await client.call<std::variant<uint64_t>>(
                            ctx, "Get", ifaceFwInfoDef, "VendorIANA");

                    vendorIANA = std::get<uint64_t>(propVendorIANA);
                }
                {
                    auto propCompatible =
                        co_await client.call<std::variant<std::string>>(
                            ctx, "Get", ifaceFwInfoDef, "CompatibleHardware");

                    compatible = std::get<std::string>(propCompatible);
                }
                {
                    auto propEMConfigType =
                        co_await client.call<std::variant<std::string>>(
                            ctx, "Get", interfaceFound, "Type");

                    emConfigType = std::get<std::string>(propEMConfigType);
                }
                {
                    auto propEMConfigName =
                        co_await client.call<std::variant<std::string>>(
                            ctx, "Get", interfaceFound, "Name");

                    emConfigName = std::get<std::string>(propEMConfigName);
                }
            }
            catch (std::exception& e)
            {
                error(e.what());
                continue;
            }

            SoftwareConfig config(path, vendorIANA, compatible, emConfigType,
                                  emConfigName);

            co_await initDevice(service, path, config);
        }
    }

    debug("[config] done with initial configuration");
}
