#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
