#pragma once
#include <boost/asio/steady_timer.hpp>
#include <phosphor-logging/lg2.hpp>

#include <chrono>
#include <format>
#include <functional>
#include <memory>
#include <set>
#include <vector>

constexpr unsigned backgroundBps = 4 * 1024;
template <class ClockType_>
class Scheduler;

template <class ClockType_ = std::chrono::steady_clock>
class MetricBase : public std::enable_shared_from_this<MetricBase<ClockType_>>
{
    // type definition
  public:
    using ClockType = ClockType_;

    // constructor
    /**
     * interval: refresh rate for the Metric
     */
    MetricBase(std::shared_ptr<Scheduler<ClockType_>> scheduler,
               ClockType_::duration interval) :
        scheduler(scheduler), interval(interval)
    {
        // partialRefreshCBs.emplace_back(std::bind(scheduler->callback,
        // nullptr));
    }

    virtual ~MetricBase()
    {
        for (auto&& func : partialRefreshCBs)
        {
            if (func)
            {
                func(std::make_error_code(std::errc::operation_canceled));
            }
        }
        for (auto&& func : refreshCBs)
        {
            if (func)
            {
                func(std::make_error_code(std::errc::operation_canceled));
            }
        }
        for (auto&& func : completeCBs)
        {
            if (func)
            {
                func(std::make_error_code(std::errc::operation_canceled));
            }
        }
    }

    // firendship
  private:
    friend class Scheduler<ClockType>;
    // variables
  protected:
    std::shared_ptr<Scheduler<ClockType>> scheduler;
    const ClockType::duration interval;

    std::optional<
        std::pair<std::chrono::time_point<ClockType>, std::vector<uint8_t>>>
        inprocessData; // start time, data
  private:
    bool refreshing = false;
    std::vector<std::function<void(std::error_code ec)>> refreshCBs;
    std::vector<std::function<void(std::error_code ec)>> partialRefreshCBs;
    std::vector<std::function<void(std::error_code ec)>> completeCBs;

    /* methods */
  public:
    // refresh the whole cache
    void refresh(std::function<void(std::error_code ec)>&& cb);

    // refresh partial of the cache if the data is large.
    void partialRefresh(std::function<void(std::error_code ec)>&& cb);

    /**
     * register a callback which will be triggered for every refresh completion.
     * the callback will NOT be removed after a single refresh completion
     */
    void registerCompleteCB(std::function<void(std::error_code ec)>&& cb)
    {
        completeCBs.push_back(std::move(cb));
    }

    bool isRefreshing() const;
    // bool isPartialRefreshing() const = 0;

  protected:
    // read data from device and update the
    // implemetation should extend this virtual function and do the real data
    // fetch from device.
    virtual void readDevice(
        std::function<void(std::error_code ec, size_t size, bool complete)>&&
            cb) noexcept = 0;

  public:
    // interface
    virtual constexpr std::string_view getIdentifier() const noexcept = 0;
    virtual bool isCacheValid() const noexcept = 0;
    virtual std::tuple<std::chrono::time_point<ClockType>,
                       std::chrono::time_point<ClockType>,
                       std::span<const uint8_t>>
        getCache() const noexcept = 0;
};

template <class ClockType_ = std::chrono::steady_clock>
class Scheduler : public std::enable_shared_from_this<Scheduler<ClockType_>>
{
  public:
    using ClockType = ClockType_;

    using ScheduledTask = std::pair<std::chrono::time_point<ClockType>,
                                    std::weak_ptr<MetricBase<ClockType>>>;

    // template <class ClockType>
    explicit Scheduler(boost::asio::io_context& io);
    ~Scheduler() = default;

    // find the schuduler with give path for a storage componenet (e.g.
    // Controller)
    static std::shared_ptr<Scheduler<ClockType_>>
        getScheduler(const std::string& path);

    void enqueue(std::chrono::time_point<ClockType> scheduledTime,
                 std::shared_ptr<MetricBase<ClockType>> task);
    void dequeue();
    // void callback(std::shared_ptr<MetricBase<ClockType>> task, size_t size);
    void start()
    {
        started = true;
    }

  private:
    friend class MetricBase<ClockType_>;

    boost::asio::io_context& io;
    boost::asio::steady_timer timer;
    bool started = false;
    // Task Queue, sorted by Scheduled Time.
    std::multiset<ScheduledTask,
                  bool (*)(const ScheduledTask&, const ScheduledTask&)>
        taskQueue;
    std::vector<std::shared_ptr<bool>> validFlags;

    std::weak_ptr<MetricBase<ClockType>>
        executingTask; // the metric is currently under execution.
};

template <class ClockType_>
void MetricBase<ClockType_>::refresh(
    std::function<void(std::error_code ec)>&& cb)
{
    refreshing = true;

    refreshCBs.push_back(std::move(cb));
    scheduler->enqueue(ClockType_::now(), this->shared_from_this());
}

