#include "NVMeIntf.hpp"
#include "Utils.hpp"

#include <boost/asio.hpp>
#include <sdbusplus/bus.hpp>

#include <cstdint>
#include <thread>

// A worker thread for calling NVMeMI cmd.
class NVMeMiWorker
{
  private:
    bool workerStop = false;
    std::mutex workerMtx;
    std::condition_variable workerCv;
    boost::asio::io_context workerIO;
    bool workerIsNotified = false;
    std::thread thread;

  public:
    NVMeMiWorker();
    NVMeMiWorker(const NVMeMiWorker&) = delete;
    ~NVMeMiWorker();
    void post(std::function<void(void)>&& func);
};

class NVMeMi : public NVMeMiIntf, public std::enable_shared_from_this<NVMeMi>
{
  public:
    NVMeMi(boost::asio::io_context& io,
           const std::shared_ptr<sdbusplus::asio::connection>& conn,
           const std::shared_ptr<const MctpDevice>& device,
           const std::shared_ptr<NVMeMiWorker>& worker,
           PowerState readState = PowerState::always);
    ~NVMeMi() override;

    bool flushOperations(std::function<void()>&& cb) override;
    void miSubsystemHealthStatusPoll(
        std::function<void(const std::error_code&,
                           nvme_mi_nvm_ss_health_status*)>&& cb) override;
    void miScanCtrl(std::function<void(const std::error_code&,
                                       const std::vector<nvme_mi_ctrl_t>&)>
                        cb) override;
    void adminIdentify(
        nvme_mi_ctrl_t ctrl, nvme_identify_cns cns, uint32_t nsid,
        uint16_t cntid,
        std::function<void(nvme_ex_ptr, std::span<uint8_t>)>&& cb) override;
    void adminGetLogPage(nvme_mi_ctrl_t ctrl, nvme_cmd_get_log_lid lid,
                         uint32_t nsid, uint8_t lsp, uint16_t lsi,
                         std::function<void(const std::error_code&,
                                            std::span<uint8_t>)>&& cb) override;

    void adminFwCommit(
        nvme_mi_ctrl_t ctrl, nvme_fw_commit_ca action, uint8_t slot, bool bpid,
        std::function<void(const std::error_code&, nvme_status_field)>&& cb)
        override;

    void adminFwDownload(nvme_mi_ctrl_t ctrl, std::string firmwarefile,
                         std::function<void(const std::error_code&,
                                            nvme_status_field)>&& cb) override;

    void adminXfer(nvme_mi_ctrl_t ctrl, const nvme_mi_admin_req_hdr& adminReq,
                   std::span<uint8_t> data, unsigned int timeoutMs,
                   std::function<void(const std::error_code&,
                                      const nvme_mi_admin_resp_hdr&,
                                      std::span<uint8_t>)>&& cb) override;

    void adminSecuritySend(nvme_mi_ctrl_t ctrl, uint8_t proto,
                           uint16_t protoSpecific, std::span<uint8_t> data,
                           std::function<void(const std::error_code&,
                                              int nvmeStatus)>&& cb) override;

    void adminSecurityReceive(
        nvme_mi_ctrl_t ctrl, uint8_t proto, uint16_t protoSpecific,
        uint32_t transferLength,
        std::function<void(const std::error_code&, int nvmeStatus,
                           std::span<uint8_t> data)>&& cb) override;

    void adminNonDataCmd(
        nvme_mi_ctrl_t ctrl, 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::function<void(const std::error_code&, int nvmeStatus,
                           uint32_t comptionDw0)>&& cb) override;

    void createNamespace(
        nvme_mi_ctrl_t ctrl, uint64_t size, size_t lbaFormat,
        bool metadataAtEnd, std::function<void(nvme_ex_ptr ex)>&& submittedCb,
        std::function<void(nvme_ex_ptr ex, NVMeNSIdentify newid)>&& finishedCb)
        override;

    void adminDeleteNamespace(
        nvme_mi_ctrl_t ctrl, uint32_t nsid,
        std::function<void(const std::error_code&, int nvmeStatus)>&& cb)
        override;

    void adminListNamespaces(
        nvme_mi_ctrl_t ctrl,
        std::function<void(nvme_ex_ptr ex, std::vector<uint32_t> ns)>&& cb)
        override;

