#pragma once

#include "callback.hpp"
#include "data_types.hpp"

#include <algorithm>
#include <functional>

namespace phosphor
{
namespace dbus
{
namespace monitoring
{

/** @class MedianCondition
 *  @brief Determine a median from properties and apply a condition.
 *
 *  When invoked, a median class instance performs its condition
 *  test against a median value that has been determined from a set
 *  of configured properties.
 *
 *  Once the median value is determined, a C++ relational operator
 *  is applied to it and a value provided by the configuration file,
 *  which determines if the condition passes or not.
 *
 *  Where no property values configured are found to determine a median from,
 *  the condition defaults to `true` and passes.
 *
 *  If the oneshot parameter is true, then this condition won't pass
 *  again until it fails at least once.
 */
template <typename T>
class MedianCondition : public IndexedConditional
{
  public:
    MedianCondition() = delete;
    MedianCondition(const MedianCondition&) = default;
    MedianCondition(MedianCondition&&) = default;
    MedianCondition& operator=(const MedianCondition&) = default;
    MedianCondition& operator=(MedianCondition&&) = default;
    ~MedianCondition() = default;

    MedianCondition(const PropertyIndex& conditionIndex,
                    const std::function<bool(T)>& _medianOp,
                    bool oneshot = false) :
        IndexedConditional(conditionIndex),
        medianOp(_medianOp), oneshot(oneshot)
    {
    }

    bool operator()() override
    {
        // Default the condition result to true
        // if no property values are found to produce a median.
        auto result = true;
        std::vector<T> values;
        for (const auto& item : index)
        {
            const auto& storage = std::get<storageIndex>(item.second);
            // Don't count properties that don't exist.
            if (!std::get<valueIndex>(storage.get()).has_value())
            {
                continue;
            }
            values.emplace_back(
                std::any_cast<T>(std::get<valueIndex>(storage.get())));
        }

        if (!values.empty())
        {
            auto median = values.front();
            // Get the determined median value
            if (values.size() == 2)
            {
                // For 2 values, use the highest instead of the average
                // for a worst case median value
                median = *std::max_element(values.begin(), values.end());
            }
            else if (values.size() > 2)
            {
                const auto oddIt = values.begin() + values.size() / 2;
                std::nth_element(values.begin(), oddIt, values.end());
                median = *oddIt;
                // Determine median for even number of values
                if (index.size() % 2 == 0)
                {
                    // Use average of middle 2 values for median
                    const auto evenIt = values.begin() + values.size() / 2 - 1;
                    std::nth_element(values.begin(), evenIt, values.end());
                    median = (median + *evenIt) / 2;
                }
            }

            // Now apply the condition to the median value.
            result = medianOp(median);
        }

        // If this was a oneshot and the the condition has already
        // passed, then don't let it pass again until the condition
        // has gone back to false.
        if (oneshot && result && lastResult)
        {
            return false;
        }

        lastResult = result;
        return result;
    }

  private:
    /** @brief The comparison to perform on the median value. */
    std::function<bool(T)> medianOp;
    /** @brief If the condition can be allowed to pass again
               on subsequent checks that are also true. */
    const bool oneshot;
    /** @brief The result of the previous check. */
    bool lastResult = false;
};

} // namespace monitoring
} // namespace dbus
} // namespace phosphor
