/**
 * Copyright © 2016 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "config.h"

#include "mainloop.hpp"

#include "env.hpp"
#include "fan_pwm.hpp"
#include "fan_speed.hpp"
#include "hwmon.hpp"
#include "hwmonio.hpp"
#include "sensor.hpp"
#include "sensorset.hpp"
#include "sysfs.hpp"
#include "targets.hpp"
#include "thresholds.hpp"
#include "util.hpp"

#include <phosphor-logging/elog-errors.hpp>
#include <xyz/openbmc_project/Sensor/Device/error.hpp>

#include <cassert>
#include <cstdlib>
#include <format>
#include <functional>
#include <future>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <unordered_set>

using namespace phosphor::logging;

// Initialization for Warning Objects
decltype(Thresholds<WarningObject>::setLo) Thresholds<WarningObject>::setLo =
    &WarningObject::warningLow;
decltype(Thresholds<WarningObject>::setHi) Thresholds<WarningObject>::setHi =
    &WarningObject::warningHigh;
decltype(Thresholds<WarningObject>::getLo) Thresholds<WarningObject>::getLo =
    &WarningObject::warningLow;
decltype(Thresholds<WarningObject>::getHi) Thresholds<WarningObject>::getHi =
    &WarningObject::warningHigh;
decltype(Thresholds<WarningObject>::alarmLo)
    Thresholds<WarningObject>::alarmLo = &WarningObject::warningAlarmLow;
decltype(Thresholds<WarningObject>::alarmHi)
    Thresholds<WarningObject>::alarmHi = &WarningObject::warningAlarmHigh;
decltype(Thresholds<WarningObject>::getAlarmLow)
    Thresholds<WarningObject>::getAlarmLow = &WarningObject::warningAlarmLow;
decltype(Thresholds<WarningObject>::getAlarmHigh)
    Thresholds<WarningObject>::getAlarmHigh = &WarningObject::warningAlarmHigh;
decltype(Thresholds<WarningObject>::assertLowSignal)
    Thresholds<WarningObject>::assertLowSignal =
        &WarningObject::warningLowAlarmAsserted;
decltype(Thresholds<WarningObject>::assertHighSignal)
    Thresholds<WarningObject>::assertHighSignal =
        &WarningObject::warningHighAlarmAsserted;
decltype(Thresholds<WarningObject>::deassertLowSignal)
    Thresholds<WarningObject>::deassertLowSignal =
        &WarningObject::warningLowAlarmDeasserted;
decltype(Thresholds<WarningObject>::deassertHighSignal)
    Thresholds<WarningObject>::deassertHighSignal =
        &WarningObject::warningHighAlarmDeasserted;

// Initialization for Critical Objects
decltype(Thresholds<CriticalObject>::setLo) Thresholds<CriticalObject>::setLo =
    &CriticalObject::criticalLow;
decltype(Thresholds<CriticalObject>::setHi) Thresholds<CriticalObject>::setHi =
    &CriticalObject::criticalHigh;
decltype(Thresholds<CriticalObject>::getLo) Thresholds<CriticalObject>::getLo =
    &CriticalObject::criticalLow;
decltype(Thresholds<CriticalObject>::getHi) Thresholds<CriticalObject>::getHi =
    &CriticalObject::criticalHigh;
decltype(Thresholds<CriticalObject>::alarmLo)
    Thresholds<CriticalObject>::alarmLo = &CriticalObject::criticalAlarmLow;
decltype(Thresholds<CriticalObject>::alarmHi)
    Thresholds<CriticalObject>::alarmHi = &CriticalObject::criticalAlarmHigh;
decltype(Thresholds<CriticalObject>::getAlarmLow)
    Thresholds<CriticalObject>::getAlarmLow = &CriticalObject::criticalAlarmLow;
decltype(Thresholds<CriticalObject>::getAlarmHigh)
    Thresholds<CriticalObject>::getAlarmHigh =
        &CriticalObject::criticalAlarmHigh;
decltype(Thresholds<CriticalObject>::assertLowSignal)
    Thresholds<CriticalObject>::assertLowSignal =
        &CriticalObject::criticalLowAlarmAsserted;
decltype(Thresholds<CriticalObject>::assertHighSignal)
    Thresholds<CriticalObject>::assertHighSignal =
        &CriticalObject::criticalHighAlarmAsserted;
decltype(Thresholds<CriticalObject>::deassertLowSignal)
    Thresholds<CriticalObject>::deassertLowSignal =
        &CriticalObject::criticalLowAlarmDeasserted;
decltype(Thresholds<CriticalObject>::deassertHighSignal)
    Thresholds<CriticalObject>::deassertHighSignal =
        &CriticalObject::criticalHighAlarmDeasserted;

void updateSensorInterfaces(InterfaceMap& ifaces, SensorValueType value)
{
    for (auto& iface : ifaces)
    {
        switch (iface.first)
        {
                // clang-format off
            case InterfaceType::VALUE:
            {
                auto& valueIface =
                    std::any_cast<std::shared_ptr<ValueObject>&>(iface.second);
                valueIface->value(value);
            }
            break;
            // clang-format on
            case InterfaceType::WARN:
                checkThresholds<WarningObject>(iface.second, value);
                break;
            case InterfaceType::CRIT:
                checkThresholds<CriticalObject>(iface.second, value);
                break;
            default:
                break;
        }
    }
}

std::string MainLoop::getID(SensorSet::container_t::const_reference sensor)
{
    std::string id;

    /*
     * Check if the value of the MODE_<item><X> env variable for the sensor
     * is set. If it is, then read the from the <item><X>_<mode>
     * file. The name of the DBUS object would be the value of the env
     * variable LABEL_<item><mode value>. If the MODE_<item><X> env variable
     * doesn't exist, then the name of DBUS object is the value of the env
     * variable LABEL_<item><X>.
     *
     * For example, if MODE_temp1 = "label", then code reads the temp1_label
     * file.  If it has a 5 in it, then it will use the following entry to
     * name the object: LABEL_temp5 = "My DBus object name".
     *
     */
    auto mode = env::getEnv("MODE", sensor.first);
    if (!mode.empty())
    {
        id = env::getIndirectID(_hwmonRoot + '/' + _instance + '/', mode,
                                sensor.first);

        if (id.empty())
        {
            return id;
        }
    }

    // Use the ID we looked up above if there was one,
    // otherwise use the standard one.
    id = (id.empty()) ? sensor.first.second : id;

    return id;
}

