#pragma once
/**
 * This file contains all cache implementation of types of Metrics
 */

#include "NVMeCache.hpp"
#include "NVMeController.hpp"
#include "NVMeVolume.hpp"

/**
 * Metric implementation for LogPage
 */

template <nvme_cmd_get_log_lid LID, class ClockType, uint8_t DA>
class ControllerLogPageMetric : public MetricBase<ClockType>
{
  public:
    ControllerLogPageMetric(std::weak_ptr<NVMeControllerEnabled> controller,
                            std::shared_ptr<Scheduler<ClockType>> scheduler,
                            ClockType::duration interval) :
        MetricBase<ClockType>(scheduler, interval),
        controller(std::move(controller))
    {}

    /* interface overrides */
    static constexpr std::string_view logpageIdentifier() noexcept
    {
        if constexpr (LID == NVME_LOG_LID_ERROR)
        {
            return "ErrorInfoMetric";
        }
        else if constexpr (LID == NVME_LOG_LID_SMART)
        {
            return "SMARTMetric";
        }
        else if constexpr (LID == NVME_LOG_LID_FW_SLOT)
        {
            return "FwSlotInfoMetric";
        }
        else if constexpr (LID == NVME_LOG_LID_DEVICE_SELF_TEST)
        {
            return "DeviceSelfTestMetric";
        }
        else if constexpr (LID == NVME_LOG_LID_TELEMETRY_HOST)
        {
            if constexpr (DA >= 1 && DA <= 4)
            {
                constexpr std::array<std::string_view, 5> daStrings = {
                    "", // DA=0 is not used in this range
                    "DriveHostInitiated_DA1", "DriveHostInitiated_DA2",
                    "DriveHostInitiated_DA3", "DriveHostInitiated_DA4"};
                return daStrings[DA];
            }
            else
            {
                return "HostInitiatedMetric";
            }
        }
        else if constexpr (LID == NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN)
        {
            return "LockdownMetric";
        }
        else
        {
            static_assert(false,
                          "LID not supported by ControllerLogPageMetric");
        }

        return {};
    }

    constexpr std::string_view getIdentifier() const noexcept override
    {
        return logpageIdentifier();
    }

    bool isCacheValid() const noexcept override
    {
        return cacheValid;
    }
    std::tuple<std::chrono::time_point<ClockType>,
               std::chrono::time_point<ClockType>, std::span<const uint8_t>>
        getCache() const noexcept override
    {
        std::chrono::time_point<ClockType> start = std::get<0>(cache);
        std::chrono::time_point<ClockType> stop = std::get<1>(cache);
        auto& data = std::get<2>(cache);
        return {start, stop,
                std::span<const uint8_t>(data.begin(), data.end())};
    }

    /* internal overrides */
  private:
    // read data from device and update the
    // implemetation should extend this virtual function and do the real
    // data fetch from device.
    void readDevice(std::function<void(std::error_code ec, size_t size,
                                       bool complete)>&& cb) noexcept override
    {
        auto startTime = ClockType::now();

        auto cntrlPtr = controller.lock();
        assert(cntrlPtr &&
               cntrlPtr->status == NVMeControllerEnabled::Status::Enabled &&
               "NVMe Metric refresh requires enabled controller");
        assert(cntrlPtr->nvmeIntf &&
               "NVMe Metric refresh requires active MI interface");
        uint8_t reqLsp = 0;
        if constexpr (LID == NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN)
        {
            reqLsp = 0xFF;
        }

        cntrlPtr->nvmeIntf->adminGetLogPage(
            cntrlPtr->nvmeCtrl, LID, 0, reqLsp, 0,
            [weakSelf{std::move(this->weak_from_this())}, startTime,
             path{cntrlPtr->path}, id{getIdentifier()}, cb{std::move(cb)}](
                const std::error_code& ec, std::span<uint8_t> data) {
            auto self = std::dynamic_pointer_cast<
                ControllerLogPageMetric<LID, ClockType, DA>>(weakSelf.lock());
            if (!self)
            {
                lg2::info("[{PATH},{ID}]metric released before callback",
                          "PATH", path, "ID", id);
                // The Scheduler will clear the invalid cache Task
                cb({}, 4096, true);
                return;
            }

            if (ec)
            {
                if (self->errorCount <
                    ControllerLogPageMetric<LID, ClockType, DA>::errorCountMax)
                {
                    lg2::warning(
                        "[{PATH},{ID}]fail to fresh log page at retry({RETRY})",
                        "PATH", path, "ID", id, "RETRY", self->errorCount++);

                    // Schedule the retry after 1s
                    // TODO: costomize the retry delay for each log pages.
                    cb(std::make_error_code(std::errc::io_error), 4096, false);
                    return;
                }
                lg2::error("[{PATH},{ID}]retry exhausted to fresh log page",
                           "PATH", path, "ID", id);
                self->cacheValid = false;

                // Notify the RefreshCB with error code; the task will
                // be reschuduled after this->interval
                cb(std::make_error_code(std::errc::io_error), 4096, true);
                return;
            }
            self->errorCount = 0;
            self->cacheValid = true;
            std::get<0>(self->cache) = startTime;
            std::get<1>(self->cache) = ClockType::now();

            auto& cacheData = std::get<2>(self->cache);
            cacheData.clear();
            cacheData.insert(cacheData.begin(), data.begin(), data.end());

            cb({}, data.size(), true);
        },
            DA);
    }
    /* member variables */
    std::weak_ptr<NVMeControllerEnabled> controller;

