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

#include <chrono>
#include <utility>
#include "IETFHardware.h"
#include "utils/log.h"
#include "utils/time.h"

using namespace std::literals;

namespace {

static const std::string ietfHardwareStatePrefix = "/ietf-hardware:hardware";

/** @brief Constructs a full XPath for a specific component */
std::string xpathForComponent(const std::string& componentName)
{
    return ietfHardwareStatePrefix + "/component[name='" + componentName + "']/";
}

/** @brief Prefix all properties from values DataTree with a component name (calculated from @p componentName) and push them into the DataTree */
void addComponent(velia::ietf_hardware::DataTree& res, const std::string& componentName, const std::optional<std::string>& parent, const velia::ietf_hardware::DataTree& values)
{
    auto componentPrefix = xpathForComponent(componentName);

    if (parent) {
        res[componentPrefix + "parent"] = *parent;
    }
    for (const auto& [k, v] : values) {
        res[componentPrefix + k] = v;
    }
}

/** @brief Write a sensor-data @p value for a component @p componentName and push it into the @p res DataTree */
void addSensorValue(velia::ietf_hardware::DataTree& res, const std::string& componentName, const std::string& value)
{
    const auto componentPrefix = xpathForComponent(componentName);
    res[componentPrefix + "sensor-data/value"] = value;
}
}