    void adminAttachDetachNamespace(
        nvme_mi_ctrl_t ctrl, uint16_t ctrlid, uint32_t nsid, bool attach,
        std::function<void(const std::error_code&, int nvmeStatus)>&& cb)
        override;

    void adminSanitize(nvme_mi_ctrl_t ctrl, enum nvme_sanitize_sanact sanact,
                       uint8_t passes, uint32_t pattern, bool invertPattern,
                       std::function<void(nvme_ex_ptr ex)>&& cb) override;

    void start(const std::shared_ptr<MctpEndpoint>& ep) override;
    void stop() override;
    void recover() override;

  private:
    // the transfer size for nvme mi messages.
    // define in github.com/linux-nvme/libnvme/blob/master/src/nvme/mi.c
    static constexpr size_t nvmeMiXferSize = 4096;

    static nvme_root_t nvmeRoot;

    boost::asio::io_context& io;
    std::shared_ptr<const MctpDevice> device;

    // power state
    std::unique_ptr<PowerCallbackEntry> powerCallback;
    PowerState readState;

    /*
     * A state machine to represent the current status of the MCTP connection.
     * In Reset state, the MCTP endpoint (EP) is not setup with the device.
     * In event of successful setup we move from Reset to Configured. If
     * opening the EP is successful from Configured the status will change to
     * Initiated. The status will change to Connected once the MTU of local
     * and device side MTU and frequency is optimized. In an event of connection
     * EP closure, the status will move back to Reset via Terminating.
     *
     * Transitions to the terminal state indicate a logic error.
     *
     * stateDiagram
     *   [*] --> Reset
     *
     *   Reset --> Reset: epReset()
     *   Reset --> [*]: epConnect()
     *   Reset --> [*]: epOptimize()
     *
     *   Initiated --> Terminating: epReset()
     *   Initiated --> Initiated: epConnect()
     *   Initiated --> Connected: epOptimize()
     *
     *   Connected --> Terminating: epReset()
     *   Connected --> Connected: epConnect()
     *   Connected --> Connected: epOptimize()
     *
     *   Terminating --> Reset: Reset close job executes
     *   Terminating --> Terminating: epReset()
     *   Terminating --> Terminating: epConnect()
     *   Terminating --> [*]: epOptimize()
     */
    enum class Status : uint8_t
    {
        Reset,
        Initiated,
        Connected,
        Terminating,
    };

    void epReset();
    bool epConnect(int lnid, uint8_t leid);
    void epOptimize();

    Status mctpStatus;
    std::shared_ptr<MctpEndpoint> endpoint;
    uint16_t mtu;
    nvme_mi_ep_t nvmeEP;
    // Handle a start() while in Status::Terminating on entry to Status::Reset.
    bool restart;
    std::shared_ptr<boost::asio::steady_timer> optimizeTimer;

    std::shared_ptr<NVMeMiWorker> worker;
    void post(std::function<void(void)>&& func);

    void
        miConfigureRemoteMCTP(uint8_t port, uint16_t mtu,
                              uint8_t maxSupportedFreq,
                              std::function<void(const std::error_code&)>&& cb);

    void miConfigureSMBusFrequency(
        uint8_t portId, uint8_t maxSupportedFreq,
        std::function<void(const std::error_code&)>&& cb);

    void miSetMCTPConfiguration(
        std::function<void(const std::error_code&)>&& cb);

    void configureLocalRouteMtu(
        std::function<void(const std::error_code& ec)>&& completed,
        int retries = 5);

    std::optional<std::error_code> isEndpointDegraded() const;

    bool readingStateGood() const
    {
        return ::readingStateGood(readState);
    }

    std::error_code tryPost(std::function<void(void)>&& func);

    void adminFwDownloadChunk(
        nvme_mi_ctrl_t ctrl, const std::string& firmwarefile, size_t size,
        size_t offset, int attemptCount,
        std::function<void(const std::error_code&, nvme_status_field)>&& cb);

    void getTelemetryLogChunk(
        nvme_mi_ctrl_t ctrl, bool host, uint64_t offset,
        std::vector<uint8_t>&& data,
        std::function<void(const std::error_code&, std::span<uint8_t>)>&& cb);

    static size_t getBlockSize(nvme_mi_ctrl_t ctrl, size_t lbaFormat);
};