template <class ClockType_>
void MetricBase<ClockType_>::partialRefresh(
    std::function<void(std::error_code ec)>&& cb)
{
    partialRefreshCBs.push_back(std::move(cb));
    scheduler->enqueue(ClockType_::now(), this->shared_from_this());
}
template <class ClockType_>
bool MetricBase<ClockType_>::isRefreshing() const
{
    return refreshing;
}

//
// void ::callback(
//     std::shared_ptr<MetricBase<ClockType>> task, size_t size)
// {}

template <class ClockType>
bool compareScheduleTask(const typename Scheduler<ClockType>::ScheduledTask& a,
                         const typename Scheduler<ClockType>::ScheduledTask& b)
{
    return a.first < b.first;
}

template <class ClockType_>
Scheduler<ClockType_>::Scheduler(boost::asio::io_context& io) :
    io(io), timer(io), taskQueue(&compareScheduleTask<ClockType_>)
{}

template <class ClockType_>
void Scheduler<ClockType_>::enqueue(
    std::chrono::time_point<ClockType> scheduledTime,
    std::shared_ptr<MetricBase<ClockType>> task)
{
    // check if the task is being executed.
    if (!executingTask.owner_before(task) && !task.owner_before(executingTask))
    {
        return;
    }
    timer.cancel();
    validFlags.clear();

    assert(task && "insert invalid task into schduler");
    // remove duplicate and find the earliest schdule time
    std::chrono::time_point<ClockType> time = scheduledTime;
    for (auto itr = taskQueue.begin(); itr != taskQueue.end();)
    {
        auto metric = itr->second.lock();
        if (!metric)
        {
            lg2::info("the task is invalid, removed from task queue");
            itr = taskQueue.erase(itr);
        }
        else if (!metric.owner_before(task) &&
                 !task.owner_before(metric)) // find duplicate task
        {
            time = std::min(time, itr->first);
            itr = taskQueue.erase(itr);
        }
        else
        {
            itr++;
        }
    }

    taskQueue.emplace(time, task);

    if (started)
    {
        dequeue();
    }
}
template <class ClockType_>
void Scheduler<ClockType_>::dequeue()
{
    if (taskQueue.empty())
    {
        return;
    }
    const std::pair<std::chrono::time_point<ClockType_>,
                    std::weak_ptr<MetricBase<ClockType_>>>& head =
        *taskQueue.begin();
    validFlags.emplace_back(std::make_shared<bool>(true));
    std::weak_ptr<bool> weakFlag = validFlags.back();

    timer.expires_at(head.first);
    timer.async_wait([weakSelf{this->weak_from_this()},
                      weakFlag](boost::system::error_code ec) {
        if (ec || weakFlag.expired())
        {
            lg2::info("new expiration time set");
            return;
        }

        auto self = weakSelf.lock();

        if (!self)
        {
            lg2::info("the scheduler has stopped");
            return;
        }

        auto node = self->taskQueue.extract(self->taskQueue.begin());
        std::weak_ptr<MetricBase<ClockType_>> weakTask = node.value().second;
        auto task = weakTask.lock();
        if (!task)
        {
            lg2::info("the task is invalid, removed from task queue");
            self->dequeue();
            return;
        }
        self->executingTask = task;

        task->readDevice(
            [self{self}, weakTask{weakTask}](std::error_code /* ec */,
                                             size_t size, bool complete) {
            // todo: deal with ec

            std::shared_ptr<MetricBase<ClockType_>> task = weakTask.lock();
            if (!task)
            {
                lg2::info("the task is invalid, removed from task queue");
                self->executingTask.reset();
                self->dequeue();
                return;
            }

            // calcuate the next schedule time
            std::chrono::time_point<ClockType_> time;
            if (complete)
            {
                if (task->interval == ClockType_::duration::max())
                {
                    time = ClockType_::time_point::max();
                }
                else
                {
                    time = ClockType_::now() + task->interval;
                }
            }
            else if (task->refreshing)
            {
                time = ClockType_::now();
            }
            else
            {
                time = ClockType_::now() +
                       std::chrono::milliseconds(static_cast<size_t>(
                           static_cast<double>(size) * 1000 / backgroundBps));
            }

            self->executingTask.reset();
            self->enqueue(time, task);

            for (auto&& func : task->partialRefreshCBs)
            {
                if (func)
                {
                    func({});
                }
            }
            task->partialRefreshCBs.clear();

            if (complete)
            {
                for (auto&& func : task->refreshCBs)
                {
                    if (func)
                    {
                        func({});
                    }
                }
                for (auto&& func : task->completeCBs)
                {
                    if (func)
                    {
                        func({});
                    }
                }
                task->refreshCBs.clear();
                task->refreshing = false;
            }
        });
    });
}
