#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
