#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