SensorIdentifiers MainLoop::getIdentifiers(
    SensorSet::container_t::const_reference sensor)
{
    std::string id = getID(sensor);
    std::string label;
    std::string accuracy;
    std::string priority;

    if (!id.empty())
    {
        // Ignore inputs without a label.
        label = env::getEnv("LABEL", sensor.first.first, id);
        accuracy = env::getEnv("ACCURACY", sensor.first.first, id);
        priority = env::getEnv("PRIORITY", sensor.first.first, id);
    }

    return std::make_tuple(std::move(id), std::move(label), std::move(accuracy),
                           std::move(priority));
}

/**
 * Reads the environment parameters of a sensor and creates an object with
 * at least the `Value` interface, otherwise returns without creating the
 * object. If the `Value` interface is successfully created, by reading the
 * sensor's corresponding sysfs file's value, the additional interfaces for
 * the sensor are created and the InterfacesAdded signal is emitted. The
 * object's state data is then returned for sensor state monitoring within
 * the main loop.
 */
std::optional<ObjectStateData> MainLoop::getObject(
    SensorSet::container_t::const_reference sensor)
{
    auto properties = getIdentifiers(sensor);
    if (std::get<sensorID>(properties).empty() ||
        std::get<sensorLabel>(properties).empty())
    {
        return {};
    }

    hwmon::Attributes attrs;
    if (!hwmon::getAttributes(sensor.first.first, attrs))
    {
        return {};
    }

    const auto& [sensorSetKey, sensorAttrs] = sensor;
    const auto& [sensorSysfsType, sensorSysfsNum] = sensorSetKey;

    /* Note: The sensor objects all share the same ioAccess object. */
    auto sensorObj =
        std::make_unique<sensor::Sensor>(sensorSetKey, _ioAccess, _devPath);

    // Get list of return codes for removing sensors on device
    auto devRmRCs = env::getEnv("REMOVERCS");
    // Add sensor removal return codes defined at the device level
    sensorObj->addRemoveRCs(devRmRCs);

    std::string objectPath{_root};
    objectPath.append(1, '/');
    objectPath.append(hwmon::getNamespace(attrs));
    objectPath.append(1, '/');
    objectPath.append(std::get<sensorLabel>(properties));

    ObjectInfo info(&_bus, std::move(objectPath), InterfaceMap());
    RetryIO retryIO(hwmonio::retries, hwmonio::delay);
    if (_rmSensors.find(sensorSetKey) != _rmSensors.end())
    {
        // When adding a sensor that was purposely removed,
        // don't retry on errors when reading its value
        std::get<size_t>(retryIO) = 0;
    }
    auto valueInterface = static_cast<std::shared_ptr<ValueObject>>(nullptr);
    try
    {
        // Add accuracy interface
        auto accuracyStr = std::get<sensorAccuracy>(properties);
        try
        {
            if (!accuracyStr.empty())
            {
                auto accuracy = stod(accuracyStr);
                sensorObj->addAccuracy(info, accuracy);
            }
        }
        catch (const std::invalid_argument&)
        {}

        // Add priority interface
        auto priorityStr = std::get<sensorPriority>(properties);
        try
        {
            if (!priorityStr.empty())
            {
                auto priority = std::stoul(priorityStr);
                sensorObj->addPriority(info, priority);
            }
        }
        catch (const std::invalid_argument&)
        {}

        // Add status interface based on _fault file being present
        sensorObj->addStatus(info);
        valueInterface = sensorObj->addValue(retryIO, info, _timedoutMap);
    }
    catch (const std::system_error& e)
    {
        auto file =
            sysfs::make_sysfs_path(_ioAccess->path(), sensorSysfsType,
                                   sensorSysfsNum, hwmon::entry::cinput);

        // Check sensorAdjusts for sensor removal RCs
        auto& sAdjusts = sensorObj->getAdjusts();
        if (sAdjusts.rmRCs.count(e.code().value()) > 0)
        {
            // Return code found in sensor return code removal list
            if (_rmSensors.find(sensorSetKey) == _rmSensors.end())
            {
                // Trace for sensor not already removed from dbus
                log<level::INFO>("Sensor not added to dbus for read fail",
                                 entry("FILE=%s", file.c_str()),
                                 entry("RC=%d", e.code().value()));
                _rmSensors[std::move(sensorSetKey)] = std::move(sensorAttrs);
            }
            return {};
        }

        using namespace sdbusplus::xyz::openbmc_project::Sensor::Device::Error;
        report<ReadFailure>(
            xyz::openbmc_project::Sensor::Device::ReadFailure::CALLOUT_ERRNO(
                e.code().value()),
            xyz::openbmc_project::Sensor::Device::ReadFailure::
                CALLOUT_DEVICE_PATH(_devPath.c_str()));

        log<level::INFO>(std::format("Failing sysfs file: {} errno: {}", file,
                                     e.code().value())
                             .c_str());
        exit(EXIT_FAILURE);
    }
    auto sensorValue = valueInterface->value();
    int64_t scale = sensorObj->getScale();

    addThreshold<WarningObject>(sensorSysfsType, std::get<sensorID>(properties),
                                sensorValue, info, scale);
    addThreshold<CriticalObject>(sensorSysfsType,
                                 std::get<sensorID>(properties), sensorValue,
                                 info, scale);

    auto target =
        addTarget<hwmon::FanSpeed>(sensorSetKey, _ioAccess, _devPath, info);
    if (target)
    {
        target->enable();
    }
    addTarget<hwmon::FanPwm>(sensorSetKey, _ioAccess, _devPath, info);

    // All the interfaces have been created.  Go ahead
    // and emit InterfacesAdded.
    valueInterface->emit_object_added();

    // Save sensor object specifications
    _sensorObjects[sensorSetKey] = std::move(sensorObj);

    return std::make_pair(std::move(std::get<sensorLabel>(properties)),
                          std::move(info));
}

