#pragma once

#include "NVMeCache.hpp"
#include "Utils.hpp"

#include <libnvme-mi.h>

#include <functional>
#include <memory>
#include <span>
#include <string>
#include <unordered_map>

class NVMeSubsystem;
class NVMeController;

class NVMePlugin;
class NVMeControllerPlugin;

// A map from library name to the dlopen() pointer
extern std::unordered_map<std::string, void*> pluginLibMap;

// entry function for plugin library to create the plugin instance
using createplugin_t = std::shared_ptr<NVMePlugin> (*)(
    std::shared_ptr<NVMeSubsystem> subsys, const SensorData& config);

class NVMeControllerPlugin
{
  public:
    using getlogpage_t = std::function<void(
        uint8_t lid, uint32_t nsid, uint8_t lsp, uint16_t lsi,
        std::function<void(const std::error_code&, std::span<uint8_t>)>&& cb)>;

    // The controller plugin can only be created from NVMePlugin
    NVMeControllerPlugin(std::shared_ptr<NVMeController> cntl,
                         [[maybe_unused]] const SensorData& cfg) :
        nvmeController(std::move(cntl))
    {}

    virtual ~NVMeControllerPlugin() = default;
    virtual getlogpage_t getGetLogPageHandler()
    {
        return {};
    }

  protected:
    const std::string& getPath() const;
    sdbusplus::asio::object_server& getDbusServer();
    std::shared_ptr<sdbusplus::asio::connection> getDbusConnection();
    boost::asio::io_context& getIOContext();
    bool isPrimary() const;

    /**
     * adminXfer() -  transfer Raw admin cmd to the binded conntroller
     * @admin_req: request header
     * @data: request data payload
     * @timeout_ms: timeout in ms
     * @resp_data_offset: offset into request data to retrieve from controller
     * @cb: callback function after the response received.
     * @ec: error code
     * @admin_resp: response header
     * @resp_data: response data payload
     *
     * Performs an arbitrary NVMe Admin command, using the provided request
     * header, in @admin_req. The requested data is attached by @data, if any.
     *
     * On success, @cb will be called and response header and data are stored
     * in
     * @admin_resp and @resp_data, which has an optional appended payload
     * buffer. The response data does not include the Admin request header, so
     * 0 represents no payload.
     *
     * As with all Admin commands, we can request partial data from the Admin
     * Response payload, offset by @resp_data_offset. In case of resp_data
     * contains only partial data of the caller's requirement, a follow-up
     * call to adminXfer with offset is required.
     *
     * See: &struct nvme_mi_admin_req_hdr and &struct nvme_mi_admin_resp_hdr.
     *
     * @ec will be returned on failure.
     */
    void adminXfer(const nvme_mi_admin_req_hdr& adminReq,
                   std::span<uint8_t> data, unsigned int timeoutMs,
                   std::function<void(const std::error_code& ec,
                                      const nvme_mi_admin_resp_hdr& adminResp,
                                      std::span<uint8_t> respData)>&& cb);
    /**
     * @brief Get cntrl_id for the binded NVMe controller
     *
     * @return cntrl_id
     */
    uint16_t getCntrlId() const;

    /**
     * @brief Check if log page is supported for the binded NVMe controller
     *
     * @param lid log page identifier
     * @return true if supported, false otherwise
     */
    bool isLogPageSupported(uint8_t lid) const;

  private:
    std::shared_ptr<NVMeController> nvmeController;
};

class NVMePlugin
{
  public:
    NVMePlugin(std::shared_ptr<NVMeSubsystem> subsys, const SensorData& config);

    virtual ~NVMePlugin();

    std::shared_ptr<NVMeControllerPlugin>
        createControllerPlugin(const NVMeController& controller,
                               const SensorData& config);

    // the NVMe subsystem will start the plugin after NVMesubsystem finished
    // intialization and started.
    virtual void start() {}

    // the NVMe subsystem will stop the plugin before NVMe subsystem stop
    // itself.
    virtual void stop() {}

    // get Vendor Metric for given path
    virtual std::vector<std::shared_ptr<MetricBase<>>>
        getMetric(const std::string& /*path*/) noexcept
    {
        return {};
    }

    static constexpr const char* libraryPath = "/usr/lib/nvmed/";

  protected:
    const std::string& getPath() const;
    const std::string& getName() const;
    boost::asio::io_context& getIOContext();
    sdbusplus::asio::object_server& getDbusServer();
    std::shared_ptr<sdbusplus::asio::connection> getDbusConnection();

    const std::map<uint16_t, std::pair<std::shared_ptr<NVMeController>,
                                       std::shared_ptr<NVMeControllerPlugin>>>&
        getControllers();
    // The nvme plugin implemenation need to overload the function to create a
    // derived controller plugin.
    virtual std::shared_ptr<NVMeControllerPlugin>
        makeController(std::shared_ptr<NVMeController> cntl,
                       const SensorData&) = 0;

  private:
    std::shared_ptr<NVMeSubsystem> subsystem;
};