namespace velia::ietf_hardware {

IETFHardware::IETFHardware() = default;

IETFHardware::~IETFHardware() = default;

std::map<std::string, std::string> IETFHardware::process()
{
    std::map<std::string, std::string> res;

    for (auto& dataReader : m_callbacks) {
        res.merge(dataReader());
    }

    res[ietfHardwareStatePrefix + "/last-change"] = velia::utils::yangTimeFormat(std::chrono::system_clock::now());
    return res;
}

void IETFHardware::registerDataReader(const DataReader& callable)
{
    m_callbacks.push_back(callable);
}

/** @brief A namespace containing predefined data readers for IETFHardware class.
 * @see IETFHardware for more information
 */
namespace data_reader {

DataReader::DataReader(std::string componentName, std::optional<std::string> parent)
    : m_componentName(std::move(componentName))
    , m_parent(std::move(parent))
{
}

/** @brief Constructs a component without any sensor-data and provide only the static data @p dataTree passed via constructor.
 * @param componentName the name of the component in the resulting tree
 * @param parent The component in YANG model has a link to parent. Specify who is the parent.
 * @param dataTree static data to insert into the resulting tree. The dataTree keys should only contain the YANG node name, not full XPath. The full XPath is constructed from @componentName and the map key.
 */
StaticData::StaticData(std::string componentName, std::optional<std::string> parent, DataTree dataTree)
    : DataReader(std::move(componentName), std::move(parent))
{
    addComponent(m_staticData,
                 m_componentName,
                 m_parent,
                 dataTree);
}

DataTree StaticData::operator()() const { return m_staticData; }

Fans::Fans(std::string componentName, std::optional<std::string> parent, std::shared_ptr<sysfs::HWMon> hwmon, unsigned fanChannelsCount)
    : DataReader(std::move(componentName), std::move(parent))
    , m_hwmon(std::move(hwmon))
    , m_fanChannelsCount(fanChannelsCount)
{
    // fans
    addComponent(m_staticData,
                 m_componentName,
                 m_parent,
                 DataTree {
                     {"class", "iana-hardware:module"}, // FIXME: Read (or pass via constructor) additional properties (mfg, model, ...). They should be in the fans' tray EEPROM.
                 });

    for (unsigned i = 1; i <= m_fanChannelsCount; i++) {
        // fans -> fan_i
        addComponent(m_staticData,
                     m_componentName + ":fan" + std::to_string(i),
                     m_componentName,
                     DataTree {
                         {"class", "iana-hardware:fan"},
                     });

        // fans -> fan_i -> sensor-data
        addComponent(m_staticData,
                     m_componentName + ":fan" + std::to_string(i) + ":rpm",
                     m_componentName + ":fan" + std::to_string(i),
                     DataTree {
                         {"class", "iana-hardware:sensor"},
                         {"sensor-data/value-type", "rpm"},
                         {"sensor-data/value-scale", "units"},
                         {"sensor-data/value-precision", "0"},
                         {"sensor-data/oper-status", "ok"},
                     });
    }
}

DataTree Fans::operator()() const
{
    DataTree res(m_staticData);

    for (unsigned i = 1; i <= m_fanChannelsCount; i++) {
        const auto sensorComponentName = m_componentName + ":fan" + std::to_string(i) + ":rpm";
        const auto attribute = "fan"s + std::to_string(i) + "_input";

        addSensorValue(res, sensorComponentName, std::to_string(m_hwmon->attribute(attribute)));
    }

    return res;
}

std::string getSysfsFilename(const SensorType type, int sysfsChannelNr)
{
    switch (type) {
        case SensorType::Temperature:
            return "temp"s + std::to_string(sysfsChannelNr) + "_input";
        case SensorType::Current:
            return "curr"s + std::to_string(sysfsChannelNr) + "_input";
        case SensorType::Power:
            return "power"s + std::to_string(sysfsChannelNr) + "_input";
        case SensorType::VoltageAC:
        case SensorType::VoltageDC:
            return "in"s + std::to_string(sysfsChannelNr) + "_input";
    }

    __builtin_unreachable();
}

template <SensorType TYPE> const DataTree sysfsStaticData;
template <> const DataTree sysfsStaticData<SensorType::Temperature> = {
    {"class", "iana-hardware:sensor"},
    {"sensor-data/value-type", "celsius"},
    {"sensor-data/value-scale", "milli"},
    {"sensor-data/value-precision", "0"},
    {"sensor-data/oper-status", "ok"},
};
template <> const DataTree sysfsStaticData<SensorType::Current> = {
    {"class", "iana-hardware:sensor"},
    {"sensor-data/value-type", "amperes"},
    {"sensor-data/value-scale", "milli"},
    {"sensor-data/value-precision", "0"},
    {"sensor-data/oper-status", "ok"},
};
template <> const DataTree sysfsStaticData<SensorType::Power> = {
    {"class", "iana-hardware:sensor"},
    {"sensor-data/value-type", "watts"},
    {"sensor-data/value-scale", "micro"},
    {"sensor-data/value-precision", "0"},
    {"sensor-data/oper-status", "ok"},
};
template <> const DataTree sysfsStaticData<SensorType::VoltageAC> = {
    {"class", "iana-hardware:sensor"},
    {"sensor-data/value-type", "volts-AC"},
    {"sensor-data/value-scale", "milli"},
    {"sensor-data/value-precision", "0"},
    {"sensor-data/oper-status", "ok"}
};
template <> const DataTree sysfsStaticData<SensorType::VoltageDC> = {
    {"class", "iana-hardware:sensor"},
    {"sensor-data/value-type", "volts-DC"},
    {"sensor-data/value-scale", "milli"},
    {"sensor-data/value-precision", "0"},
    {"sensor-data/oper-status", "ok"}
};

template <SensorType TYPE>
SysfsValue<TYPE>::SysfsValue(std::string componentName, std::optional<std::string> parent, std::shared_ptr<sysfs::HWMon> hwmon, int sysfsChannelNr)
    : DataReader(std::move(componentName), std::move(parent))
    , m_hwmon(std::move(hwmon))
    , m_sysfsFile(getSysfsFilename(TYPE, sysfsChannelNr))
{
    addComponent(m_staticData,
                 m_componentName,
                 m_parent,
                 sysfsStaticData<TYPE>);
}

template <SensorType TYPE>
DataTree SysfsValue<TYPE>::operator()() const
{
    DataTree res(m_staticData);

    int64_t sensorValue = m_hwmon->attribute(m_sysfsFile);
    addSensorValue(res, m_componentName, std::to_string(sensorValue));

    return res;
}

template struct SysfsValue<SensorType::Current>;
template struct SysfsValue<SensorType::Power>;
template struct SysfsValue<SensorType::Temperature>;
template struct SysfsValue<SensorType::VoltageAC>;
template struct SysfsValue<SensorType::VoltageDC>;

EMMC::EMMC(std::string componentName, std::optional<std::string> parent, std::shared_ptr<sysfs::EMMC> emmc)
    : DataReader(std::move(componentName), std::move(parent))
    , m_emmc(std::move(emmc))
{
    auto emmcAttrs = m_emmc->attributes();

    // date is specified in MM/YYYY format (source: kernel core/mmc.c) and mfg-date is unfortunately of type yang:date-and-time
    std::string mfgDate = emmcAttrs.at("date");
    // FIXME: replace this with C++20's <chrono> calendar features once Buildroot gets GCC 11+
    struct tm date;
    memset(&date, 0, sizeof(date));
    date.tm_mday = 1;
    date.tm_mon = std::stoul(mfgDate.substr(0, 2)) - 1;
    date.tm_year = std::stoi(mfgDate.substr(3, 4)) - 1900;
    date.tm_isdst = -1;
    mfgDate = velia::utils::yangTimeFormat(std::chrono::system_clock::from_time_t(timegm(&date)));

    addComponent(m_staticData,
                 m_componentName,
                 m_parent,
                 DataTree {
                     {"class", "iana-hardware:module"},
                     {"mfg-date", mfgDate},
                     {"serial-num", emmcAttrs.at("serial")},
                     {"model-name", emmcAttrs.at("name")},
                 });

    addComponent(m_staticData,
                 m_componentName + ":lifetime",
                 m_componentName,
                 DataTree {
                     {"class", "iana-hardware:sensor"},
                     {"sensor-data/value-type", "other"},
                     {"sensor-data/value-scale", "units"},
                     {"sensor-data/value-precision", "0"},
                     {"sensor-data/oper-status", "ok"},
                     {"sensor-data/units-display", "percent"s},
                 });
}

DataTree EMMC::operator()() const
{
    DataTree res(m_staticData);

    auto emmcAttrs = m_emmc->attributes();
    addSensorValue(res, m_componentName + ":lifetime", emmcAttrs.at("life_time"));

    return res;
}
}
}
