#include "NVMeController.hpp"

#include "AsioHelper.hpp"
#include "NVMeCacheImpl.hpp"
#include "NVMeError.hpp"
#include "NVMePlugin.hpp"
#include "NVMeSubsys.hpp"

#include <sdbusplus/exception.hpp>
#include <sdbusplus/message/native_types.hpp>
#include <xyz/openbmc_project/Common/File/error.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

#include <cstdio>
#include <filesystem>
#include <fstream>
#include <iostream>

// using sdbusplus::xyz::openbmc_project::Inventory::Item::server::
//     StorageController;
using sdbusplus::xyz::openbmc_project::NVMe::server::NVMeAdmin;
using SchedulerClockType = std::chrono::steady_clock;

std::shared_ptr<NVMeControllerEnabled>
    NVMeControllerEnabled::create(NVMeController&& nvmeController)
{
    auto self = std::shared_ptr<NVMeControllerEnabled>(
        new NVMeControllerEnabled(std::move(nvmeController)));
    self->init();
    return self;
}

NVMeControllerEnabled::NVMeControllerEnabled(NVMeController&& nvmeController) :
    NVMeController(nvmeController),
    NVMeAdmin(*this->NVMeController::conn, this->NVMeController::path.c_str(),
              {{"FirmwareCommitStatus", {FwCommitStatus::Ready}},
               {"FirmwareDownloadStatus", {FwDownloadStatus::Ready}}}),
    SoftwareExtVersion(dynamic_cast<sdbusplus::bus_t&>(*conn), path.c_str()),
    SoftwareVersion(dynamic_cast<sdbusplus::bus_t&>(*conn), path.c_str())
{}

void NVMeControllerEnabled::init()
{
    createAssociation();

    passthruInterface =
        objServer.add_interface(path, "xyz.openbmc_project.NVMe.Passthru");

    passthruInterface->register_method(
        "AdminNonDataCmd",
        [selfWeak{weak_from_this()}](
            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) {
        auto self = selfWeak.lock();
        if (!self)
        {
            checkLibNVMeError(std::make_error_code(std::errc::no_such_device),
                              -1, "AdminNonDataCmd");
            return std::tuple<uint32_t, uint32_t, uint32_t>{0, 0, 0};
        }

        if (self->status != Status::Enabled)
        {
            std::cerr << "Controller has been disabled" << '\n';
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }
        return self->adminNonDataCmdMethod(std::move(yield), opcode, cdw1, cdw2,
                                           cdw3, cdw10, cdw11, cdw12, cdw13,
                                           cdw14, cdw15);
    });
    passthruInterface->initialize();

    securityInterface = objServer.add_interface(
        path, "xyz.openbmc_project.Inventory.Item.StorageControllerSecurity");
    securityInterface->register_method(
        "SecuritySend", [selfWeak{weak_from_this()}](
                            boost::asio::yield_context yield, uint8_t proto,
                            uint16_t protoSpecific, std::vector<uint8_t> data) {
        auto self = selfWeak.lock();
        if (!self)
        {
            checkLibNVMeError(std::make_error_code(std::errc::no_such_device),
                              -1, "SecuritySend");
            return;
        }

        if (self->status != Status::Enabled)
        {
            std::cerr << "Controller has been disabled" << '\n';
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }

        return self->securitySendMethod(std::move(yield), proto, protoSpecific,
                                        data);
    });
    securityInterface->register_method(
        "SecurityReceive",
        [selfWeak{weak_from_this()}](boost::asio::yield_context yield,
                                     uint8_t proto, uint16_t protoSpecific,
                                     uint32_t transferLength) {
        auto self = selfWeak.lock();
        if (!self)
        {
            checkLibNVMeError(std::make_error_code(std::errc::no_such_device),
                              -1, "SecurityReceive");
            return std::vector<uint8_t>{};
        }

        if (self->status != Status::Enabled)
        {
            std::cerr << "Controller has been disabled" << '\n';
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }

        return self->securityReceiveMethod(std::move(yield), proto,
                                           protoSpecific, transferLength);
    });

    // StorageController interface is implemented manually to allow
    // async methods
    ctrlInterface = objServer.add_interface(
        path, "xyz.openbmc_project.Inventory.Item.StorageController");
    ctrlInterface->register_method(
        "AttachVolume", [selfWeak{weak_from_this()}](
                            boost::asio::yield_context yield,
                            const sdbusplus::message::object_path& volPath) {
        auto self = selfWeak.lock();
        if (!self)
        {
            checkLibNVMeError(std::make_error_code(std::errc::no_such_device),
                              -1, "SecurityReceive");
            return;
        }

        if (self->status != Status::Enabled)
        {
            std::cerr << "Controller has been disabled" << '\n';
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }

        return self->attachVolume(std::move(yield), volPath);
    });
    ctrlInterface->register_method(
        "DetachVolume", [selfWeak{weak_from_this()}](
                            boost::asio::yield_context yield,
                            const sdbusplus::message::object_path& volPath) {
        auto self = selfWeak.lock();
        if (!self)
        {
            checkLibNVMeError(std::make_error_code(std::errc::no_such_device),
                              -1, "SecurityReceive");
            return;
        }

        if (self->status != Status::Enabled)
        {
            std::cerr << "Controller has been disabled" << '\n';
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }

        return self->detachVolume(std::move(yield), volPath);
    });

    ctrlInterface->initialize();

    securityInterface->initialize();
    // StorageController::emit_added();

    NVMeAdmin::emit_added();
    SoftwareExtVersion::emit_added();
    SoftwareVersion::emit_added();
}

