/**
 * Copyright © 2022 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 "fan.hpp"

#include "logging.hpp"
#include "sdbusplus.hpp"
#include "system.hpp"
#include "types.hpp"
#include "utility.hpp"

#include <phosphor-logging/log.hpp>

#include <format>

namespace phosphor
{
namespace fan
{
namespace monitor
{

using namespace phosphor::logging;
using namespace sdbusplus::bus::match;

Fan::Fan(Mode mode, sdbusplus::bus_t& bus, const sdeventplus::Event& event,
         std::unique_ptr<trust::Manager>& trust, const FanDefinition& def,
         System& system) :
    _bus(bus),
    _name(def.name), _deviation(def.deviation),
    _upperDeviation(def.upperDeviation),
    _numSensorFailsForNonFunc(def.numSensorFailsForNonfunc),
    _trustManager(trust),
#ifdef MONITOR_USE_JSON
    _monitorDelay(def.monitorStartDelay),
    _monitorTimer(event, std::bind(std::mem_fn(&Fan::startMonitor), this)),
#endif
    _system(system),
    _presenceMatch(bus,
                   rules::propertiesChanged(util::INVENTORY_PATH + _name,
                                            util::INV_ITEM_IFACE),
                   std::bind(std::mem_fn(&Fan::presenceChanged), this,
                             std::placeholders::_1)),
    _presenceIfaceAddedMatch(
        bus,
        rules::interfacesAdded() +
            rules::argNpath(0, util::INVENTORY_PATH + _name),
        std::bind(std::mem_fn(&Fan::presenceIfaceAdded), this,
                  std::placeholders::_1)),
    _fanMissingErrorDelay(def.fanMissingErrDelay),
    _setFuncOnPresent(def.funcOnPresent)
{
    // Setup tach sensors for monitoring
    for (const auto& s : def.sensorList)
    {
        _sensors.emplace_back(std::make_shared<TachSensor>(
            mode, bus, *this, s.name, s.hasTarget, def.funcDelay,
            s.targetInterface, s.targetPath, s.factor, s.offset, def.method,
            s.threshold, s.ignoreAboveMax, def.timeout,
            def.nonfuncRotorErrDelay, def.countInterval, event));

        _trustManager->registerSensor(_sensors.back());
    }

    bool functionalState =
        (_numSensorFailsForNonFunc == 0) ||
        (countNonFunctionalSensors() < _numSensorFailsForNonFunc);

    if (updateInventory(functionalState) && !functionalState)
    {
        // the inventory update threw an exception, possibly because D-Bus
        // wasn't ready. Try to update sensors back to functional to avoid a
        // false-alarm. They will be updated again from subscribing to the
        // properties-changed event

        for (auto& sensor : _sensors)
            sensor->setFunctional(true);
    }

#ifndef MONITOR_USE_JSON
    // Check current tach state when entering monitor mode
    if (mode != Mode::init)
    {
        _monitorReady = true;

        // The TachSensors will now have already read the input
        // and target values, so check them.
        tachChanged();
    }
#else
    if (_system.isPowerOn())
    {
        _monitorTimer.restartOnce(std::chrono::seconds(_monitorDelay));
    }
#endif

    if (_fanMissingErrorDelay)
    {
        _fanMissingErrorTimer = std::make_unique<
            sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
            event, std::bind(&System::fanMissingErrorTimerExpired, &system,
                             std::ref(*this)));
    }

    try
    {
        _present = util::SDBusPlus::getProperty<bool>(
            util::INVENTORY_PATH + _name, util::INV_ITEM_IFACE, "Present");

        if (!_present)
        {
            getLogger().log(
                std::format("On startup, fan {} is missing", _name));
            if (_system.isPowerOn() && _fanMissingErrorTimer)
            {
                _fanMissingErrorTimer->restartOnce(
                    std::chrono::seconds{*_fanMissingErrorDelay});
            }
        }
    }
    catch (const util::DBusServiceError& e)
    {
        // This could happen on the first BMC boot if the presence
        // detect app hasn't started yet and there isn't an inventory
        // cache yet.
    }
}

void Fan::presenceIfaceAdded(sdbusplus::message_t& msg)
{
    sdbusplus::message::object_path path;
    std::map<std::string, std::map<std::string, std::variant<bool>>> interfaces;

    msg.read(path, interfaces);

    auto properties = interfaces.find(util::INV_ITEM_IFACE);
    if (properties == interfaces.end())
    {
        return;
    }

    auto property = properties->second.find("Present");
    if (property == properties->second.end())
    {
        return;
    }

    _present = std::get<bool>(property->second);

    if (!_present)
    {
        getLogger().log(std::format(
            "New fan {} interface added and fan is not present", _name));
        if (_system.isPowerOn() && _fanMissingErrorTimer)
        {
            _fanMissingErrorTimer->restartOnce(
                std::chrono::seconds{*_fanMissingErrorDelay});
        }
    }

    _system.fanStatusChange(*this);
}

void Fan::startMonitor()
{
    _monitorReady = true;

    std::for_each(_sensors.begin(), _sensors.end(), [this](auto& sensor) {
        if (_present)
        {
            try
            {
                // Force a getProperty call to check if the tach sensor is
                // on D-Bus.  If it isn't, now set it to nonfunctional.
                // This isn't done earlier so that code watching for
                // nonfunctional tach sensors doesn't take actions before
                // those sensors show up on D-Bus.
                sensor->updateTachAndTarget();
                tachChanged(*sensor);
            }
            catch (const util::DBusServiceError& e)
            {
                // The tach property still isn't on D-Bus. Ensure
                // sensor is nonfunctional, but skip creating an
                // error for it since it isn't a fan problem.
                getLogger().log(std::format(
                    "Monitoring starting but {} sensor value not on D-Bus",
                    sensor->name()));

                sensor->setFunctional(false, true);

                if (_numSensorFailsForNonFunc)
                {
                    if (_functional && (countNonFunctionalSensors() >=
                                        _numSensorFailsForNonFunc))
                    {
                        updateInventory(false);
                    }
                }

                // At this point, don't start any power off actions due
                // to missing sensors.  Let something else handle that
                // policy.
                _system.fanStatusChange(*this, true);
            }
        }
    });
}

void Fan::tachChanged()
{
    if (_monitorReady)
    {
        for (auto& s : _sensors)
        {
            tachChanged(*s);
        }
    }
}

void Fan::tachChanged(TachSensor& sensor)
{
    if (!_system.isPowerOn() || !_monitorReady)
    {
        return;
    }

    if (_trustManager->active())
    {
        if (!_trustManager->checkTrust(sensor))
        {
            return;
        }
    }

    // If the error checking method is 'count', if a tach change leads
    // to an out of range sensor the count timer will take over in calling
    // process() until the sensor is healthy again.
    if (!sensor.countTimerRunning())
    {
        process(sensor);
    }
}

void Fan::countTimerExpired(TachSensor& sensor)
{
    if (_trustManager->active() && !_trustManager->checkTrust(sensor))
    {
        return;
    }
    process(sensor);
}

void Fan::process(TachSensor& sensor)
{
    // If this sensor is out of range at this moment, start
    // its timer, at the end of which the inventory
    // for the fan may get updated to not functional.

    // If this sensor is OK, put everything back into a good state.

    if (outOfRange(sensor))
    {
        if (sensor.functional())
        {
            switch (sensor.getMethod())
            {
                case MethodMode::timebased:
                    // Start nonfunctional timer if not already running
                    sensor.startTimer(TimerMode::nonfunc);
                    break;
                case MethodMode::count:

                    if (!sensor.countTimerRunning())
                    {
                        sensor.startCountTimer();
                    }
                    sensor.setCounter(true);
                    if (sensor.getCounter() >= sensor.getThreshold())
                    {
                        updateState(sensor);
                    }
                    break;
            }
        }
    }
    else
    {
        switch (sensor.getMethod())
        {
            case MethodMode::timebased:
                if (sensor.functional())
                {
                    if (sensor.timerRunning())
                    {
                        sensor.stopTimer();
                    }
                }
                else
                {
                    // Start functional timer if not already running
                    sensor.startTimer(TimerMode::func);
                }
                break;
            case MethodMode::count:
                sensor.setCounter(false);
                if (sensor.getCounter() == 0)
                {
                    if (!sensor.functional())
                    {
                        updateState(sensor);
                    }

                    sensor.stopCountTimer();
                }
                break;
        }
    }
}

uint64_t Fan::findTargetSpeed()
{
    uint64_t target = 0;
    // The sensor doesn't support a target,
    // so get it from another sensor.
    auto s = std::find_if(_sensors.begin(), _sensors.end(),
                          [](const auto& s) { return s->hasTarget(); });

    if (s != _sensors.end())
    {
        target = (*s)->getTarget();
    }

    return target;
}

size_t Fan::countNonFunctionalSensors() const
{
    return std::count_if(_sensors.begin(), _sensors.end(),
                         [](const auto& s) { return !s->functional(); });
}

bool Fan::outOfRange(const TachSensor& sensor)
{
    if (!sensor.hasOwner())
    {
        return true;
    }

    auto actual = static_cast<uint64_t>(sensor.getInput());
    auto range = sensor.getRange(_deviation, _upperDeviation);

    return ((actual < range.first) ||
            (range.second && actual > range.second.value()));
}

void Fan::updateState(TachSensor& sensor)
{
    if (!_system.isPowerOn())
    {
        return;
    }

    auto range = sensor.getRange(_deviation, _upperDeviation);
    std::string rangeMax = "NoMax";
    if (range.second)
    {
        rangeMax = std::to_string(range.second.value());
    }

    // Skip starting the error timer if the sensor
    // isn't on D-Bus as this isn't a fan hardware problem.
    sensor.setFunctional(!sensor.functional(), !sensor.hasOwner());

    getLogger().log(std::format(
        "Setting tach sensor {} functional state to {}. "
        "[target = {}, actual = {}, allowed range = ({} - {}) "
        "owned = {}]",
        sensor.name(), sensor.functional(), sensor.getTarget(),
        sensor.getInput(), range.first, rangeMax, sensor.hasOwner()));

    // A zero value for _numSensorFailsForNonFunc means we aren't dealing
    // with fan FRU functional status, only sensor functional status.
    if (_numSensorFailsForNonFunc)
    {
        auto numNonFuncSensors = countNonFunctionalSensors();
        // If the fan was nonfunctional and enough sensors are now OK,
        // the fan can be set to functional as long as `set_func_on_present` was
        // not set
        if (!_setFuncOnPresent && !_functional &&
            !(numNonFuncSensors >= _numSensorFailsForNonFunc))
        {
            getLogger().log(std::format("Setting fan {} to functional, number "
                                        "of nonfunctional sensors = {}",
                                        _name, numNonFuncSensors));
            updateInventory(true);
        }

        // If the fan is currently functional, but too many
        // contained sensors are now nonfunctional, update
        // the fan to nonfunctional.
        if (_functional && (numNonFuncSensors >= _numSensorFailsForNonFunc))
        {
            getLogger().log(std::format("Setting fan {} to nonfunctional, "
                                        "number of nonfunctional sensors = {}",
                                        _name, numNonFuncSensors));
            updateInventory(false);
        }
    }

    // Skip the power off rule checks if the sensor isn't
    // on D-Bus so a running system isn't shutdown.
    _system.fanStatusChange(*this, !sensor.hasOwner());
}

bool Fan::updateInventory(bool functional)
{
    bool dbusError = false;

    try
    {
        auto objectMap =
            util::getObjMap<bool>(_name, util::OPERATIONAL_STATUS_INTF,
                                  util::FUNCTIONAL_PROPERTY, functional);

        auto response = util::SDBusPlus::callMethod(
            _bus, util::INVENTORY_SVC, util::INVENTORY_PATH,
            util::INVENTORY_INTF, "Notify", objectMap);

        if (response.is_method_error())
        {
            log<level::ERR>("Error in Notify call to update inventory");

            dbusError = true;
        }
    }
    catch (const util::DBusError& e)
    {
        dbusError = true;

        getLogger().log(
            std::format("D-Bus Exception reading/updating inventory : {}",
                        e.what()),
            Logger::error);
    }

    // This will always track the current state of the inventory.
    _functional = functional;

    return dbusError;
}

void Fan::presenceChanged(sdbusplus::message_t& msg)
{
    std::string interface;
    std::map<std::string, std::variant<bool>> properties;

    msg.read(interface, properties);

    auto presentProp = properties.find("Present");
    if (presentProp != properties.end())
    {
        _present = std::get<bool>(presentProp->second);

        getLogger().log(
            std::format("Fan {} presence state change to {}", _name, _present));

        if (_present && _setFuncOnPresent)
        {
            updateInventory(true);
            std::for_each(_sensors.begin(), _sensors.end(), [](auto& sensor) {
                sensor->setFunctional(true);
                sensor->resetMethod();
            });
        }

        _system.fanStatusChange(*this);

        if (_fanMissingErrorDelay)
        {
            if (!_present && _system.isPowerOn())
            {
                _fanMissingErrorTimer->restartOnce(
                    std::chrono::seconds{*_fanMissingErrorDelay});
            }
            else if (_present && _fanMissingErrorTimer->isEnabled())
            {
                _fanMissingErrorTimer->setEnabled(false);
            }
        }
    }
}

void Fan::sensorErrorTimerExpired(const TachSensor& sensor)
{
    if (_present && _system.isPowerOn())
    {
        _system.sensorErrorTimerExpired(*this, sensor);
    }
}

void Fan::powerStateChanged([[maybe_unused]] bool powerStateOn)
{
#ifdef MONITOR_USE_JSON
    if (powerStateOn)
    {
        _monitorTimer.restartOnce(std::chrono::seconds(_monitorDelay));

        _numSensorsOnDBusAtPowerOn = 0;

        std::for_each(_sensors.begin(), _sensors.end(), [this](auto& sensor) {
            try
            {
                // Force a getProperty call.  If sensor is on D-Bus,
                // then make sure it's functional.
                sensor->updateTachAndTarget();

                _numSensorsOnDBusAtPowerOn++;

                if (_present)
                {
                    // If not functional, set it back to functional.
                    if (!sensor->functional())
                    {
                        sensor->setFunctional(true);
                        _system.fanStatusChange(*this, true);
                    }

                    // Set the counters back to zero
                    if (sensor->getMethod() == MethodMode::count)
                    {
                        sensor->resetMethod();
                    }
                }
            }
            catch (const util::DBusError& e)
            {
                // Properties still aren't on D-Bus.  Let startMonitor()
                // deal with it, or maybe System::powerStateChanged() if
                // there aren't any sensors at all on D-Bus.
                getLogger().log(std::format(
                    "At power on, tach sensor {} value not on D-Bus",
                    sensor->name()));
            }
        });

        if (_present)
        {
            // If configured to change functional state on the fan itself,
            // Set it back to true now if necessary.
            if (_numSensorFailsForNonFunc)
            {
                if (!_functional &&
                    (countNonFunctionalSensors() < _numSensorFailsForNonFunc))
                {
                    updateInventory(true);
                }
            }
        }
        else
        {
            getLogger().log(
                std::format("At power on, fan {} is missing", _name));

            if (_fanMissingErrorTimer)
            {
                _fanMissingErrorTimer->restartOnce(
                    std::chrono::seconds{*_fanMissingErrorDelay});
            }
        }
    }
    else
    {
        _monitorReady = false;

        if (_monitorTimer.isEnabled())
        {
            _monitorTimer.setEnabled(false);
        }

        if (_fanMissingErrorTimer && _fanMissingErrorTimer->isEnabled())
        {
            _fanMissingErrorTimer->setEnabled(false);
        }

        std::for_each(_sensors.begin(), _sensors.end(), [](auto& sensor) {
            if (sensor->timerRunning())
            {
                sensor->stopTimer();
            }

            sensor->stopCountTimer();
        });
    }
#endif
}

} // namespace monitor
} // namespace fan
} // namespace phosphor