MainLoop::MainLoop(sdbusplus::bus_t&& bus, const std::string& param,
                   const std::string& path, const std::string& devPath,
                   const char* prefix, const char* root,
                   const std::string& instanceId,
                   const hwmonio::HwmonIOInterface* ioIntf) :
    _bus(std::move(bus)), _manager(_bus, root), _pathParam(param), _hwmonRoot(),
    _instance(), _devPath(devPath), _prefix(prefix), _root(root), _state(),
    _instanceId(instanceId), _ioAccess(ioIntf),
    _event(sdeventplus::Event::get_default()),
    _timer(_event, std::bind(&MainLoop::read, this))
{
    // Strip off any trailing slashes.
    std::string p = path;
    while (!p.empty() && p.back() == '/')
    {
        p.pop_back();
    }

    // Given the furthest right /, set instance to
    // the basename, and hwmonRoot to the leading path.
    auto n = p.rfind('/');
    if (n != std::string::npos)
    {
        _instance.assign(p.substr(n + 1));
        _hwmonRoot.assign(p.substr(0, n));
    }

    assert(!_instance.empty());
    assert(!_hwmonRoot.empty());
}

void MainLoop::shutdown() noexcept
{
    _event.exit(0);
}

void MainLoop::run()
{
    init();

    std::function<void()> callback(std::bind(&MainLoop::read, this));
    try
    {
        _timer.restart(std::chrono::microseconds(_interval));

        // TODO: Issue#6 - Optionally look at polling interval sysfs entry.

        // TODO: Issue#7 - Should probably periodically check the SensorSet
        //       for new entries.

        _bus.attach_event(_event.get(), SD_EVENT_PRIORITY_IMPORTANT);
        _event.loop();
    }
    catch (const std::exception& e)
    {
        log<level::ERR>("Error in sysfs polling loop",
                        entry("ERROR=%s", e.what()));
        throw;
    }
}

