#include "config.h"

#include "grouplayout.hpp"
#include "json-config.hpp"
#include "ledlayout.hpp"

#include <nlohmann/json.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/bus.hpp>
#include <sdeventplus/event.hpp>

#include <filesystem>
#include <fstream>
#include <iostream>

namespace fs = std::filesystem;

using Json = nlohmann::json;

// Priority for a particular LED needs to stay SAME across all groups
// phosphor::led::Layout::Action can only be one of `Blink` and `On`
using PriorityMap =
    std::unordered_map<std::string,
                       std::optional<phosphor::led::Layout::Action>>;

/** @brief Parse LED JSON file and output Json object
 *
 *  @param[in] path - path of LED JSON file
 *
 *  @return const Json - Json object
 */
Json readJson(const fs::path& path)
{
    if (!fs::exists(path) || fs::is_empty(path))
    {
        lg2::error("Incorrect File Path or empty file, FILE_PATH = {PATH}",
                   "PATH", path);
        throw std::runtime_error("Incorrect File Path or empty file");
    }

    try
    {
        std::ifstream jsonFile(path);
        return Json::parse(jsonFile);
    }
    catch (const std::exception& e)
    {
        lg2::error(
            "Failed to parse config file, ERROR = {ERROR}, FILE_PATH = {PATH}",
            "ERROR", e, "PATH", path);
        throw std::runtime_error("Failed to parse config file");
    }
}

/** @brief Returns action enum based on string
 *
 *  @param[in] action - action string
 *
 *  @return Action - action enum (On/Blink)
 */
phosphor::led::Layout::Action getAction(const std::string& action)
{
    assert(action == "On" || action == "Blink");

    return action == "Blink" ? phosphor::led::Layout::Action::Blink
                             : phosphor::led::Layout::Action::On;
}

static std::string priorityToString(
    const std::optional<phosphor::led::Layout::Action>& priority)
{
    if (!priority.has_value())
    {
        return "none";
    }
    switch (priority.value())
    {
        case phosphor::led::Layout::Action::Off:
            return "Off";
        case phosphor::led::Layout::Action::On:
            return "On";
        case phosphor::led::Layout::Action::Blink:
            return "Blink";
    }
    return "?";
}

/** @brief Validate the Priority of an LED is same across ALL groups
 *
 *  @param[in] name - led name member of each group
 *  @param[in] priority - member priority of each group
 *  @param[out] priorityMap - std::unordered_map, key:name, value:priority
 *
 *  @return
 */
void validatePriority(
    const std::string& name,
    const std::optional<phosphor::led::Layout::Action>& priority,
    PriorityMap& priorityMap)
{
    auto iter = priorityMap.find(name);
    if (iter == priorityMap.end())
    {
        priorityMap.emplace(name, priority);
        return;
    }

    if (iter->second != priority)
    {
        lg2::error(
            "Priority of LED is not same across all, Name = {NAME}, Old Priority = {OLD_PRIO}, New Priority = {NEW_PRIO}",
            "NAME", name, "OLD_PRIO", priorityToString(iter->second),
            "NEW_PRIO", priorityToString(priority));

        throw std::runtime_error(
            "Priority of at least one LED is not same across groups");
    }
}

static void loadJsonConfigV1GroupMember(const Json& member,
                                        PriorityMap& priorityMap,
                                        phosphor::led::ActionSet& ledActions)
{
    auto name = member.value("Name", "");
    auto action = getAction(member.value("Action", ""));
    uint8_t dutyOn = member.value("DutyOn", 50);
    uint16_t period = member.value("Period", 0);

    const std::string priorityStr = member.value("Priority", "");
    std::optional<phosphor::led::Layout::Action> priority = std::nullopt;

    if (!priorityStr.empty())
    {
        priority = getAction(priorityStr);
    }

    // Same LEDs can be part of multiple groups. However, their
    // priorities across groups need to match.
    validatePriority(name, priority, priorityMap);

    phosphor::led::Layout::LedAction ledAction{name, action, dutyOn, period,
                                               priority};
    ledActions.emplace(ledAction);
}

static void loadJsonConfigV1Group(const Json& entry,
                                  phosphor::led::GroupMap& ledMap,
                                  PriorityMap& priorityMap)
{
    const Json empty{};

    fs::path tmpPath("/xyz/openbmc_project/led/groups");

    const std::string groupName = entry.value("group", "");

    tmpPath /= groupName;
    auto objpath = tmpPath.string();
    auto members = entry.value("members", empty);
    int priority = entry.value("Priority", 0);

    lg2::debug("config for '{GROUP}'", "GROUP", groupName);

    phosphor::led::ActionSet ledActions{};
    phosphor::led::Layout::GroupLayout groupLayout{};
    for (const auto& member : members)
    {
        loadJsonConfigV1GroupMember(member, priorityMap, ledActions);
    }

    // Generated an std::unordered_map of LedGroupNames to std::set of LEDs
    // containing the name and properties.
    groupLayout.actionSet = ledActions;
    groupLayout.priority = priority;

    ledMap.emplace(objpath, groupLayout);
}

/** @brief Load JSON config and return led map (JSON version 1)
 *
 *  @return phosphor::led::GroupMap
 */
const phosphor::led::GroupMap loadJsonConfigV1(const Json& json)
{
    phosphor::led::GroupMap ledMap{};
    PriorityMap priorityMap{};

    // define the default JSON as empty
    const Json empty{};
    auto leds = json.value("leds", empty);

    for (const auto& entry : leds)
    {
        loadJsonConfigV1Group(entry, ledMap, priorityMap);
    }

    return ledMap;
}

/** @brief Load JSON config and return led map
 *
 *  @return phosphor::led::GroupMap
 */
const phosphor::led::GroupMap loadJsonConfig(const fs::path& path)
{
    auto json = readJson(path);

    auto version = json.value("version", 1);
    switch (version)
    {
        case 1:
            return loadJsonConfigV1(json);

        default:
            lg2::error("Unsupported JSON Version: {VERSION}", "VERSION",
                       version);
            throw std::runtime_error("Unsupported version");
    }

    return phosphor::led::GroupMap{};
}

/** @brief Get led map from LED groups JSON config
 *
 *  @param[in] config - Path to the JSON config.
 *  @return phosphor::led::GroupMap
 *
 *  @note if config is an empty string, daemon will interrogate dbus for
 *        compatible strings.
 */
const phosphor::led::GroupMap getSystemLedMap(fs::path config)
{
    if (config.empty())
    {
        config = phosphor::led::getJsonConfig();
    }

    return loadJsonConfig(config);
}