void NVMeControllerEnabled::start(
    const std::shared_ptr<NVMeControllerPlugin>& nvmePlugin)
{
    this->NVMeController::start(nvmePlugin);

    // only to test compilation. need to remove.
    this->metricStore.emplace(this->NVMeController::io,
                              this->NVMeController::conn,
                              this->NVMeController::path);

    auto scheduler = Scheduler<SchedulerClockType>::getScheduler(path);

    using IdentifyMetric =
        IdentifyMetric<NVME_IDENTIFY_CNS_CTRL, SchedulerClockType>;

    using ErrorInfoMetric =
        ControllerLogPageMetric<NVME_LOG_LID_ERROR, SchedulerClockType>;
    using SMARTMetric =
        ControllerLogPageMetric<NVME_LOG_LID_SMART, SchedulerClockType>;
    using FwSlotMetric =
        ControllerLogPageMetric<NVME_LOG_LID_FW_SLOT, SchedulerClockType>;
    using SelfTestMetric =
        ControllerLogPageMetric<NVME_LOG_LID_DEVICE_SELF_TEST,
                                SchedulerClockType>;
    using HostTelemetryMetric =
        ControllerLogPageMetric<NVME_LOG_LID_TELEMETRY_HOST,
                                SchedulerClockType>;

    // NOLINTBEGIN(modernize-make-shared)
    auto identify = std::shared_ptr<IdentifyMetric>(
        new IdentifyMetric(this->shared_from_this(), scheduler,
                           // Identify info is persist throughout the controller
                           // lifecycle i.e. from start() to stop()
                           IdentifyMetric::ClockType::duration::max()));

    auto errorInfo = std::shared_ptr<ErrorInfoMetric>(new ErrorInfoMetric(
        this->weak_from_this(), scheduler,
        // TODO: configurable interval
        std::chrono::duration_cast<SchedulerClockType::duration>(
            std::chrono::seconds(60))));

    auto smart = std::shared_ptr<SMARTMetric>(new SMARTMetric(
        this->weak_from_this(), scheduler,
        // TODO: configurable interval
        std::chrono::duration_cast<SchedulerClockType::duration>(
            std::chrono::seconds(60))));

    auto fwSlot = std::shared_ptr<FwSlotMetric>(new FwSlotMetric(
        this->weak_from_this(), scheduler,
        // TODO: configurable interval
        std::chrono::duration_cast<SchedulerClockType::duration>(
            std::chrono::seconds(60))));

    auto selfTest = std::shared_ptr<SelfTestMetric>(new SelfTestMetric(
        this->weak_from_this(), scheduler,
        // TODO: configurable interval
        std::chrono::duration_cast<SchedulerClockType::duration>(
            std::chrono::seconds(60))));

    auto hostTelemetry =
        std::shared_ptr<HostTelemetryMetric>(new HostTelemetryMetric(
            this->weak_from_this(), scheduler,
            // TODO: configurable interval
            std::chrono::duration_cast<SchedulerClockType::duration>(
                std::chrono::seconds(900))));
    // NOLINTEND(modernize-make-shared)

    this->metricStore.emplace(
        this->NVMeController::io, this->NVMeController::conn,
        this->NVMeController::path, std::move(identify), std::move(errorInfo),
        std::move(smart), std::move(fwSlot), std::move(selfTest),
        std::move(hostTelemetry));

    status = Status::Enabled;
}

