#include "NVMeController.hpp"

#include "dbus-sensor_config.h"

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

#include <boost/asio/async_result.hpp>
#include <boost/asio/spawn.hpp>
#include <phosphor-logging/lg2.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 <cstdint>
#include <cstdio>
#include <filesystem>
#include <fstream>
#include <system_error>
#include <tuple>
#include <vector>

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

inline std::optional<std::string> findPluginName(const SensorData& config)
{
    // find base configuration
    auto sensorBase = config.find(configInterfaceName(nvme::sensorType));
    if (sensorBase == config.end())
    {
        return {};
    }
    const SensorBaseConfigMap& sensorConfig = sensorBase->second;
    auto findPlugin = sensorConfig.find("Plugin");
    if (findPlugin == sensorConfig.end())
    {
        return std::nullopt;
    }
    return std::get<std::string>(findPlugin->second);
}

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)
        {
            lg2::error("Controller has been disabled");
            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)
        {
            lg2::error("Controller has been disabled");
            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)
        {
            lg2::error("Controller has been disabled");
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }

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

    if (this->featureLockdownEnabled)
    {
        lockdownInterface =
            objServer.add_interface(path, "xyz.openbmc_project.NVMe.Lockdown");

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

            if (self->status != Status::Enabled)
            {
                lg2::error("Controller has been disabled");
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    Unavailable();
            }

            return self->lockdownInbandMethod(std::move(yield), prohibit,
                                              adminCmds, features, logPages);
        });
        lockdownInterface->initialize();
    }

    // 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)
        {
            lg2::error("Controller has been disabled");
            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)
        {
            lg2::error("Controller has been disabled");
            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::initializeMetricStore()
{
    // if metric store feature is disabled then create empty metric store
    // the dbus interface will be there but with no metrics
    if (metricStoreFeature == MetricStoreFeature::Disabled)
    {
        this->metricStore.emplace(this->NVMeController::io,
                                  this->NVMeController::conn,
                                  this->NVMeController::path);
        return;
    }
    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,
        // Metigate solution before Knuckle FW fix for b/404610159
        std::chrono::seconds(60)));

    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 pluginName = findPluginName(config);
    auto hostTelemetry =
        (!pluginName || pluginName != "OCP")
            ? std::shared_ptr<HostTelemetryMetric>(new HostTelemetryMetric(
                  this->weak_from_this(), scheduler,
                  // TODO: configurable interval
                  std::chrono::duration_cast<SchedulerClockType::duration>(
                      std::chrono::seconds(900))))
            : std::shared_ptr<HostTelemetryMetric>();
    // 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));
}

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

    if (isPrimary)
    {
        this->initializeMetricStore();
    }
    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)
    {
        lg2::error("makeAssociation() after shutdown");
        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)
    {
        lg2::error("Controller has been disabled");
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    std::array<int, 2> pipe{};
    if (::pipe(pipe.data()) < 0)
    {
        lg2::error("GetLogPage fails to open pipe: {ERROR}", "ERROR",
                   strerror(errno));
        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)
            {
                lg2::error("fail to GetLogPage: {ERROR}", "ERROR",
                           ec.message());
                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)
                {
                    lg2::error("GetLogPage fails to write fd: {ERROR}", "ERROR",
                               error.message());
                }
            });

            // 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)
                {
                    lg2::error("fail to GetLogPage: {ERROR}", "ERROR",
                               ec.message());
                    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)
                    {
                        lg2::error("GetLogPage fails to write fd: {ERROR}",
                                   "ERROR", error.message());
                    }
                });

                // 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)
    {
        lg2::error("Controller has been disabled");
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    std::array<int, 2> pipe{};
    if (::pipe(pipe.data()) < 0)
    {
        lg2::error("Identify fails to open pipe: {ERROR}", "ERROR",
                   strerror(errno));
        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)
        {
            lg2::error("fail to Identify: {ERROR}", "ERROR", ex->what());
            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)
            {
                lg2::error("Identify fails to write fd: {ERROR}", "ERROR",
                           error.message());
            }
        });

        // 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)
    {
        lg2::error("Controller has been disabled");
        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);
    if (lockdownInterface)
    {
        objServer.remove_interface(lockdownInterface);
    }
    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,
    const SensorData& configData, std::shared_ptr<NVMeMiIntf> nvmeIntf,
    nvme_mi_ctrl_t ctrl, std::weak_ptr<NVMeSubsystem> subsys,
    bool enableFeatureLockdown) :
    isPrimary(true), io(io), objServer(objServer), conn(std::move(conn)),
    path(std::move(path)), config(configData), nvmeIntf(std::move(nvmeIntf)),
    nvmeCtrl(ctrl), subsys(std::move(subsys)),
    featureLockdownEnabled(enableFeatureLockdown)
{}

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)
    {
        lg2::error("Controller has been disabled");
        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)
    {
        lg2::error("Controller has been disabled");
        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);

    lg2::debug("nvme_status:{STATUS}, dw0:{DW0}", "STATUS", nvmeStatus, "DW0",
               completionDw0);
    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};
}

std::tuple<uint32_t, uint32_t, uint32_t, std::string, uint32_t>
    NVMeControllerEnabled::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)
{
    using callback_t =
        void(std::tuple<std::error_code, int, uint32_t, std::string, uint32_t>);

    auto [err, nvmeStatus, completionDw0, failureScope, failureId] =
        boost::asio::async_initiate<boost::asio::yield_context, callback_t>(
            [intf{nvmeIntf}, ctrl{nvmeCtrl}, prohibit, adminCmds, features,
             logPages](auto&& handler) {
        auto h = asio_helper::CopyableCallback(
            std::forward<decltype(handler)>(handler));

        intf->adminLockdownInband(ctrl, prohibit, adminCmds, features, logPages,
                                  [h](const std::error_code& err,
                                      int nvmeStatus, uint32_t completionDw0,
                                      const std::string& scope,
                                      uint32_t id) mutable {
            h(std::make_tuple(err, nvmeStatus, completionDw0, scope, id));
        });
    },
            yield);

    lg2::debug("NVMe command result: status={STATUS}, dw0={DW0}", "STATUS",
               nvmeStatus, "DW0", completionDw0);
    if (nvmeStatus < 0)
    {
        throw sdbusplus::exception::SdBusError(err.value(),
                                               "lockdownInbandMethod");
    }

    uint32_t miStatus = 0;
    uint32_t adminStatus = 0;
    if (nvme_status_get_type(nvmeStatus) == NVME_STATUS_TYPE_MI)
    {
        // If it's an MI status (e.g., protocol failure), Admin status is 0.
        miStatus = nvme_status_get_value(nvmeStatus);
        adminStatus = 0;
        completionDw0 = 0;
    }
    else
    {
        // If it's an Admin status (e.g., command failed on the drive), MI
        // status is 0.
        miStatus = 0;
        adminStatus = nvme_status_get_value(nvmeStatus);
    }

    // Returns the standardized tuple for the D-Bus client
    return {miStatus, adminStatus, completionDw0, failureScope, failureId};
}

void NVMeControllerEnabled::attachVolume(
    boost::asio::yield_context yield,
    const sdbusplus::message::object_path& volumePath)
{
    if (status != Status::Enabled)
    {
        lg2::error("Controller has been disabled");
        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)
            {
                lg2::error("{ERROR}", "ERROR", e.what());
                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)
    {
        lg2::error("Controller has been disabled");
        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)
            {
                lg2::error("{ERROR}", "ERROR", e.what());
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InternalFailure();
            }
        }
        updateAssociation();
    }
}