void MainLoop::init()
{
    // Check sysfs for available sensors.
    auto sensors = std::make_unique<SensorSet>(_hwmonRoot + '/' + _instance);

    for (const auto& i : *sensors)
    {
        auto object = getObject(i);
        if (object)
        {
            // Construct the SensorSet value
            // std::tuple<SensorSet::mapped_type,
            //            std::string(Sensor Label),
            //            ObjectInfo>
            auto value =
                std::make_tuple(std::move(i.second), std::move((*object).first),
                                std::move((*object).second));

            _state[std::move(i.first)] = std::move(value);
        }

        // Initialize _averageMap of sensor. e.g. <<power, 1>, <0, 0>>
        if ((i.first.first == hwmon::type::power) &&
            (phosphor::utility::isAverageEnvSet(i.first)))
        {
            _average.setAverageValue(i.first, std::make_pair(0, 0));
        }
    }

    /* If there are no sensors specified by labels, exit. */
    if (0 == _state.size())
    {
        exit(0);
    }

    {
        std::stringstream ss;
        std::string id = _instanceId;
        if (id.empty())
        {
            id =
                std::to_string(std::hash<std::string>{}(_devPath + _pathParam));
        }
        ss << _prefix << "-" << id << ".Hwmon1";

        _bus.request_name(ss.str().c_str());
    }

    {
        auto interval = env::getEnv("INTERVAL");
        if (!interval.empty())
        {
            _interval = std::strtoull(interval.c_str(), NULL, 10);
        }
    }
}

