
#pragma once

#include "NVMeFeatureStore.hpp"
#include "NVMeIntf.hpp"
#include "NVMeMetricStore.hpp"
#include "NVMePlugin.hpp"
#include "Utils.hpp"

#include <boost/asio.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <xyz/openbmc_project/Inventory/Item/StorageController/server.hpp>
#include <xyz/openbmc_project/NVMe/NVMeAdmin/server.hpp>
#include <xyz/openbmc_project/Software/ExtendedVersion/server.hpp>
#include <xyz/openbmc_project/Software/Version/server.hpp>

#include <utility>

using SoftwareVersion =
    sdbusplus::xyz::openbmc_project::Software::server::Version;
using SoftwareExtVersion =
    sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion;

class NVMeSubsystem;

/**
 * @brief A class to represent the NVMeController has not been enabled (CC.EN =
 * 0)
 *
 * The disabled controllers still have cntrl_id and are listed in the
 * cntrl_list. However the functionility has been disabled so neither
 * StorageController nor NVMeAdmin interface should be exposed for the disabled
 * controllers.
 *
 */
class NVMeController
{
  public:
    NVMeController(boost::asio::io_context& io,
                   sdbusplus::asio::object_server& objServer,
                   std::shared_ptr<sdbusplus::asio::connection> conn,
                   std::string path, const SensorData& configData,
                   std::shared_ptr<NVMeMiIntf> nvmeIntf, nvme_mi_ctrl_t ctrl,
                   std::weak_ptr<NVMeSubsystem> subsys,
                   bool enableFeatureLockdown);

    virtual ~NVMeController();

    virtual void start(const std::shared_ptr<NVMeControllerPlugin>& nvmePlugin);
    virtual void stop();

    // set the target as a primary controller with secondary controller list
    // with it
    inline void setPrimary(
        const std::vector<std::shared_ptr<NVMeController>>& secCntrls)
    {
        isPrimary = true;
        setSecAssoc(secCntrls);
    }

    // set the target as a secondary controller
    inline void setSecondary()
    {
        isPrimary = false;
        setSecAssoc({});
    }

    /**
     * @brief Get cntrl_id for the binded NVMe controller
     *
     * @return cntrl_id
     */
    // TODO: replace this with something from libnvme?
    uint16_t getCntrlId() const
    {
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
        return *reinterpret_cast<uint16_t*>(
            // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
            (reinterpret_cast<uint8_t*>(nvmeCtrl) +
             std::max(sizeof(uint16_t), sizeof(void*))));
    }

    /**
     * @brief Get the NVMe controller handle
     */
    nvme_mi_ctrl_t getMiCtrl() const
    {
        return nvmeCtrl;
    }

    void setNvmeVersion(uint32_t version);

    std::shared_ptr<NVMeMiIntf> getNvmeIntf() const
    {
        return nvmeIntf;
    }
    /**
     * @brief Update association interface.
     *
     * May be called externally when attached volumes change.
     **/
    void updateAssociation();

  protected:
    friend class NVMeControllerPlugin;

    bool isLogPageSupported(uint8_t lid) const;

    bool isPrimary;
    boost::asio::io_context& io;
    sdbusplus::asio::object_server& objServer;
    std::shared_ptr<sdbusplus::asio::connection> conn;
    std::string path;
    SensorData config;

    std::shared_ptr<sdbusplus::asio::dbus_interface> ctrlInterface;
    std::shared_ptr<sdbusplus::asio::dbus_interface> securityInterface;
    std::shared_ptr<sdbusplus::asio::dbus_interface> passthruInterface;
    std::shared_ptr<sdbusplus::asio::dbus_interface> lockdownInterface;
    std::shared_ptr<sdbusplus::asio::dbus_interface> featureStoreIntf;

    std::shared_ptr<NVMeMiIntf> nvmeIntf;
    nvme_mi_ctrl_t nvmeCtrl;

    std::shared_ptr<sdbusplus::asio::dbus_interface> assocIntf;
    void createAssociation();
    std::vector<Association> makeAssociation() const;

    // The association to secondary controllers from a primary controller
    std::vector<std::string> secondaryControllers;

    // The parent subsystem
    std::weak_ptr<NVMeSubsystem> subsys;

    // NVMe Plug-in for vendor defined command/field
    std::weak_ptr<NVMeControllerPlugin> plugin;

    bool featureLockdownEnabled = false;

    uint32_t nvmeVersion = 0;
    std::vector<uint8_t> supportedLogPages;

#if NVME_UNIT_TEST
    friend class NVMeTest;
#endif

  private:
    void setSecAssoc(
        const std::vector<std::shared_ptr<NVMeController>>& secCntrls);
};

/**
 * Forward declaration for metrics
 */
template <nvme_cmd_get_log_lid LID, class ClockType = std::chrono::steady_clock>
class ControllerLogPageMetric;
template <nvme_identify_cns CNS, class ClockType>
class IdentifyMetric;

/**
 * @brief A class for the NVMe controller that has been enabled (CC.EN = 1)
 *
 * The premitted NVMe Admin cmds should be anable to processed via the enabled
 * controller (e.g reading the temletries or other admin tasks). Thus the
 * NVMeAmin and StorageController Dbus interface will be exposed via this class.
 *
 */
