/**
 * 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 <phosphor-logging/elog-errors.hpp>
#include <xyz/openbmc_project/Sensor/Device/error.hpp>

#include <cassert>
#include <cstdlib>
#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;

    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
