#include "utils.hpp"

#include <phosphor-logging/log.hpp>
#include <sdbusplus/exception.hpp>
#include <sdeventplus/event.hpp>

#include <filesystem>
#include <fstream>

namespace fs = std::filesystem;

using namespace phosphor::logging;

namespace phosphor
{
namespace led
{

static constexpr auto confFileName = "led-group-config.json";
static constexpr auto confOverridePath = "/etc/phosphor-led-manager";
static constexpr auto confBasePath = "/usr/share/phosphor-led-manager";
static constexpr auto confCompatibleInterface =
    "xyz.openbmc_project.Configuration.IBMCompatibleSystem";
static constexpr auto confCompatibleProperty = "Names";

class JsonConfig
{
  public:
    /**
     * @brief Constructor
     *
     * Looks for the JSON config file.  If it can't find one, then it
     * will watch entity-manager for the IBMCompatibleSystem interface
     * to show up.
     *
     * @param[in] bus       - The D-Bus object
     * @param[in] event     - sd event handler
     */
    JsonConfig(sdbusplus::bus::bus& bus, sdeventplus::Event& event) :
        event(event)
    {
        match = std::make_unique<sdbusplus::server::match::match>(
            bus,
            sdbusplus::bus::match::rules::interfacesAdded() +
                sdbusplus::bus::match::rules::sender(
                    "xyz.openbmc_project.EntityManager"),
            std::bind(&JsonConfig::ifacesAddedCallback, this,
                      std::placeholders::_1));
        getFilePath();

        if (!confFile.empty())
        {
            match.reset();
        }
    }

    /**
     * @brief Get the configuration file
     *
     * @return filesystem path
     */
    inline const fs::path& getConfFile() const
    {
        return confFile;
    }

  private:
    /** @brief Check the file path exists
     *
     *  @param[in]  names   -  Vector of the confCompatible Property
     *
     *  @return             -  True or False
     */
    bool filePathExists(const std::vector<std::string>& names)
    {
        auto it =
            std::find_if(names.begin(), names.end(), [this](const auto& name) {
                auto tempConfFile =
                    fs::path{confBasePath} / name / confFileName;
                if (fs::exists(tempConfFile))
                {
                    confFile = tempConfFile;
                    return true;
                }
                return false;
            });
        return it == names.end() ? false : true;
    }

    /**
     * @brief The interfacesAdded callback function that looks for
     *        the IBMCompatibleSystem interface.  If it finds it,
     *        it uses the Names property in the interface to find
     *        the JSON config file to use.
     *
     * @param[in] msg - The D-Bus message contents
     */
    void ifacesAddedCallback(sdbusplus::message::message& msg)
    {
        sdbusplus::message::object_path path;
        std::map<std::string,
                 std::map<std::string, std::variant<std::vector<std::string>>>>
            interfaces;

        msg.read(path, interfaces);

        if (!interfaces.contains(confCompatibleInterface))
        {
            return;
        }

        // Get the "Name" property value of the
        // "xyz.openbmc_project.Configuration.IBMCompatibleSystem" interface
        const auto& properties = interfaces.at(confCompatibleInterface);

        if (!properties.contains(confCompatibleProperty))
        {
            return;
        }
        auto names = std::get<std::vector<std::string>>(
            properties.at(confCompatibleProperty));

        if (filePathExists(names))
        {
            match.reset();

            // This results in event.loop() exiting in getSystemLedMap
            event.exit(0);
        }
    }

    /**
     * Get the json configuration file. The first location found to contain the
     * json config file from the following locations in order.
     * confOverridePath: /etc/phosphor-led-manager/led-group-config.json
     * confBasePath: /usr/shard/phosphor-led-manager/led-group-config.json
     * the name property of the confCompatibleInterface:
     * /usr/shard/phosphor-led-manager/${Name}/led-group-config.json
     *
     * @brief Get the configuration file to be used
     *
     * @return
     */
    void getFilePath()
    {
        // Check override location
        confFile = fs::path{confOverridePath} / confFileName;
        if (fs::exists(confFile))
        {
            return;
        }

        // If the default file is there, use it
        confFile = fs::path{confBasePath} / confFileName;
        if (fs::exists(confFile))
        {
            return;
        }
        confFile.clear();

        try
        {
            // Get all objects implementing the compatible interface
            auto objects =
                dBusHandler.getSubTreePaths("/", confCompatibleInterface);
            for (const auto& path : objects)
            {
                try
                {
                    // Retrieve json config compatible relative path locations
                    auto value = dBusHandler.getProperty(
                        path, confCompatibleInterface, confCompatibleProperty);

                    auto confCompatValues =
                        std::get<std::vector<std::string>>(value);

                    // Look for a config file at each name relative to the base
                    // path and use the first one found
                    if (filePathExists(confCompatValues))
                    {
                        // Use the first config file found at a listed location
                        break;
                    }
                    confFile.clear();
                }
                catch (const sdbusplus::exception::exception& e)
                {
                    // Property unavailable on object.
                    log<level::ERR>(
                        "Failed to get Names property",
                        entry("ERROR=%s", e.what()),
                        entry("INTERFACE=%s", confCompatibleInterface),
                        entry("PATH=%s", path.c_str()));

                    confFile.clear();
                }
            }
        }
        catch (const sdbusplus::exception::exception& e)
        {
            log<level::ERR>("Failed to call the SubTreePaths method",
                            entry("ERROR=%s", e.what()),
                            entry("INTERFACE=%s", confCompatibleInterface));
        }
        return;
    }

  private:
    /**
     * @brief sd event handler.
     */
    sdeventplus::Event& event;

    /**
     * @brief The JSON config file
     */
    fs::path confFile;

    /**
     * @brief The interfacesAdded match that is used to wait
     *        for the IBMCompatibleSystem interface to show up.
     */
    std::unique_ptr<sdbusplus::server::match::match> match;

    /** DBusHandler class handles the D-Bus operations */
    utils::DBusHandler dBusHandler;
};
} // namespace led
} // namespace phosphor