void NVMeControllerEnabled::stop()
{
    status = Status::Disabled;
    this->metricStore.reset();
}

void NVMeController::createAssociation()
{
    assocIntf = objServer.add_interface(path, association::interface);
    assocIntf->register_property("Associations", makeAssociation());
    assocIntf->initialize();
}

void NVMeController::updateAssociation()
{
    if (assocIntf)
    {
        assocIntf->set_property("Associations", makeAssociation());
    }
}

std::vector<Association> NVMeController::makeAssociation() const
{
    std::vector<Association> associations;
    std::filesystem::path p(path);

    auto s = subsys.lock();
    if (!s)
    {
        std::cerr << "makeAssociation() after shutdown\n";
        return associations;
    }

    associations.emplace_back("storage", "storage_controller", s->path);

    for (const auto& cntrl : secondaryControllers)
    {
        associations.emplace_back("secondary", "primary", cntrl);
    }

    for (uint32_t nsid : s->attachedVolumes(getCntrlId()))
    {
        auto p = s->volumePath(nsid);
        associations.emplace_back("attaching", "attached", p);
    }

    return associations;
}

sdbusplus::message::unix_fd NVMeControllerEnabled::getLogPage(uint8_t lid,
                                                              uint32_t nsid,
                                                              uint8_t lsp,
                                                              uint16_t lsi)
{
    if (status != Status::Enabled)
    {
        std::cerr << "Controller has been disabled" << '\n';
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    std::array<int, 2> pipe{};
    if (::pipe(pipe.data()) < 0)
    {
        std::cerr << "GetLogPage fails to open pipe: " << std::strerror(errno)
                  << '\n';
        throw sdbusplus::xyz::openbmc_project::Common::File::Error::Open();
    }

    // standard NVMe Log IDs
    if (lid < uint8_t{0xC0})
    {
        nvmeIntf->adminGetLogPage(
            nvmeCtrl, static_cast<nvme_cmd_get_log_lid>(lid), nsid, lsp, lsi,
            [pipe, &io = this->io](const std::error_code& ec,
                                   std::span<uint8_t> data) {
            if (ec)
            {
                std::cerr << "fail to GetLogPage: " << ec.message() << '\n';
                close(pipe[1]);
                close(pipe[0]);
                return;
            }

            // async write to pipe
            auto asyncPipe =
                std::make_shared<boost::asio::posix::stream_descriptor>(
                    io, pipe[1]);
            std::weak_ptr<boost::asio::posix::stream_descriptor> weakPipe =
                asyncPipe;

            auto asyncBuffer = std::make_shared<std::vector<uint8_t>>(
                data.begin(), data.end());
            boost::asio::async_write(
                *asyncPipe, boost::asio::buffer(*asyncBuffer),
                [asyncPipe, asyncBuffer](const boost::system::error_code& error,
                                         std::size_t /* transferredSize */) {
                if (error)
                {
                    std::cerr
                        << "GetLogPage fails to write fd: " << error.message()
                        << '\n';
                }
            });

            // set a timer of 5 second for the client to read the telemetry.
            auto timer = std::make_shared<boost::asio::steady_timer>(io);
            timer->expires_after(std::chrono::seconds(5));
            timer->async_wait([timer, fd{pipe[0]}, weakPipe](
                                  const boost::system::error_code& /* ec */) {
                auto pipe = weakPipe.lock();
                if (pipe)
                {
                    pipe->cancel();
                }
                close(fd);
            });
        });
    }
    // vendor Log IDs
    else if (!plugin.expired())
    {
        auto nvmePlugin = plugin.lock();
        auto handler = nvmePlugin->getGetLogPageHandler();
        if (handler)
        {
            std::function<void(const std::error_code&, std::span<uint8_t>)> cb =
                [pipe, &io = this->io](std::error_code ec,
                                       std::span<uint8_t> data) {
                if (ec)
                {
                    std::cerr << "fail to GetLogPage: " << ec.message() << '\n';
                    close(pipe[1]);
                    close(pipe[0]);
                    return;
                }

                // async write to pipe
                auto asyncPipe =
                    std::make_shared<boost::asio::posix::stream_descriptor>(
                        io, pipe[1]);
                std::weak_ptr<boost::asio::posix::stream_descriptor> weakPipe =
                    asyncPipe;

                auto asyncBuffer = std::make_shared<std::vector<uint8_t>>(
                    data.begin(), data.end());
                boost::asio::async_write(
                    *asyncPipe, boost::asio::buffer(*asyncBuffer),
                    [asyncPipe,
                     asyncBuffer](const boost::system::error_code& error,
                                  std::size_t /* transferredSize */) {
                    if (error)
                    {
                        std::cerr << "GetLogPage fails to write fd: "
                                  << error.message() << '\n';
                    }
                });

                // set a timer of 5 second for the client to read the telemetry.
                auto timer = std::make_shared<boost::asio::steady_timer>(io);
                timer->expires_after(std::chrono::seconds(5));
                timer->async_wait(
                    [timer, fd{pipe[0]},
                     weakPipe](const boost::system::error_code& /* ec */) {
                    auto pipe = weakPipe.lock();
                    if (pipe)
                    {
                        pipe->cancel();
                    }
                    close(fd);
                });
            };
            handler(lid, nsid, lsp, lsi, std::move(cb));
        }
        else // No VU LogPage handler
        {
            close(pipe[1]);
            close(pipe[0]);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }
    }
    else // No VU plugin
    {
        close(pipe[0]);
        close(pipe[1]);
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }
    return sdbusplus::message::unix_fd{pipe[0]};
}

sdbusplus::message::unix_fd
    NVMeControllerEnabled::identify(uint8_t cns, uint32_t nsid, uint16_t cntid)
{
    if (status != Status::Enabled)
    {
        std::cerr << "Controller has been disabled" << '\n';
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    std::array<int, 2> pipe{};
    if (::pipe(pipe.data()) < 0)
    {
        std::cerr << "Identify fails to open pipe: " << std::strerror(errno)
                  << '\n';
        throw sdbusplus::xyz::openbmc_project::Common::File::Error::Open();
    }

    nvmeIntf->adminIdentify(
        nvmeCtrl, static_cast<nvme_identify_cns>(cns), nsid, cntid,
        [pipe, &io = this->io](const nvme_ex_ptr& ex, std::span<uint8_t> data) {
        if (ex)
        {
            std::cerr << "fail to Identify: " << ex << '\n';
            close(pipe[1]);
            close(pipe[0]);
            return;
        }

        // async write to pipe
        auto asyncPipe =
            std::make_shared<boost::asio::posix::stream_descriptor>(io,
                                                                    pipe[1]);
        std::weak_ptr<boost::asio::posix::stream_descriptor> weakPipe =
            asyncPipe;

        auto asyncBuffer = std::make_shared<std::vector<uint8_t>>(data.begin(),
                                                                  data.end());
        boost::asio::async_write(
            *asyncPipe, boost::asio::buffer(*asyncBuffer),
            [asyncPipe, asyncBuffer](const boost::system::error_code& error,
                                     std::size_t /* transferredSize */) {
            if (error)
            {
                std::cerr << "Identify fails to write fd: " << error.message()
                          << '\n';
            }
        });

        // set a timer of 5 second for the client to read the telemetry.
        auto timer = std::make_shared<boost::asio::steady_timer>(io);
        timer->expires_after(std::chrono::seconds(5));
        timer->async_wait([timer, fd{pipe[0]}, weakPipe](
                              const boost::system::error_code& /* ec */) {
            auto pipe = weakPipe.lock();
            if (pipe)
            {
                pipe->cancel();
            }
            close(fd);
        });
    });
    return sdbusplus::message::unix_fd{pipe[0]};
}

NVMeAdmin::FwCommitStatus NVMeControllerEnabled::firmwareCommitStatus(
    NVMeAdmin::FwCommitStatus status)
{
    auto commitStatus = this->NVMeAdmin::firmwareCommitStatus();
    // The function is only allowed to reset the status back to ready
    if (status != FwCommitStatus::Ready ||
        commitStatus == FwCommitStatus::Ready ||
        commitStatus == FwCommitStatus::InProgress)
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed{};
    }
    return this->NVMeAdmin::firmwareCommitStatus(status);
}

void NVMeControllerEnabled::firmwareCommitAsync(uint8_t commitAction,
                                                uint8_t firmwareSlot, bool bpid)
{
    auto commitStatus = this->NVMeAdmin::firmwareCommitStatus();
    if (commitStatus != FwCommitStatus::Ready)
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed();
    }

    if (status != Status::Enabled)
    {
        std::cerr << "Controller has been disabled" << '\n';
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    this->NVMeAdmin::firmwareCommitStatus(FwCommitStatus::InProgress);
    nvmeIntf->adminFwCommit(
        nvmeCtrl, static_cast<nvme_fw_commit_ca>(commitAction & 0b111),
        firmwareSlot, bpid,
        [self{shared_from_this()}](const std::error_code& ec,
                                   nvme_status_field status) {
        if (ec)
        {
            self->NVMeAdmin::firmwareCommitStatus(FwCommitStatus::Failed);
            return;
        }
        if (status != NVME_SC_SUCCESS)
        {
            self->NVMeAdmin::firmwareCommitStatus(FwCommitStatus::RequireReset);
            return;
        }

        self->NVMeAdmin::firmwareCommitStatus(FwCommitStatus::Success);
    });
}

NVMeAdmin::FwDownloadStatus NVMeControllerEnabled::firmwareDownloadStatus(
    NVMeAdmin::FwDownloadStatus status)
{
    auto downloadStatus = this->NVMeAdmin::firmwareDownloadStatus();
    // The function is only allowed to reset the status back to ready
    if (status != FwDownloadStatus::Ready ||
        downloadStatus == FwDownloadStatus::Ready ||
        downloadStatus == FwDownloadStatus::InProgress)
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed{};
    }
    return this->NVMeAdmin::firmwareDownloadStatus(status);
}

