/**
 * 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 <fmt/format.h>

#include <cassert>
#include <cstdlib>
#include <functional>
#include <future>
#include <iostream>
#include <memory>
#include <phosphor-logging/elog-errors.hpp>
#include <sstream>
#include <string>
#include <unordered_set>
#include <xyz/openbmc_project/Sensor/Device/error.hpp>

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;

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

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

/**
 * Reads the environment parameters of a sensor and creates an object with
 * atleast 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 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>(fmt::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>(fmt::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);
        }
    }
}

// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
