#pragma once
#include "NVMeBasic.hpp"
#include "NVMeController.hpp"
#include "NVMeDrive.hpp"
#include "NVMePlugin.hpp"
#include "NVMeProgress.hpp"
#include "NVMeSensor.hpp"
#include "NVMeStorage.hpp"
#include "NVMeUtil.hpp"
#include "Utils.hpp"

#include <cstdint>

class NVMeVolume;
class NVMeCreateVolumeProgress;

#ifdef NVME_UNIT_TEST
class NVMeTest;
#endif

class NVMeSubsystem :
    public std::enable_shared_from_this<NVMeSubsystem>,
    public NVMeStorage
{
  public:
    static std::shared_ptr<NVMeSubsystem>
        create(boost::asio::io_context& io,
               sdbusplus::asio::object_server& objServer,
               const std::shared_ptr<sdbusplus::asio::connection>& conn,
               const std::string& path, const std::string& name,
               const SensorData& configData, NVMeIntf intf);

    ~NVMeSubsystem() override;

    void start();

    void stop();

    /** @brief Returns the dbus path for a given volume.
     *
     *  @param[in] nsid - The NSID of the volume
     *
     *  @return path[std::string] - The dbus path for the volume.
     */
    std::string volumePath(uint32_t nsid) const;

    /**
     * @brief delete given namespace from the nvme device and nvme daemon,
     * throws on error
     */
    void deleteVolume(boost::asio::yield_context yield,
                      const std::shared_ptr<NVMeVolume>& volume);

    std::vector<uint32_t> attachedVolumes(uint16_t ctrlId) const;

    /**
     * @brief Attach the namespace to controller, throws std::runtime_error on
     * failure
     */
    void attachCtrlVolume(uint16_t ctrlId, uint32_t nsid);
    /**
     * @brief Detach the namespace from controller, throws std::runtime_error on
     * failure
     */
    void detachCtrlVolume(uint16_t ctrlId, uint32_t nsid);
    void detachAllCtrlVolume(uint32_t nsid);
    std::shared_ptr<NVMeVolume>
        getVolume(const sdbusplus::message::object_path& volPath) const;

    void startSanitize(const NVMeSanitizeParams& params,
                       std::function<void(nvme_ex_ptr ex)>&& submitCb);
    void sanitizeStatus(
        std::function<void(nvme_ex_ptr ex, bool inProgress, bool failed,
                           bool completed, uint16_t sstat, uint16_t sprog,
                           uint32_t scdw10)>&& cb);

    const std::string path;

    NVMeSubsystem(boost::asio::io_context& io,
                  sdbusplus::asio::object_server& objServer,
                  const std::shared_ptr<sdbusplus::asio::connection>& conn,
                  const std::string& path, const std::string& name,
                  const SensorData& configData, NVMeIntf intf);

    void init();

    const std::string& getName() const
    {
        return name;
    }

#if defined NVME_UNIT_TEST
    // allow the test fixture change the settings for subsystem
    friend class NVMeTest;
#endif

  private:
    friend class NVMePlugin;

    template <nvme_identify_cns CNS, class ClockType>
    friend class IdentifyMetric;

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

    NVMeIntf nvmeIntf;

    /*
     * stateDiagram
     *     [*] --> Stop
     *     Stop --> Intiatilzing
     *     Intiatilzing --> Start
     *     Intiatilzing --> Aborting
     *     Start --> Terminating
     *     Aborting --> Terminating
     *     Terminating --> Stop
     */
    enum class Status : uint8_t
    {
        Stop,
        Intiatilzing,
        Aborting,
        Start,
        Terminating,
    };

    Status status;

    // plugin
    std::shared_ptr<NVMePlugin> plugin;

    /* thermal sensor for the subsystem */
    std::shared_ptr<NVMeSensor> ctemp;
    std::shared_ptr<boost::asio::steady_timer> ctempTimer;
    std::chrono::milliseconds pollingInterval = std::chrono::milliseconds(1000);

    /* Begin of patch context
     *
     *
     *
     */
    /*
     *
     *
     * End of patch context
     */

    /*
    Drive interface: xyz.openbmc_project.Inventory.Item.Drive
    */
    std::shared_ptr<NVMeDrive> drive;

    // map from cntrlid to a pair of {controller, controller_plugin}
    std::map<uint16_t, std::pair<std::shared_ptr<NVMeController>,
                                 std::shared_ptr<NVMeControllerPlugin>>>
        controllers;

    /*
    map of nsid to volumes
    */
    std::map<uint32_t, std::shared_ptr<NVMeVolume>> volumes;

    /*
     * volumes attached to controllers
     */
    std::map<uint16_t, std::set<uint32_t>> attached;

    /*
    In-progress or completed create operations
    */
    std::unordered_map<std::string, std::shared_ptr<NVMeCreateVolumeProgress>>
        createProgress;

    // controller to use for NVMe operations. Is a member of the controllers
    // map. Access this through getPrimaryController() to test for nullness.
    std::shared_ptr<NVMeControllerEnabled> primaryController;

    std::shared_ptr<sdbusplus::asio::dbus_interface> assocIntf;

    void createAssociation();
    void updateAssociation();
    std::vector<Association> makeAssociation() const;

    // make the subsystem functional/functional be enabling/disabling the
    // storage controller, namespaces and thermal sensors.
    void markFunctional(bool toggle);

    // mark the availability of the Storage device.
    void markAvailable(bool toggle);

    // may throw NVMeError if no controller is available
    std::shared_ptr<NVMeControllerEnabled> getPrimaryController() const;

    sdbusplus::message::object_path
        createVolume(boost::asio::yield_context yield, uint64_t size,
                     size_t lbaFormat, bool metadataAtEnd) override;

    // callback when drive completes. not called in dbus method context.
    void createVolumeFinished(const std::string& progId, const nvme_ex_ptr& ex,
                              NVMeNSIdentify ns);

    void addIdentifyNamespace(boost::asio::yield_context yield, uint32_t nsid);

    // fill DBus object for Drive, throws on failure
    void fillDrive(boost::asio::yield_context yield);

    // update all namespaces in the subsystem, throws on failure
    void updateVolumes(boost::asio::yield_context yield);

    // removes state associated with the volume. Does not manipulate the drive.
    // throws on error
    void forgetVolume(const std::shared_ptr<NVMeVolume>& volume);

    // adds state associated with the volume. Does not create a volume.
    // may throw if the volume exists.
    std::shared_ptr<NVMeVolume> addVolume(const NVMeNSIdentify& ns);

    // query the supported LBA formats from identify ns, throws on failure
    void querySupportedFormats(boost::asio::yield_context yield);

    // a counter to skip health poll when NVMe subsystem becomes Unavailable
    unsigned unavailableCount = 0;
    unsigned unavailableMaxCount = 60;

    // process Secondary controller and start controllers and the associated
    // Plugin
    void processSecondaryControllerList(nvme_secondary_ctrl_list* secCntlrList);
};
