#pragma once

#include <chrono>
#include "data_types.hpp"

namespace phosphor
{
namespace dbus
{
namespace monitoring
{

/** @class Callback
 *  @brief Callback interface.
 *
 *  Callbacks of any type can be run.
 */
class Callback
{
    public:
        Callback() = default;
        Callback(const Callback&) = delete;
        Callback(Callback&&) = default;
        Callback& operator=(const Callback&) = delete;
        Callback& operator=(Callback&&) = default;
        virtual ~Callback() = default;

        /** @brief Run the callback.
         *  @param[in] ctx - caller context
         *     Context could be Startup or Signal
         *     Startup: Callback is called as part of process startup.
         *     Signal: Callback is called as part of watch condition has been met.
         *
         */
        virtual void operator()(Context ctx) = 0;
};

/** @class Conditional
 *  @brief Condition interface.
 *
 *  Conditions of any type can be tested for true or false.
 */
class Conditional
{
    public:
        Conditional() = default;
        Conditional(const Conditional&) = delete;
        Conditional(Conditional&&) = default;
        Conditional& operator=(const Conditional&) = delete;
        Conditional& operator=(Conditional&&) = default;
        virtual ~Conditional() = default;

        /** @brief Test the condition. */
        virtual bool operator()() = 0;
};

/** @class IndexedConditional
 *  @brief Condition with an index.
 */
class IndexedConditional : public Conditional
{
    public:
        IndexedConditional() = delete;
        IndexedConditional(const IndexedConditional&) = delete;
        IndexedConditional(IndexedConditional&&) = default;
        IndexedConditional& operator=(const IndexedConditional&) = delete;
        IndexedConditional& operator=(IndexedConditional&&) = default;
        virtual ~IndexedConditional() = default;

        explicit IndexedConditional(const PropertyIndex& conditionIndex)
            : Conditional(), index(conditionIndex) {}

        /** @brief Test the condition. */
        virtual bool operator()() override = 0;

    protected:

        /** @brief Property names and their associated storage. */
        const PropertyIndex& index;
};

/** @class IndexedCallback
 *  @brief Callback with an index.
 */
class IndexedCallback : public Callback
{
    public:
        IndexedCallback() = delete;
        IndexedCallback(const IndexedCallback&) = delete;
        IndexedCallback(IndexedCallback&&) = default;
        IndexedCallback& operator=(const IndexedCallback&) = delete;
        IndexedCallback& operator=(IndexedCallback&&) = default;
        virtual ~IndexedCallback() = default;
        explicit IndexedCallback(const PropertyIndex& callbackIndex)
            : Callback(), index(callbackIndex) {}

        /** @brief Run the callback. */
        virtual void operator()(Context ctx) override = 0;

    protected:

        /** @brief Property names and their associated storage. */
        const PropertyIndex& index;
};

/** @class GroupOfCallbacks
 *  @brief Invoke multiple callbacks.
 *
 *  A group of callbacks is implemented as a vector of array indices
 *  into an external array  of callbacks.  The group function call
 *  operator traverses the vector of indices, invoking each
 *  callback.
 *
 *  @tparam CallbackAccess - Access to the array of callbacks.
 */
template <typename CallbackAccess>
class GroupOfCallbacks : public Callback
{
    public:
        GroupOfCallbacks() = delete;
        GroupOfCallbacks(const GroupOfCallbacks&) = delete;
        GroupOfCallbacks(GroupOfCallbacks&&) = default;
        GroupOfCallbacks& operator=(const GroupOfCallbacks&) = delete;
        GroupOfCallbacks& operator=(GroupOfCallbacks&&) = default;
        ~GroupOfCallbacks() = default;
        explicit GroupOfCallbacks(
            const std::vector<size_t>& graphEntry)
            : graph(graphEntry) {}

        /** @brief Run the callbacks. */
        void operator()(Context ctx) override
        {
            for (auto e : graph)
            {
                (*CallbackAccess::get()[e])(ctx);
            }
        }

    private:
        /** @brief The offsets of the callbacks in the group. */
        const std::vector<size_t>& graph;
};

/** @class ConditionalCallback
 *  @brief Callback adaptor that asssociates a condition with a callback.
 */
template <typename CallbackAccess>
class ConditionalCallback: public Callback
{
    public:
        ConditionalCallback() = delete;
        ConditionalCallback(const ConditionalCallback&) = delete;
        ConditionalCallback(ConditionalCallback&&) = default;
        ConditionalCallback& operator=(const ConditionalCallback&) = delete;
        ConditionalCallback& operator=(ConditionalCallback&&) = default;
        virtual ~ConditionalCallback() = default;
        ConditionalCallback(
            const std::vector<size_t>& graphEntry,
            Conditional& cond)
            : graph(graphEntry), condition(cond) {}

        /** @brief Run the callback if the condition is satisfied. */
        virtual void operator()(Context ctx) override
        {
            if (condition())
            {
                (*CallbackAccess::get()[graph[0]])(ctx);
            }
        }

    protected:
        /** @brief The index of the callback to conditionally invoke. */
        const std::vector<size_t>& graph;

        /** @brief The condition to test. */
        Conditional& condition;
};

/** @class DeferrableCallback
 *
 *  Deferrable callbacks wait a configurable period before
 *  invoking their associated callback.
 *
 *  When the callback condition is initially met, start a timer.  If the
 *  condition is tested again before the timer expires and it is not
 *  met cancel the timer.  If the timer expires invoke the associated
 *  callback.
 *
 *  @tparam CallbackAccess - Provide access to callback group instances.
 *  @tparam TimerType - Delegated timer access methods.
 */
template <typename CallbackAccess, typename TimerType>
class DeferrableCallback : public ConditionalCallback<CallbackAccess>
{
    public:
        DeferrableCallback() = delete;
        DeferrableCallback(const DeferrableCallback&) = delete;
        DeferrableCallback(DeferrableCallback&&) = default;
        DeferrableCallback& operator=(const DeferrableCallback&) = delete;
        DeferrableCallback& operator=(DeferrableCallback&&) = default;
        ~DeferrableCallback() = default;

        DeferrableCallback(
            const std::vector<size_t>& graphEntry,
            Conditional& cond,
            const std::chrono::microseconds& delay)
            : ConditionalCallback<CallbackAccess>(graphEntry, cond),
              delayInterval(delay),
              timer(nullptr) {}

        void operator()(Context ctx) override
        {
            if (!timer)
            {
                timer = std::make_unique<TimerType>(
// **INDENT-OFF**
                    [ctx, this](auto & source)
                    {
                        this->ConditionalCallback<CallbackAccess>::operator()(ctx);
                    });
// **INDENT-ON**
                timer->disable();
            }

            if (this->condition())
            {
                if (!timer->enabled())
                {
                    // This is the first time the condition evaluated.
                    // Start the countdown.
                    timer->update(timer->now() + delayInterval);
                    timer->enable();
                }
            }
            else
            {
                // The condition did not evaluate.  Stop the countdown.
                timer->disable();
            }
        }

    private:
        /** @brief The length to wait for the condition to stop evaluating. */
        std::chrono::microseconds delayInterval;

        /** @brief Delegated timer functions. */
        std::unique_ptr<TimerType> timer;
};

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