void MainLoop::read()
{
    // TODO: Issue#3 - Need to make calls to the dbus sensor cache here to
    //       ensure the objects all exist?

    // Iterate through all the sensors.
    for (auto& [sensorSetKey, sensorStateTuple] : _state)
    {
        const auto& [sensorSysfsType, sensorSysfsNum] = sensorSetKey;
        auto& [attrs, unused, objInfo] = sensorStateTuple;

        if (attrs.find(hwmon::entry::input) == attrs.end())
        {
            continue;
        }

        // Read value from sensor.
        std::string input = hwmon::entry::input;
        if (sensorSysfsType == hwmon::type::pwm)
        {
            input = "";
        }
        // If type is power and AVERAGE_power* is true in env, use average
        // instead of input
        else if ((sensorSysfsType == hwmon::type::power) &&
                 (phosphor::utility::isAverageEnvSet(sensorSetKey)))
        {
            input = hwmon::entry::average;
        }

        SensorValueType value;
        auto& obj = std::get<InterfaceMap>(objInfo);
        std::unique_ptr<sensor::Sensor>& sensor = _sensorObjects[sensorSetKey];

        auto& statusIface = std::any_cast<std::shared_ptr<StatusObject>&>(
            obj[InterfaceType::STATUS]);
        // As long as addStatus is called before addValue, statusIface
        // should never be nullptr.
        assert(statusIface);

        try
        {
            if (sensor->hasFaultFile())
            {
                auto fault = _ioAccess->read(sensorSysfsType, sensorSysfsNum,
                                             hwmon::entry::fault,
                                             hwmonio::retries, hwmonio::delay);
                // Skip reading from a sensor with a valid fault file
                // and set the functional property accordingly
                if (!statusIface->functional((fault == 0) ? true : false))
                {
                    continue;
                }
            }

            {
                // RAII object for GPIO unlock / lock
                auto locker = sensor::gpioUnlock(sensor->getGpio());

                // For sensors with attribute ASYNC_READ_TIMEOUT,
                // spawn a thread with timeout
                auto asyncReadTimeout =
                    env::getEnv("ASYNC_READ_TIMEOUT", sensorSetKey);
                if (!asyncReadTimeout.empty())
                {
                    std::chrono::milliseconds asyncTimeout{
                        std::stoi(asyncReadTimeout)};
                    value = sensor::asyncRead(
                        sensorSetKey, _ioAccess, asyncTimeout, _timedoutMap,
                        sensorSysfsType, sensorSysfsNum, input,
                        hwmonio::retries, hwmonio::delay);
                }
                else
                {
                    // Retry for up to a second if device is busy
                    // or has a transient error.
                    value =
                        _ioAccess->read(sensorSysfsType, sensorSysfsNum, input,
                                        hwmonio::retries, hwmonio::delay);
                }

                // Set functional property to true if we could read sensor
                statusIface->functional(true);

                value = sensor->adjustValue(value);

                if (input == hwmon::entry::average)
                {
                    // Calculate the values of averageMap based on current
                    // average value, current average_interval value, previous
                    // average value, previous average_interval value
                    int64_t interval =
                        _ioAccess->read(sensorSysfsType, sensorSysfsNum,
                                        hwmon::entry::caverage_interval,
                                        hwmonio::retries, hwmonio::delay);
                    auto ret = _average.getAverageValue(sensorSetKey);
                    assert(ret);

                    const auto& [preAverage, preInterval] = *ret;

                    auto calValue = Average::calcAverage(
                        preAverage, preInterval, value, interval);
                    if (calValue)
                    {
                        // Update previous values in averageMap before the
                        // variable value is changed next
                        _average.setAverageValue(
                            sensorSetKey, std::make_pair(value, interval));
                        // Update value to be calculated average
                        value = calValue.value();
                    }
                    else
                    {
                        // the value of
                        // power*_average_interval is not changed yet, use the
                        // previous calculated average instead. So skip dbus
                        // update.
                        continue;
                    }
                }
            }

            updateSensorInterfaces(obj, value);
        }
        catch (const std::system_error& e)
        {
#if UPDATE_FUNCTIONAL_ON_FAIL
            // If UPDATE_FUNCTIONAL_ON_FAIL is defined and an exception was
            // thrown, set the functional property to false.
            // We cannot set this with the 'continue' in the lower block
            // as the code may exit before reaching it.
            statusIface->functional(false);
#endif
            auto file = sysfs::make_sysfs_path(
                _ioAccess->path(), sensorSysfsType, sensorSysfsNum, input);

            // Check sensorAdjusts for sensor removal RCs
            auto& sAdjusts = _sensorObjects[sensorSetKey]->getAdjusts();
            if (sAdjusts.rmRCs.count(e.code().value()) > 0)
            {
                // Return code found in sensor return code removal list
                if (_rmSensors.find(sensorSetKey) == _rmSensors.end())
                {
                    // Trace for sensor not already removed from dbus
                    log<level::INFO>("Remove sensor from dbus for read fail",
                                     entry("FILE=%s", file.c_str()),
                                     entry("RC=%d", e.code().value()));
                    // Mark this sensor to be removed from dbus
                    _rmSensors[sensorSetKey] = attrs;
                }
                continue;
            }
#if UPDATE_FUNCTIONAL_ON_FAIL
            // Do not exit with failure if UPDATE_FUNCTIONAL_ON_FAIL is set
            continue;
#endif
            using namespace sdbusplus::xyz::openbmc_project::Sensor::Device::
                Error;
            report<ReadFailure>(
                xyz::openbmc_project::Sensor::Device::ReadFailure::
                    CALLOUT_ERRNO(e.code().value()),
                xyz::openbmc_project::Sensor::Device::ReadFailure::
                    CALLOUT_DEVICE_PATH(_devPath.c_str()));

            log<level::INFO>(std::format("Failing sysfs file: {} errno: {}",
                                         file, e.code().value())
                                 .c_str());

            exit(EXIT_FAILURE);
        }
    }

    removeSensors();

    addDroppedSensors();
}

