#include "platform_config.hpp"

#include <phosphor-logging/lg2.hpp>
#include <xyz/openbmc_project/Inventory/Decorator/Compatible/common.hpp>

using InventoryDecoratorCompatible =
    sdbusplus::common::xyz::openbmc_project::inventory::decorator::Compatible;

PHOSPHOR_LOG2_USING;

namespace pldm
{
namespace responder
{

namespace platform_config
{
/** @brief callback function invoked when interfaces get added from
 *      Entity manager
 *
 *  @param[in] msg - Data associated with subscribed signal
 */
void Handler::systemCompatibleCallback(sdbusplus::message_t& msg)
{
    sdbusplus::object_path path;

    pldm::utils::InterfaceMap interfaceMap;

    msg.read(path, interfaceMap);

    if (!interfaceMap.contains(InventoryDecoratorCompatible::interface))
    {
        return;
    }
    // Get the "Name" property value of the
    // "xyz.openbmc_project.Inventory.Decorator.Compatible" interface
    const auto& properties =
        interfaceMap.at(InventoryDecoratorCompatible::interface);

    if (!properties.contains(
            InventoryDecoratorCompatible::property_names::names))
    {
        return;
    }
    auto names = std::get<pldm::utils::Interfaces>(
        properties.at(InventoryDecoratorCompatible::property_names::names));

    if (!names.empty())
    {
        std::optional<std::string> sysType =
            getSysSpecificJsonDir(sysDirPath, names);
        if (sysType.has_value())
        {
            systemType = sysType.value();
        }
        if (sysTypeCallback)
        {
            sysTypeCallback(systemType, true);
        }
    }

    if (!systemType.empty())
    {
        systemCompatibleMatchCallBack.reset();
    }
}

/** @brief Method to get the system type information
 *
 *  @return - the system type information
 */
std::optional<std::filesystem::path> Handler::getPlatformName()
{
    if (!systemType.empty())
    {
        return fs::path{systemType};
    }

    namespace fs = std::filesystem;
    static const std::string entityMangerService =
        "xyz.openbmc_project.EntityManager";

    static constexpr auto searchpath = "/xyz/openbmc_project/";
    int depth = 0;
    std::vector<std::string> systemCompatible = {
        InventoryDecoratorCompatible::interface};

    try
    {
        pldm::utils::GetSubTreeResponse response =
            pldm::utils::DBusHandler().getSubtree(searchpath, depth,
                                                  systemCompatible);
        auto& bus = pldm::utils::DBusHandler::getBus();

        for (const auto& [objectPath, serviceMap] : response)
        {
            try
            {
                auto record = std::find_if(
                    serviceMap.begin(), serviceMap.end(),
                    [](auto map) { return map.first == entityMangerService; });

                if (record != serviceMap.end())
                {
                    auto method = bus.new_method_call(
                        entityMangerService.c_str(), objectPath.c_str(),
                        "org.freedesktop.DBus.Properties", "Get");
                    method.append(
                        InventoryDecoratorCompatible::interface,
                        InventoryDecoratorCompatible::property_names::names);
                    auto propSystemList =
                        bus.call(method, dbusTimeout).unpack<PropertyValue>();
                    auto systemList =
                        std::get<std::vector<std::string>>(propSystemList);

                    if (!systemList.empty())
                    {
                        std::optional<std::string> sysType =
                            getSysSpecificJsonDir(sysDirPath, systemList);
                        // once systemtype received,then resetting a callback
                        systemCompatibleMatchCallBack.reset();
                        if (sysType.has_value())
                        {
                            systemType = sysType.value();
                        }
                        return fs::path{systemType};
                    }
                }
            }
            catch (const std::exception& e)
            {
                error(
                    "Failed to get Names property at '{PATH}' on interface '{INTERFACE}', error - {ERROR}",
                    "PATH", objectPath, "INTERFACE",
                    InventoryDecoratorCompatible::interface, "ERROR", e);
            }
        }
    }
    catch (const std::exception& e)
    {
        error(
            "Failed to make a d-bus call to get platform name, error - {ERROR}",
            "ERROR", e);
    }
    return std::nullopt;
}

std::optional<std::string> Handler::getSysSpecificJsonDir(
    const fs::path& dirPath, const std::vector<std::string>& dirNames)
{
    // The current setup assumes that the BIOS and PDR configurations always
    // come from the same system type. If, in the future, we need to use BIOS
    // and PDR configurations from different system types, we should create
    // separate system type folders for each and update the logic to support
    // this.

    if (dirPath.empty())
    {
        return std::nullopt;
    }

    for (const auto& compatibleName : dirNames)
    {
        for (const auto& dirEntry :
             std::filesystem::directory_iterator{dirPath})
        {
            if (dirEntry.is_directory() &&
                (compatibleName == dirEntry.path().filename()))
            {
                return compatibleName;
            }
        }
    }

    return std::nullopt;
}

void Handler::registerSystemTypeCallback(SystemTypeCallback callback)
{
    sysTypeCallback = callback;
}

} // namespace platform_config

} // namespace responder

} // namespace pldm