void NVMeControllerEnabled::firmwareDownloadAsync(std::string pathToImage)
{
    auto downloadStatus = this->NVMeAdmin::firmwareDownloadStatus();
    if (downloadStatus != FwDownloadStatus::Ready)
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed();
    }
    if (std::filesystem::exists(pathToImage))
    {
        this->NVMeAdmin::firmwareDownloadStatus(FwDownloadStatus::InProgress);
        nvmeIntf->adminFwDownload(
            nvmeCtrl, pathToImage,
            [self{shared_from_this()}](const std::error_code& ec,
                                       nvme_status_field status) {
            if (ec || status != NVME_SC_SUCCESS)
            {
                self->NVMeAdmin::firmwareDownloadStatus(
                    FwDownloadStatus::Failed);
                return;
            }
            self->NVMeAdmin::firmwareDownloadStatus(FwDownloadStatus::Success);
        });
    }
    else
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }
}

NVMeControllerEnabled::~NVMeControllerEnabled()
{
    objServer.remove_interface(securityInterface);
    objServer.remove_interface(passthruInterface);
    SoftwareVersion::emit_removed();
    SoftwareExtVersion::emit_removed();
    NVMeAdmin::emit_removed();
    // StorageController::emit_removed();
    objServer.remove_interface(ctrlInterface);
}

