#pragma once

#include <sdbusplus/bus.hpp>
#include <tuple>
#include <vector>
#include "event.hpp"
#include "tach_sensor.hpp"
#include "types.hpp"

namespace phosphor
{
namespace fan
{
namespace monitor
{

/**
 * The mode fan monitor will run in:
 *   - init - only do the initialization steps
 *   - monitor - run normal monitoring algorithm
 */
enum class Mode
{
    init,
    monitor
};

/**
 * @class InvalidSensorError
 *
 * An exception type for sensors that don't exist or
 * are otherwise inaccessible.
 */
class InvalidSensorError : public std::exception {};

/**
 * @class Fan
 *
 * Represents a fan, which can contain 1 or more sensors which
 * loosely correspond to rotors.  See below.
 *
 * There is a sensor when hwmon exposes one, which means there is a
 * speed value to be read.  Sometimes there is a sensor per rotor,
 * and other times multiple rotors just use 1 sensor total where
 * the sensor reports the slowest speed of all of the rotors.
 *
 * A rotor's speed is set by writing the Target value of a sensor.
 * Sometimes each sensor in a fan supports having a Target, and other
 * times not all of them do.  A TachSensor object knows if it supports
 * the Target property.
 *
 * The strategy for monitoring fan speeds is as follows:
 *
 * Every time a Target (new speed written) or Input (actual speed read)
 * sensor changes, check if the input value is within some range of the target
 * value.  If it isn't, start a timer at the end of which the sensor will be
 * set to not functional.  If enough sensors in the fan are now nonfunctional,
 * set the whole fan to nonfunctional in the inventory.
 *
 * When sensor inputs come back within a specified range of the target,
 * stop its timer if running, make the sensor functional again if it wasn't,
 * and if enough sensors in the fan are now functional set the whole fan
 * back to functional in the inventory.
 */
class Fan
{
    using Property = std::string;
    using Value = sdbusplus::message::variant<bool>;
    using PropertyMap = std::map<Property, Value>;

    using Interface = std::string;
    using InterfaceMap = std::map<Interface, PropertyMap>;

    using Object = sdbusplus::message::object_path;
    using ObjectMap = std::map<Object, InterfaceMap>;

    public:

        Fan() = delete;
        Fan(const Fan&) = delete;
        Fan(Fan&&) = default;
        Fan& operator=(const Fan&) = delete;
        Fan& operator=(Fan&&) = default;
        ~Fan() = default;

        /**
         * @brief Constructor
         *
         * @param mode - mode of fan monitor
         * @param bus - the dbus object
         * @param events - pointer to sd_event object
         * @param def - the fan definition structure
         */
        Fan(Mode mode,
            sdbusplus::bus::bus& bus,
            phosphor::fan::event::EventPtr& events,
            const FanDefinition& def);

        /**
         * @brief Callback function for when an input sensor changes
         *
         * Starts a timer, where if it expires then the sensor
         * was out of range for too long and can be considered not functional.
         */
        void tachChanged(TachSensor& sensor);

        /**
         * @brief Calls tachChanged(sensor) on each sensor
         */
        void tachChanged();

        /**
         * @brief The callback function for the timer
         *
         * Sets the sensor to not functional.
         * If enough sensors are now not functional,
         * updates the functional status of the whole
         * fan in the inventory.
         *
         * @param[in] sensor - the sensor whose timer expired
         */
        void timerExpired(TachSensor& sensor);

    private:

        /**
         * @brief Returns the target speed of the sensor
         *
         * If the sensor itself doesn't have a target, it finds
         * the target speed from another sensor.
         *
         * @param[in] sensor - the sensor to get the target speed for
         */
        uint64_t getTargetSpeed(const TachSensor& sensor);

        /**
         * @brief Returns true if the sensor input is not within
         * some deviation of the target.
         *
         * @param[in] sensor - the sensor to check
         */
        bool outOfRange(const TachSensor& sensor);

        /**
         * @brief Returns true if too many sensors are nonfunctional
         *        as defined by _numSensorFailsForNonFunc
         */
        bool tooManySensorsNonfunctional();

        /**
         * @brief Updates the Functional property in the inventory
         *        for the fan based on the value passed in.
         *
         * @param[in] functional - If the Functional property should
         *                         be set to true or false.
         */
        void updateInventory(bool functional);

        /**
         * @brief Returns the object map to use when updating the inventory
         *
         * @param[in] functional - If the Functional property should
         *                         be set to true or false.
         */
        ObjectMap getObjectMap(bool functional);

        /**
         * @brief the dbus object
         */
        sdbusplus::bus::bus& _bus;

        /**
         * @brief The inventory name of the fan
         */
        const std::string _name;

        /**
         * @brief The percentage that the input speed must be below
         *        the target speed to be considered an error.
         *        Between 0 and 100.
         */
        const size_t _deviation;

        /**
         * The number of sensors that must be nonfunctional at the
         * same time in order for the fan to be set to nonfunctional
         * in the inventory.
         */
        const size_t _numSensorFailsForNonFunc;

        /**
         * @brief The current functional state of the fan
         */
        bool _functional = true;

        /**
         * The sensor objects for the fan
         */
        std::vector<std::unique_ptr<TachSensor>> _sensors;
};

}
}
}
