/*
 * Copyright (C) 2021 CESNET, https://photonics.cesnet.cz/
 *
 * Written by Tomáš Pecka <tomas.pecka@cesnet.cz>
 *
 */

#include "LED.h"

#include <utility>
#include "utils/io.h"
#include "utils/libyang.h"
#include "utils/log.h"
#include "utils/sysrepo.h"

using namespace std::literals;

namespace {

const auto CZECHLIGHT_SYSTEM_MODULE_NAME = "czechlight-system"s;
const auto CZECHLIGHT_SYSTEM_LEDS_MODULE_PREFIX = "/"s + CZECHLIGHT_SYSTEM_MODULE_NAME + ":leds/"s;

const auto UID_LED = "uid:blue"s;
const auto POLL_INTERVAL = 125ms;
}

namespace velia::system {

LED::LED(const std::shared_ptr<::sysrepo::Connection>& srConn, std::filesystem::path sysfsLeds)
    : m_log(spdlog::get("system"))
    , m_srSession(std::make_shared<::sysrepo::Session>(srConn))
    , m_srSubscribe(std::make_shared<::sysrepo::Subscribe>(m_srSession))
    , m_thrRunning(true)
{
    utils::ensureModuleImplemented(m_srSession, CZECHLIGHT_SYSTEM_MODULE_NAME, "2021-01-13");

    for (const auto& entry : std::filesystem::directory_iterator(sysfsLeds)) {
        if (!std::filesystem::is_directory(entry.path())) {
            continue;
        }

        const auto fullPath = sysfsLeds / entry.path();
        uint32_t maxBrightness = velia::utils::readFileInt64(fullPath / "max_brightness");
        m_log->debug("Discovered LED '{}' (max brightness {})", std::string(entry.path().filename()), maxBrightness);
        m_ledsMaxBrightness[fullPath] = maxBrightness;
    }

    m_thr = std::thread(&LED::poll, this);

    const auto uidMaxBrightness = std::to_string(velia::utils::readFileInt64(sysfsLeds / UID_LED / "max_brightness"));
    const auto triggerFile = sysfsLeds / UID_LED / "trigger";
    const auto brightnessFile = sysfsLeds / UID_LED / "brightness";

    m_srSubscribe->rpc_subscribe_tree(
        (CZECHLIGHT_SYSTEM_LEDS_MODULE_PREFIX + "uid").c_str(),
        [this, uidMaxBrightness, triggerFile, brightnessFile](auto session, auto, auto input, auto, auto, auto) {
            std::string val = getValueAsString(getSubtree(input, (CZECHLIGHT_SYSTEM_LEDS_MODULE_PREFIX + "uid/state").c_str()));

            try {
                if (val == "on") {
                    utils::writeFile(triggerFile, "none");
                    utils::writeFile(brightnessFile, uidMaxBrightness);
                } else if (val == "off") {
                    utils::writeFile(triggerFile, "none");
                    utils::writeFile(brightnessFile, "0");
                } else if (val == "blinking") {
                    utils::writeFile(triggerFile, "timer");
                    utils::writeFile(brightnessFile, uidMaxBrightness);
                }
            } catch (const std::invalid_argument& e) {
                m_log->warn("Failed to set state of the UID LED: '{}'", e.what());
                session->set_error("Failed to set state of the UID LED", nullptr);
                return SR_ERR_OPERATION_FAILED;
            }

            return SR_ERR_OK;
        });
}

LED::~LED()
{
    m_thrRunning = false;
    m_thr.join();
}

void LED::poll() const
{
    while (m_thrRunning) {
        std::map<std::string, std::string> data;

        for (const auto& [ledDirectory, maxBrightness] : m_ledsMaxBrightness) {
            const auto deviceName = ledDirectory.filename();

            try {
                /* actually just uint32_t is needed for the next two variables; but there is no harm in reading them as int64_t and downcasting them later (especially when the code for reading int64_t already exists)
                 * See https://github.com/torvalds/linux/commit/af0bfab907a011e146304d20d81dddce4e4d62d0
                 */
                const uint32_t brightness = velia::utils::readFileInt64(ledDirectory / "brightness");
                auto percent = brightness * 100 / maxBrightness;

                data[CZECHLIGHT_SYSTEM_LEDS_MODULE_PREFIX + "led[name='" + std::string(deviceName) + "']/brightness"] = std::to_string(percent);
            } catch (const std::invalid_argument& e) {
                m_log->warn("Failed reading state of the LED '{}': {}", std::string(deviceName), e.what());
            }
        }

        utils::valuesPush(data, {}, m_srSession, SR_DS_OPERATIONAL);

        std::this_thread::sleep_for(POLL_INTERVAL);
    }
}
}