    std::tuple<std::chrono::time_point<ClockType>,
               std::chrono::time_point<ClockType>, std::vector<uint8_t>>
        cache;
    bool cacheValid{false};
    unsigned errorCount{0};
    static constexpr unsigned errorCountMax = 5;
};

/**
 * Metric implementation for Identify info
 */
template <nvme_identify_cns CNS, class ClockType>
class IdentifyMetric : public MetricBase<ClockType>
{
  public:
    template <class T>
        requires((CNS == NVME_IDENTIFY_CNS_CTRL &&
                  std::is_base_of_v<NVMeControllerEnabled, T>) ||
                 (CNS == NVME_IDENTIFY_CNS_NS &&
                  std::is_base_of_v<NVMeVolume, T>))
    IdentifyMetric(std::shared_ptr<T> resource,
                   std::shared_ptr<Scheduler<ClockType>> scheduler,
                   ClockType::duration interval) :
        MetricBase<ClockType>(scheduler, interval)
    {
        assert(resource &&
               "Fail to construct Identify Metric on empty resource");
        path = resource->path;
        if constexpr (CNS == NVME_IDENTIFY_CNS_CTRL)
        {
            controller = resource;
            namespaceId = 0;
        }
        else if constexpr (CNS == NVME_IDENTIFY_CNS_NS)
        {
            auto subsys = resource->subsys.lock();
            assert(subsys &&
                   "Fail to construct NS Identify Metric on expired subsystem");
            controller = subsys->getPrimaryController();
            namespaceId = resource->namespaceId();
        }
        else
        {
            static_assert(false, "unsupported CNS for IdentifyMetric");
        }
    }

    /* interface overrides */
    inline static constexpr std::string_view identifyIdentifier() noexcept
    {
        return "IdentifyMetric";
    }
    constexpr std::string_view getIdentifier() const noexcept override
    {
        return identifyIdentifier();
    }

    bool isCacheValid() const noexcept override
    {
        return cacheValid;
    }
    std::tuple<std::chrono::time_point<ClockType>,
               std::chrono::time_point<ClockType>, std::span<const uint8_t>>
        getCache() const noexcept override
    {
        std::chrono::time_point<ClockType> start = std::get<0>(cache);
        std::chrono::time_point<ClockType> stop = std::get<1>(cache);
        auto& data = std::get<2>(cache);
        return {start, stop,
                std::span<const uint8_t>(data.begin(), data.end())};
    }

    /* internal overrides */
  private:
    // read data from device and update the
    // implemetation should extend this virtual function and do the real
    // data fetch from device.
    void readDevice(std::function<void(std::error_code ec, size_t size,
                                       bool complete)>&& cb) noexcept override
    {
        auto startTime = ClockType::now();

        auto cntrlPtr = controller.lock();
        assert(cntrlPtr &&
               cntrlPtr->status == NVMeControllerEnabled::Status::Enabled &&
               "NVMe Metric refresh requires enabled controller");
        assert(cntrlPtr->nvmeIntf &&
               "NVMe Metric refresh requires active MI interface");

        cntrlPtr->nvmeIntf->adminIdentify(
            cntrlPtr->nvmeCtrl, CNS, namespaceId,
            0 /* CNTID will not be used for CNS = 00h/01h */,
            [weakSelf{std::move(this->weak_from_this())}, startTime, path{path},
             id{getIdentifier()}, cb{std::move(cb)}](const nvme_ex_ptr& ex,
                                                     std::span<uint8_t> data) {
            auto self =
                std::dynamic_pointer_cast<IdentifyMetric<CNS, ClockType>>(
                    weakSelf.lock());
            if (!self)
            {
                lg2::info("[{PATH},{ID}]metric released before callback",
                          "PATH", path, "ID", id);
                // The Scheduler will clear the invalid cache Task
                cb({}, 4096, true);
                return;
            }
            if (ex)
            {
                if (self->errorCount <
                    IdentifyMetric<CNS, ClockType>::errorCountMax)
                {
                    lg2::warning(
                        "[{PATH},{ID}]fail to fresh identify at retry({RETRY}): {ERROR}",
                        "PATH", path, "ID", id, "RETRY", self->errorCount++,
                        "ERROR", ex->description());

                    // Schedule the retry after 1s
                    cb(std::make_error_code(std::errc::io_error), 4096, false);
                    return;
                }
                lg2::error(
                    "[{PATH},{ID}]retry exhausted to fresh identify: {ERROR}",
                    "PATH", path, "ID", id, "ERROR", ex->description());
                self->cacheValid = false;

                // Notify the RefreshCB with error code; the task will
                // be reschuduled after this->interval
                cb(std::make_error_code(std::errc::io_error), 4096, true);
                return;
            }
            self->errorCount = 0;
            self->cacheValid = true;
            std::get<0>(self->cache) = startTime;
            std::get<1>(self->cache) = ClockType::now();

            auto& cacheData = std::get<2>(self->cache);
            cacheData.clear();
            cacheData.insert(cacheData.begin(), data.begin(), data.end());

            cb({}, data.size(), true);
        });
    }

    /* member variables */
    std::string path;
    std::weak_ptr<NVMeControllerEnabled> controller;
    uint32_t namespaceId;

    std::tuple<std::chrono::time_point<ClockType>,
               std::chrono::time_point<ClockType>, std::vector<uint8_t>>
        cache;
    bool cacheValid{false};
    unsigned errorCount{0};
    static constexpr unsigned errorCountMax = 5;
};