NVMeController::NVMeController(
    boost::asio::io_context& io, sdbusplus::asio::object_server& objServer,
    std::shared_ptr<sdbusplus::asio::connection> conn, std::string path,
    std::shared_ptr<NVMeMiIntf> nvmeIntf, nvme_mi_ctrl_t ctrl,
    std::weak_ptr<NVMeSubsystem> subsys) :
    isPrimary(true), io(io), objServer(objServer), conn(std::move(conn)),
    path(std::move(path)), nvmeIntf(std::move(nvmeIntf)), nvmeCtrl(ctrl),
    subsys(std::move(subsys))
{}

NVMeController::~NVMeController()
{
    objServer.remove_interface(assocIntf);
}

void NVMeController::start(
    const std::shared_ptr<NVMeControllerPlugin>& nvmePlugin)
{
    plugin = nvmePlugin;
}

void NVMeController::stop() {}

void NVMeController::setSecAssoc(
    const std::vector<std::shared_ptr<NVMeController>>& secCntrls)
{
    secondaryControllers.clear();

    if (secCntrls.empty())
    {
        return;
    }

    for (const auto& cntrl : secCntrls)
    {
        secondaryControllers.push_back(cntrl->path);
    }
    updateAssociation();
}

void NVMeControllerEnabled::securitySendMethod(boost::asio::yield_context yield,
                                               uint8_t proto,
                                               uint16_t protoSpecific,
                                               std::span<uint8_t> data)
{
    if (status != Status::Enabled)
    {
        std::cerr << "Controller has been disabled" << '\n';
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    using callback_t = void(std::tuple<std::error_code, int>);
    auto [err, nvmeStatus] =
        boost::asio::async_initiate<boost::asio::yield_context, callback_t>(
            [intf{nvmeIntf}, ctrl{nvmeCtrl}, proto, protoSpecific,
             &data](auto&& handler) {
        auto h = asio_helper::CopyableCallback(
            std::forward<decltype(handler)>(handler));

        intf->adminSecuritySend(
            ctrl, proto, protoSpecific, data,
            [h](const std::error_code& err, int nvmeStatus) mutable {
            h(std::make_tuple(err, nvmeStatus));
        });
    },
            yield);

    // exception must be thrown outside of the async block
    checkLibNVMeError(err, nvmeStatus, "SecuritySend");
}

std::vector<uint8_t> NVMeControllerEnabled::securityReceiveMethod(
    boost::asio::yield_context yield, uint8_t proto, uint16_t protoSpecific,
    uint32_t transferLength)
{
    if (status != Status::Enabled)
    {
        std::cerr << "Controller has been disabled" << '\n';
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    using callback_t =
        void(std::tuple<std::error_code, int, std::vector<uint8_t>>);
    auto [err, nvmeStatus, data] =
        boost::asio::async_initiate<boost::asio::yield_context, callback_t>(
            [intf{nvmeIntf}, ctrl{nvmeCtrl}, proto, protoSpecific,
             transferLength](auto&& handler) {
        auto h = asio_helper::CopyableCallback(
            std::forward<decltype(handler)>(handler));

        intf->adminSecurityReceive(ctrl, proto, protoSpecific, transferLength,
                                   [h](const std::error_code& err,
                                       int nvmeStatus,
                                       std::span<uint8_t> data) mutable {
            std::vector<uint8_t> d(data.begin(), data.end());
            h(std::make_tuple(err, nvmeStatus, d));
        });
    },
            yield);

    // exception must be thrown outside of the async block
    checkLibNVMeError(err, nvmeStatus, "SecurityReceive");
    return data;
}

std::tuple<uint32_t, uint32_t, uint32_t>
    NVMeControllerEnabled::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)
{
    using callback_t = void(std::tuple<std::error_code, int, uint32_t>);
    auto [err, nvmeStatus, completionDw0] =
        boost::asio::async_initiate<boost::asio::yield_context, callback_t>(
            [intf{nvmeIntf}, ctrl{nvmeCtrl}, opcode, cdw1, cdw2, cdw3, cdw10,
             cdw11, cdw12, cdw13, cdw14, cdw15](auto&& handler) {
        auto h = asio_helper::CopyableCallback(
            std::forward<decltype(handler)>(handler));

        intf->adminNonDataCmd(ctrl, opcode, cdw1, cdw2, cdw3, cdw10, cdw11,
                              cdw12, cdw13, cdw14, cdw15,
                              [h](const std::error_code& err, int nvmeStatus,
                                  uint32_t completionDw0) mutable {
            h(std::make_tuple(err, nvmeStatus, completionDw0));
        });
    },
            yield);

    std::cerr << "nvme_status:" << nvmeStatus << ", dw0:" << completionDw0
              << '\n';
    if (nvmeStatus < 0)
    {
        throw sdbusplus::exception::SdBusError(err.value(),
                                               "adminNonDataCmdMethod");
    }

    // Parse MI status Or MI status from nvme_status
    uint32_t miStatus = 0;
    uint32_t adminStatus = 0;
    if (nvme_status_get_type(nvmeStatus) == NVME_STATUS_TYPE_MI)
    {
        // there is no Admin status and dw0 if MI layer failed.
        miStatus = nvme_status_get_value(nvmeStatus);
        adminStatus = 0;
        completionDw0 = 0;
    }
    else
    {
        miStatus = 0;
        adminStatus = nvme_status_get_value(nvmeStatus);
    }
    return {miStatus, adminStatus, completionDw0};
}

void NVMeControllerEnabled::attachVolume(
    boost::asio::yield_context yield,
    const sdbusplus::message::object_path& volumePath)
{
    if (status != Status::Enabled)
    {
        std::cerr << "Controller has been disabled" << '\n';
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    uint32_t nsid = 0;
    if (auto s = subsys.lock())
    {
        auto vol = s->getVolume(volumePath);
        if (!vol)
        {
            throw sdbusplus::exception::SdBusError(ENOENT, "attachVolume");
        }
        nsid = vol->namespaceId();
    }
    else
    {
        return;
    }

    using callback_t = void(std::tuple<std::error_code, int>);
    uint16_t ctrlid = getCntrlId();
    auto [err, nvmeStatus] =
        boost::asio::async_initiate<boost::asio::yield_context, callback_t>(
            [intf{nvmeIntf}, ctrl{nvmeCtrl}, ctrlid, nsid](auto&& handler) {
        auto h = asio_helper::CopyableCallback(
            std::forward<decltype(handler)>(handler));

        intf->adminAttachDetachNamespace(
            ctrl, ctrlid, nsid, true,
            [h](const std::error_code& err, int nvmeStatus) mutable {
            h(std::make_tuple(err, nvmeStatus));
        });
    }, yield);

    // exception must be thrown outside of the async block
    checkLibNVMeError(err, nvmeStatus, "attachVolume");

    if (status == Status::Enabled)
    {
        if (auto s = subsys.lock())
        {
            try
            {
                s->attachCtrlVolume(getCntrlId(), nsid);
            }
            catch (const std::exception& e)
            {
                std::cerr << e.what() << '\n';
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InternalFailure();
            }
        }
        updateAssociation();
    }
}

void NVMeControllerEnabled::detachVolume(
    boost::asio::yield_context yield,
    const sdbusplus::message::object_path& volumePath)
{
    if (status != Status::Enabled)
    {
        std::cerr << "Controller has been disabled" << '\n';
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    uint32_t nsid = 0;
    if (auto s = subsys.lock())
    {
        auto vol = s->getVolume(volumePath);
        if (!vol)
        {
            throw sdbusplus::exception::SdBusError(ENOENT, "detachVolume");
        }
        nsid = vol->namespaceId();
    }
    else
    {
        return;
    }

    using callback_t = void(std::tuple<std::error_code, int>);
    uint16_t ctrlid = getCntrlId();
    auto [err, nvmeStatus] =
        boost::asio::async_initiate<boost::asio::yield_context, callback_t>(
            [intf{nvmeIntf}, ctrl{nvmeCtrl}, ctrlid, nsid](auto&& handler) {
        auto h = asio_helper::CopyableCallback(
            std::forward<decltype(handler)>(handler));

        intf->adminAttachDetachNamespace(
            ctrl, ctrlid, nsid, false,
            [h](const std::error_code& err, int nvmeStatus) mutable {
            h(std::make_tuple(err, nvmeStatus));
        });
    }, yield);

    // exception must be thrown outside of the async block
    checkLibNVMeError(err, nvmeStatus, "detachVolume");

    if (status == Status::Enabled)
    {
        if (auto s = subsys.lock())
        {
            try
            {
                s->detachCtrlVolume(getCntrlId(), nsid);
            }
            catch (const std::exception& e)
            {
                std::cerr << e.what() << '\n';
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InternalFailure();
            }
        }
        updateAssociation();
    }
}
