#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,
               bool enableFeatureLockdown);

    ~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,
                  bool enableFeatureLockdown);

    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;

    bool featureLockdownEnabled = false;

    /*
    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);
};