void MainLoop::removeSensors()
{
    // Remove any sensors marked for removal
    for (const auto& i : _rmSensors)
    {
        // Remove sensor object from dbus using emit_object_removed()
        auto& objInfo = std::get<ObjectInfo>(_state[i.first]);
        auto& objPath = std::get<std::string>(objInfo);

        _bus.emit_object_removed(objPath.c_str());

        // Erase sensor object info
        _state.erase(i.first);
    }
}

void MainLoop::addDroppedSensors()
{
    // Attempt to add any sensors that were removed
    auto it = _rmSensors.begin();
    while (it != _rmSensors.end())
    {
        if (_state.find(it->first) == _state.end())
        {
            SensorSet::container_t::value_type ssValueType =
                std::make_pair(it->first, it->second);

            auto object = getObject(ssValueType);
            if (object)
            {
                // Construct the SensorSet value
                // std::tuple<SensorSet::mapped_type,
                //            std::string(Sensor Label),
                //            ObjectInfo>
                auto value = std::make_tuple(std::move(ssValueType.second),
                                             std::move((*object).first),
                                             std::move((*object).second));

                _state[std::move(ssValueType.first)] = std::move(value);

                std::string input = hwmon::entry::input;
                // If type is power and AVERAGE_power* is true in env, use
                // average instead of input
                if ((it->first.first == hwmon::type::power) &&
                    (phosphor::utility::isAverageEnvSet(it->first)))
                {
                    input = hwmon::entry::average;
                }
                // Sensor object added, erase entry from removal list
                auto file =
                    sysfs::make_sysfs_path(_ioAccess->path(), it->first.first,
                                           it->first.second, input);

                log<level::INFO>("Added sensor to dbus after successful read",
                                 entry("FILE=%s", file.c_str()));

                it = _rmSensors.erase(it);
            }
            else
            {
                ++it;
            }
        }
        else
        {
            // Sanity check to remove sensors that were re-added
            it = _rmSensors.erase(it);
        }
    }
}