class NVMeControllerEnabled :
    public NVMeController,
    //  StorageController interface will be used from PDI once coroutine
    //  sdbusplus methods are added. In the interim it is implemented manually.
    // private sdbusplus::xyz::openbmc_project::Inventory::Item::server::
    //     StorageController,
    private sdbusplus::xyz::openbmc_project::NVMe::server::NVMeAdmin,
    public SoftwareExtVersion,
    public SoftwareVersion,
    public std::enable_shared_from_this<NVMeControllerEnabled>

{
  public:
    static std::shared_ptr<NVMeControllerEnabled>
        create(NVMeController&& nvmeController);

    ~NVMeControllerEnabled() override;

    void
        start(const std::shared_ptr<NVMeControllerPlugin>& nvmePlugin) override;
    void stop() override;

  private:
    template <nvme_cmd_get_log_lid LID, class ClockType>
    friend class ControllerLogPageMetric;
    template <nvme_identify_cns CNS, class ClockType>
    friend class IdentifyMetric;

#if NVME_UNIT_TEST
    friend class NVMeTest;
#endif

    enum class Status : uint8_t
    {
        Disabled = 0, // the controller is not ready to serve
                      // DBus calls
        Enabled = 1,  // the controller is ready to serve DBus calls
    };

    Status status = Status::Disabled;

    std::optional<MetricStore> metricStore;
    std::shared_ptr<FeatureStore> featureStore;

    /** Create Metric store and load all the metric implementations
     */
    void initializeMetricStore();

    /** Create Feature store and load all the feature implementations
     */
    void initializeFeatureStore();

    explicit NVMeControllerEnabled(NVMeController&& nvmeController);

    void init();

    /* NVMeAdmin method overload */

    /** @brief Implementation for GetLogPage
     *  Send GetLogPage command to NVMe device
     *
     *  @param[in] lid - Log Page Identifier
     *  @param[in] nsid - Namespace Identifier
     *  @param[in] lsp - Log Specific Field
     *  @param[in] lsi - Log Specific Identifier
     *
     *  @return log[sdbusplus::message::unix_fd] - Returned Log
     * Page
     */
    sdbusplus::message::unix_fd getLogPage(uint8_t lid, uint32_t nsid,
                                           uint8_t lsp, uint16_t lsi) override;

    /** @brief Implementation for Identify
     *  Send Identify command to NVMe device
     *
     *  @param[in] cns - Controller or Namespace Structure
     *  @param[in] nsid - Namespace Identifier
     *  @param[in] cntid - Controller Identifier
     *
     *  @return data[sdbusplus::message::unix_fd] - Identify
     * Data
     */
    sdbusplus::message::unix_fd identify(uint8_t cns, uint32_t nsid,
                                         uint16_t cntid) override;
    /** Set value of FirmwareCommitStatus
     * Used to reset the the status back to ready if the commit
     * is not in process.
     */
    NVMeAdmin::FwCommitStatus
        firmwareCommitStatus(NVMeAdmin::FwCommitStatus commitStatus) override;

    /** @brief Implementation for FirmwareCommitAsync
     *  Send Firmware Commit command to NVMe device
     *
     *  @param[in] commitAction - Commit Action defined by NVMe
     * base spec (Figure 175 of rev 1.4)
     *  @param[in] firmwareSlot - Firmware Slot
     *  @param[in] bpid - Boot Partition ID
     */
    void firmwareCommitAsync(uint8_t commitAction, uint8_t firmwareSlot,
                             bool bpid) override;

    /** Set value of FirmwareDownloadStatus
     * Used to reset the the status back to ready if the
     * download is not in process.
     */
    NVMeAdmin::FwDownloadStatus firmwareDownloadStatus(
        NVMeAdmin::FwDownloadStatus downloadStatus) override;

    /** @brief Implementation for FirmwareDownloadAsync
     *  Send Firmware Image to the NVMe device
     *
     *  @param[in] pathToImage - Path to the firmware image
     */
    void firmwareDownloadAsync(std::string pathToImage) override;

    void securitySendMethod(boost::asio::yield_context yield, uint8_t proto,
                            uint16_t protoSpecific, std::span<uint8_t> data);

    std::vector<uint8_t> securityReceiveMethod(boost::asio::yield_context yield,
                                               uint8_t proto,
                                               uint16_t protoSpecific,
                                               uint32_t transferLength);

    std::tuple<uint32_t, uint32_t, uint32_t>
        adminNonDataCmdMethod(boost::asio::yield_context yield, uint8_t opcode,
                              uint32_t cdw1, uint32_t cdw2, uint32_t cdw3,
                              uint32_t cdw10, uint32_t cdw11, uint32_t cdw12,
                              uint32_t cdw13, uint32_t cdw14, uint32_t cdw15);

    std::tuple<uint32_t, uint32_t, uint32_t, std::string, uint32_t>
        lockdownInbandMethod(boost::asio::yield_context yield, uint8_t prohibit,
                             const std::vector<uint8_t>& adminCmds,
                             const std::vector<uint8_t>& features,
                             const std::vector<uint8_t>& logPages);

    void attachVolume(boost::asio::yield_context yield,
                      const sdbusplus::message::object_path& volumePath);

    void detachVolume(boost::asio::yield_context yield,
                      const sdbusplus::message::object_path& volumePath);

    void populateMetricStore();
    void discoverSupportedLogPages();

    void fetchSupportedLogPages(int retryCount,
                                const std::weak_ptr<bool>& weakToken);

    std::shared_ptr<boost::asio::steady_timer> discoverLogsRetryTimer;
    std::shared_ptr<bool> discoverLogsToken;
};
