#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::message::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("Names"))
    {
        return;
    }
    auto names = std::get<pldm::utils::Interfaces>(properties.at("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,
                                  "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
