#pragma once
#include "tach_sensor.hpp"

#include <memory>

namespace phosphor
{
namespace fan
{
namespace trust
{

constexpr auto sensorName = 0;
constexpr auto inTrust = 1;
using GroupDefinition = std::tuple<std::string, bool>;

struct GroupSensor
{
    std::shared_ptr<monitor::TachSensor> sensor;
    bool inTrust;
};

/**
 * @class Group
 *
 * An abstract sensor trust group base class.
 *
 * Supports the ability to know if a fan speed sensor value can
 * be trusted or not, where if it isn't trusted then it shouldn't
 * be used to determine if the fan is faulted or not.
 *
 * It's a group in that there can be multiple sensors in the group
 * and the trust of all sensors depends on something about those sensors.
 * For example, if all sensors in the group report a speed of zero,
 * then no sensor in the group is trusted.  All sensors in the group
 * have the same trust value.
 *
 * Trust is calculated when checkTrust() is called after a group
 * sensor's tach value changes.
 *
 * A derived class must override checkGroupTrust().
 */
class Group
{
  public:
    Group() = delete;
    virtual ~Group() = default;
    Group(const Group&) = delete;
    Group& operator=(const Group&) = delete;
    Group(Group&&) = default;
    Group& operator=(Group&&) = default;

    /**
     * Constructor
     *
     * @param[in] names - the names and inclusion of sensors in the group
     */
    explicit Group(const std::vector<GroupDefinition>& names) : _names(names) {}

    /**
     * Used to register a TachSensor object with the group.
     * It's only added to the group if the sensor's name is
     * in the group's list of names.
     *
     * @param[in] sensor - the TachSensor to register
     */
    void registerSensor(std::shared_ptr<monitor::TachSensor>& sensor)
    {
        auto found = std::find_if(_names.begin(), _names.end(),
                                  [&sensor](const auto& name) {
            return monitor::FAN_SENSOR_PATH + std::get<sensorName>(name) ==
                   sensor->name();
        });

        if (found != _names.end())
        {
            _sensors.push_back({sensor, std::get<inTrust>(*found)});
        }
    }

    /**
     * Says if a sensor belongs to the group.
     *
     * After all sensors have registered, this can be
     * used to say if a TachSensor is in the group.
     *
     * @param[in] sensor - the TachSensor object
     */
    bool inGroup(const monitor::TachSensor& sensor)
    {
        return (std::find_if(_sensors.begin(), _sensors.end(),
                             [&sensor](const auto& s) {
            return sensor.name() == s.sensor->name();
                }) != _sensors.end());
    }

    /**
     * Cancels monitoring on all sensors in the group.
     *
     * Called when the group just changed to not trusted,
     * so that its sensors' monitoring method does not
     * cause them to be considered faulted.
     */
    void cancelMonitoring()
    {
        std::for_each(_sensors.begin(), _sensors.end(),
                      [](const auto& s) { s.sensor->resetMethod(); });
    }

    /**
     * Starts monitoring on all sensors in the group by processing their current
     * state
     *
     * Called when the group just changed to trusted.
     */
    void startMonitoring()
    {
        std::for_each(_sensors.begin(), _sensors.end(),
                      [](const auto& s) { s.sensor->processState(); });
    }

    /**
     * Determines the trust for this group based on this
     * sensor's latest status.
     *
     * Calls the derived class's checkGroupTrust function
     * and updates the class with the results.
     *
     * If this is called with a sensor not in the group,
     * it will be considered trusted.
     *
     * @param[in] sensor - TachSensor object
     *
     * @return tuple<bool, bool> -
     *   field 0 - the trust value
     *   field 1 - if that trust value changed since last call
     *             to checkTrust
     */
    auto checkTrust(const monitor::TachSensor& sensor)
    {
        if (inGroup(sensor))
        {
            auto trust = checkGroupTrust();

            setTrust(trust);

            return std::tuple<bool, bool>(_trusted, _stateChange);
        }
        return std::tuple<bool, bool>(true, false);
    }

    /**
     * Says if all sensors in the group are currently trusted,
     * as determined by the last call to checkTrust().
     *
     * @return bool - if the group's sensors are trusted or not
     */
    inline auto getTrust() const
    {
        return _trusted;
    }

    /**
     * Says if the trust value changed in the last call to
     * checkTrust()
     *
     * @return bool - if the trust changed or not
     */
    inline auto trustChanged() const
    {
        return _stateChange;
    }

  protected:
    /**
     * The sensor objects and their trust inclusion in the group.
     *
     * Added by registerSensor().
     */
    std::vector<GroupSensor> _sensors;

  private:
    /**
     * Checks if the group's sensors are trusted.
     *
     * The derived class must override this function
     * to provide custom functionality.
     *
     * @return bool - if group is trusted or not
     */
    virtual bool checkGroupTrust() = 0;

    /**
     * Sets the trust value on the object.
     *
     * @param[in] trust - the new trust value
     */
    inline void setTrust(bool trust)
    {
        _stateChange = (trust != _trusted);
        _trusted = trust;
    }

    /**
     * The current trust state of the group
     */
    bool _trusted = true;

    /**
     * If the trust value changed in the last call to checkTrust
     */
    bool _stateChange = false;

    /**
     * The names of the sensors and whether it is included in
     * determining trust for this group
     */
    const std::vector<GroupDefinition> _names;
}; // namespace trust

} // namespace trust
} // namespace fan
} // namespace phosphor
