#include "lamptest.hpp"

#include <phosphor-logging/lg2.hpp>

#include <algorithm>

namespace phosphor
{
namespace led
{

using Json = nlohmann::json;
static const fs::path lampTestIndicator =
    "/var/lib/phosphor-led-manager/lamp-test-running";

bool LampTest::processLEDUpdates(const ActionSet& ledsAssert,
                                 const ActionSet& ledsDeAssert)
{
    // If the physical LED status is updated during the lamp test, it should be
    // saved to Queue, and the queue will be processed after the lamp test is
    // stopped.
    if (isLampTestRunning)
    {
        // Physical LEDs will be updated during lamp test
        for (const auto& it : ledsDeAssert)
        {
            std::string path = std::string(phyLedPath) + it.name;
            auto iter = std::find_if(
                forceUpdateLEDs.begin(), forceUpdateLEDs.end(),
                [&path](const auto& name) { return name == path; });

            if (iter != forceUpdateLEDs.end())
            {
                phosphor::led::Manager::drivePhysicalLED(
                    path, Layout::Action::Off, it.dutyOn, it.period);
            }
        }

        for (const auto& it : ledsAssert)
        {
            std::string path = std::string(phyLedPath) + it.name;
            auto iter = std::find_if(
                forceUpdateLEDs.begin(), forceUpdateLEDs.end(),
                [&path](const auto& name) { return name == path; });

            if (iter != forceUpdateLEDs.end())
            {
                phosphor::led::Manager::drivePhysicalLED(path, it.action,
                                                         it.dutyOn, it.period);
            }
        }

        updatedLEDsDuringLampTest.emplace(ledsAssert, ledsDeAssert);
        return true;
    }
    return false;
}

void LampTest::stop()
{
    if (!isLampTestRunning)
    {
        return;
    }

    timer.setEnabled(false);

    // Stop host lamp test
    doHostLampTest(false);

    // Set all the Physical action to Off
    for (const auto& path : physicalLEDPaths)
    {
        auto iter =
            std::find_if(skipUpdateLEDs.begin(), skipUpdateLEDs.end(),
                         [&path](const auto& skip) { return skip == path; });

        if (iter != skipUpdateLEDs.end())
        {
            // Skip update physical path
            continue;
        }

        phosphor::led::Manager::drivePhysicalLED(path, Layout::Action::Off, 0,
                                                 0);
    }

    if (std::filesystem::exists(lampTestIndicator))
    {
        if (!std::filesystem::remove(lampTestIndicator))
        {
            lg2::error(
                "Error removing lamp test on indicator file after lamp test execution.");
        }
    }

    isLampTestRunning = false;
    restorePhysicalLedStates();
}

Layout::Action LampTest::getActionFromString(const std::string& str)
{
    Layout::Action action = Layout::Action::Off;

    if (str == "xyz.openbmc_project.Led.Physical.Action.On")
    {
        action = Layout::Action::On;
    }
    else if (str == "xyz.openbmc_project.Led.Physical.Action.Blink")
    {
        action = Layout::Action::Blink;
    }

    return action;
}

void LampTest::storePhysicalLEDsStates()
{
    physicalLEDStatesPriorToLampTest.clear();

    for (const auto& path : physicalLEDPaths)
    {
        auto iter = std::find_if(
            skipUpdateLEDs.begin(), skipUpdateLEDs.end(),
            [&path](const auto& skipLed) { return skipLed == path; });

        if (iter != skipUpdateLEDs.end())
        {
            // Physical LEDs will be skipped
            continue;
        }

        // Reverse intercept path, Get the name of each member of physical led
        // e.g: path = /xyz/openbmc_project/led/physical/front_fan
        //      name = front_fan
        sdbusplus::message::object_path object_path(path);
        auto name = object_path.filename();
        if (name.empty())
        {
            lg2::error(
                "Failed to get the name of member of physical LED path, PATH = {PATH}, NAME = {NAME}",
                "PATH", path, "NAME", name);
            continue;
        }

        std::string state{};
        uint16_t period{};
        uint8_t dutyOn{};
        try
        {
            auto properties =
                phosphor::led::utils::DBusHandler::getAllProperties(path,
                                                                    phyLedIntf);

            state = std::get<std::string>(properties["State"]);
            period = std::get<uint16_t>(properties["Period"]);
            dutyOn = std::get<uint8_t>(properties["DutyOn"]);
        }
        catch (const sdbusplus::exception_t& e)
        {
            lg2::error(
                "Failed to get All properties, ERROR = {ERROR}, PATH = {PATH}",
                "ERROR", e, "PATH", path);
            continue;
        }

        phosphor::led::Layout::Action action = getActionFromString(state);
        if (action != phosphor::led::Layout::Action::Off)
        {
            phosphor::led::Layout::LedAction ledAction{
                name, action, dutyOn, period,
                phosphor::led::Layout::Action::On};
            physicalLEDStatesPriorToLampTest.emplace(ledAction);
        }
    }
}

void LampTest::start()
{
    if (isLampTestRunning)
    {
        // reset the timer and then return
        timer.restart(std::chrono::seconds(LAMP_TEST_TIMEOUT_IN_SECS));

        // Notify host to reset the timer
        doHostLampTest(true);

        return;
    }

    // Get paths of all the Physical LED objects
    try
    {
        physicalLEDPaths = phosphor::led::utils::DBusHandler::getSubTreePaths(
            phyLedPath, phyLedIntf);
    }
    catch (const sdbusplus::exception_t& e)
    {
        lg2::error(
            "Failed to call the SubTreePaths method: {ERROR}, ledPath: {PATH}, ledInterface: {INTERFACE}",
            "ERROR", e, "PATH", phyLedPath, "INTERFACE", phyLedIntf);
        return;
    }

    // Get physical LEDs states before lamp test
    storePhysicalLEDsStates();

    // restart lamp test, it contains initiate or reset the timer.
    timer.restart(std::chrono::seconds(LAMP_TEST_TIMEOUT_IN_SECS));
    isLampTestRunning = true;

    // Notify host to start the lamp test
    doHostLampTest(true);

    // Create a file to maintain the state across reboots that Lamp test is on.
    // This is required as there was a scenario where it has been found that
    // LEDs remains in "on" state if lamp test is triggered and reboot takes
    // place.
    const auto ledDirectory = lampTestIndicator.parent_path();

    if (!fs::exists(ledDirectory))
    {
        fs::create_directories(ledDirectory);
    }

    std::ofstream ofs(lampTestIndicator.c_str());

    // Set all the Physical action to On for lamp test
    for (const auto& path : physicalLEDPaths)
    {
        auto iter =
            std::find_if(skipUpdateLEDs.begin(), skipUpdateLEDs.end(),
                         [&path](const auto& skip) { return skip == path; });

        if (iter != skipUpdateLEDs.end())
        {
            // Skip update physical path
            continue;
        }

        phosphor::led::Manager::drivePhysicalLED(path, Layout::Action::On, 0,
                                                 0);
    }
}

void LampTest::timeOutHandler()
{
    // set the Asserted property of lamp test to false
    if (groupObj == nullptr)
    {
        lg2::error("the Group object is nullptr");
        throw std::runtime_error("the Group object is nullptr");
    }

    groupObj->asserted(false);
}

bool LampTest::requestHandler(Group* group, bool value)
{
    if (groupObj == nullptr)
    {
        groupObj = group;
    }

    if (value)
    {
        start();

        // Return true in both cases (F -> T && T -> T)
        return true;
    }
    else
    {
        if (timer.hasExpired())
        {
            stop();

            // Return true as the request to stop the lamptest is handled
            // successfully.
            return true;
        }
        else if (timer.isEnabled())
        {
            lg2::info(
                "Lamp test is still running. Cannot force stop the lamp test. Asserted is set back to true.");

            // Return false as the request to stop lamptest is not handled as
            // the lamptest is still running.
            return false;
        }
        return false;
    }
}

void LampTest::restorePhysicalLedStates()
{
    // restore physical LEDs states before lamp test
    ActionSet ledsDeAssert{};
    manager.driveLEDs(physicalLEDStatesPriorToLampTest, ledsDeAssert);
    physicalLEDStatesPriorToLampTest.clear();

    // restore physical LEDs states during lamp test
    while (!updatedLEDsDuringLampTest.empty())
    {
        auto& [ledsAssert, ledsDeAssert] = updatedLEDsDuringLampTest.front();
        manager.driveLEDs(ledsAssert, ledsDeAssert);
        updatedLEDsDuringLampTest.pop();
    }
}

void LampTest::doHostLampTest(bool value)
{
    try
    {
        PropertyValue assertedValue{value};
        phosphor::led::utils::DBusHandler::setProperty(
            HOST_LAMP_TEST_OBJECT, "xyz.openbmc_project.Led.Group", "Asserted",
            assertedValue);
    }
    catch (const sdbusplus::exception_t& e)
    {
        lg2::error(
            "Failed to set Asserted property, ERROR = {ERROR}, PATH = {PATH}",
            "ERROR", e, "PATH", std::string(HOST_LAMP_TEST_OBJECT));
    }
}

void LampTest::getPhysicalLEDNamesFromJson(const fs::path& path)
{
    if (!fs::exists(path) || fs::is_empty(path))
    {
        lg2::info("The file does not exist or is empty, FILE_PATH = {PATH}",
                  "PATH", path);
        return;
    }

    try
    {
        std::ifstream jsonFile(path);
        auto json = Json::parse(jsonFile);

        // define the default JSON as empty
        const std::vector<std::string> empty{};
        auto forceLEDs = json.value("forceLEDs", empty);
        std::ranges::transform(forceLEDs, std::back_inserter(forceUpdateLEDs),
                               [](const auto& i) { return phyLedPath + i; });

        auto skipLEDs = json.value("skipLEDs", empty);
        std::ranges::transform(skipLEDs, std::back_inserter(skipUpdateLEDs),
                               [](const auto& i) { return phyLedPath + i; });
    }
    catch (const std::exception& e)
    {
        lg2::error(
            "Failed to parse config file, ERROR = {ERROR}, FILE_PATH = {PATH}",
            "ERROR", e, "PATH", path);
    }
    return;
}

void LampTest::clearLamps()
{
    if (std::filesystem::exists(lampTestIndicator))
    {
        // we need to off all the LEDs.
        std::vector<std::string> physicalLedPaths =
            phosphor::led::utils::DBusHandler::getSubTreePaths(
                phosphor::led::phyLedPath, phosphor::led::phyLedIntf);

        for (const auto& path : physicalLedPaths)
        {
            phosphor::led::Manager::drivePhysicalLED(
                path, phosphor::led::Layout::Action::Off, 0, 0);
        }

        // Also remove the lamp test on indicator file.
        if (!std::filesystem::remove(lampTestIndicator))
        {
            lg2::error(
                "Error removing lamp test on indicator file after lamp test execution.");
        }
    }
}
} // namespace led
} // namespace phosphor
