#include "NVMeController.hpp"

#include "dbus-sensor_config.h"

#include "AsioHelper.hpp"
#include "NVMeCacheImpl.hpp"
#include "NVMeError.hpp"
#include "NVMePlugin.hpp"
#include "NVMeSubsys.hpp"
#include "Utils.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 <xyz/openbmc_project/NVMe/Format/server.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;

constexpr uint32_t kMinNvmeVerLogLid00hSupport = 0x020000;
constexpr int kDiscoverLogsMaxRetries =
    6; // exponentially backoff ~6.3s (100ms to 3.2s)
constexpr int kDiscoverLogsBaseBackoffMs = 100;
constexpr uint64_t kDefaultDA1IntervalSeconds = 60;
constexpr uint64_t kDefaultDAIntervalSeconds = 86400;

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

inline std::vector<std::string> findHostInitiatedLog(const SensorData& config)
{
    auto sensorBase = config.find(configInterfaceName(nvme::sensorType));
    if (sensorBase == config.end())
    {
        return {};
    }
    const SensorBaseConfigMap& sensorConfig = sensorBase->second;
    auto findHostInitLog = sensorConfig.find("HostInitiatedLog");
    if (findHostInitLog == sensorConfig.end())
    {
        return {};
    }
    if (std::holds_alternative<std::vector<std::string>>(
            findHostInitLog->second))
    {
        return std::get<std::vector<std::string>>(findHostInitLog->second);
    }
    return {};
}

inline std::optional<uint64_t> findDAPollingRate(const SensorData& config,
                                                 const std::string& key)
{
    auto sensorBase = config.find(configInterfaceName(nvme::sensorType));
    if (sensorBase == config.end())
    {
        return {};
    }
    const SensorBaseConfigMap& sensorConfig = sensorBase->second;
    auto findRate = sensorConfig.find(key);
    if (findRate == sensorConfig.end())
    {
        return {};
    }

    if (std::holds_alternative<uint64_t>(findRate->second))
    {
        return std::get<uint64_t>(findRate->second);
    }
    if (std::holds_alternative<double>(findRate->second))
    {
        return static_cast<uint64_t>(std::get<double>(findRate->second));
    }
    if (std::holds_alternative<uint32_t>(findRate->second))
    {
        return std::get<uint32_t>(findRate->second);
    }

    return {};
}

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("[{PATH}]Controller has been disabled", "PATH",
                       self->path);
            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("[{PATH}]Controller has been disabled", "PATH",
                       self->path);
            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("[{PATH}]Controller has been disabled", "PATH",
                       self->path);
            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("[{PATH}]Controller has been disabled", "PATH",
                           self->path);
                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("[{PATH}]Controller has been disabled", "PATH",
                       self->path);
            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("[{PATH}]Controller has been disabled", "PATH",
                       self->path);
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }

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

    ctrlInterface->initialize();

    nvmeControllerInterface =
        objServer.add_interface(path, "xyz.openbmc_project.Nvme.Controller");
    nvmeControllerInterface->register_method(
        "Format", [selfWeak{weak_from_this()}](
                      boost::asio::yield_context yield, uint8_t lbaFormat,
                      sdbusplus::xyz::openbmc_project::NVMe::server::Format::
                          SecureEraseSetting secureEraseSetting,
                      sdbusplus::xyz::openbmc_project::NVMe::server::Format::
                          DataProtectionType dataProtectionType) {
        auto self = selfWeak.lock();
        if (!self)
        {
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }
        if (self->status != Status::Enabled)
        {
            lg2::error("Controller has been disabled");
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }
        if (auto s = self->subsys.lock())
        {
            uint8_t fna = s->getFna();
            using SecureEraseSetting = sdbusplus::xyz::openbmc_project::NVMe::
                server::Format::SecureEraseSetting;
            if (((fna & nvme::fna::fmtAllRestriction) != 0) ||
                (((fna & nvme::fna::secureEraseAllRestriction) != 0) &&
                 secureEraseSetting != SecureEraseSetting::None))
            {
                lg2::error(
                    "Controller level format is not allowed based on FNA Bit 0 or Bit 1 restrictions");
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    NotAllowed();
            }
            s->formatController(std::move(yield), lbaFormat, secureEraseSetting,
                                dataProtectionType, self->getCntrlId());
        }
        else
        {
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }
    });

    nvmeControllerInterface->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 (!isMetricStoreEnabled())
    {
        this->metricStore.emplace(this->NVMeController::io,
                                  this->NVMeController::conn,
                                  this->NVMeController::path);
        return;
    }

    lg2::info("[{PATH}] NVMe version for controller: {VERSION}", "PATH", path,
              "VERSION", lg2::hex, nvmeVersion);

    discoverSupportedLogPages();
}

void NVMeControllerEnabled::populateMetricStore()
{
    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>;
    using HostTelemetryMetricDA1 =
        ControllerLogPageMetric<NVME_LOG_LID_TELEMETRY_HOST, SchedulerClockType,
                                1>;
    using HostTelemetryMetricDA2 =
        ControllerLogPageMetric<NVME_LOG_LID_TELEMETRY_HOST, SchedulerClockType,
                                2>;
    using HostTelemetryMetricDA3 =
        ControllerLogPageMetric<NVME_LOG_LID_TELEMETRY_HOST, SchedulerClockType,
                                3>;
    using HostTelemetryMetricDA4 =
        ControllerLogPageMetric<NVME_LOG_LID_TELEMETRY_HOST, SchedulerClockType,
                                4>;
    using LockdownMetric =
        ControllerLogPageMetric<NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN,
                                SchedulerClockType>;

    auto defaultLogpageRefreshDuration =
        std::chrono::duration_cast<SchedulerClockType::duration>(
            std::chrono::seconds(60));

    auto identify = std::make_shared<IdentifyMetric>(
        shared_from_this(), scheduler,
        // Mitigate solution before Knuckle FW fix for b/404610159
        defaultLogpageRefreshDuration);

    std::list<std::shared_ptr<MetricBase<SchedulerClockType>>> metrics;
    metrics.push_back(identify);

    // Standard core metrics are statically supported across all NVMe versions
    metrics.push_back(std::make_shared<ErrorInfoMetric>(
        this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
    metrics.push_back(std::make_shared<SMARTMetric>(
        this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
    metrics.push_back(std::make_shared<FwSlotMetric>(
        this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
    metrics.push_back(std::make_shared<SelfTestMetric>(
        this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));

    auto pluginName = findPluginName(config);
    bool isOcp = pluginName == "OCP";
    auto hostInitLog = findHostInitiatedLog(config);

    if (!isOcp)
    {
        metrics.push_back(std::make_shared<HostTelemetryMetric>(
            this->weak_from_this(), scheduler,
            std::chrono::duration_cast<SchedulerClockType::duration>(
                std::chrono::seconds(900))));
    }

    for (const auto& dataArea : hostInitLog)
    {
        std::string configKey = "HostInitiatedLog" + dataArea + "Interval";
        auto rateOpt = findDAPollingRate(config, configKey);
        uint64_t durationSec = rateOpt.value_or(0);
        if (durationSec == 0)
        {
            durationSec = (dataArea == "DA1") ? kDefaultDA1IntervalSeconds
                                              : kDefaultDAIntervalSeconds;
        }

        if (dataArea == "DA1")
        {
            lg2::debug("{PATH}: applied polling interval {DURATION}s for DA1",
                       "PATH", path, "DURATION", durationSec);
            metrics.push_back(std::make_shared<HostTelemetryMetricDA1>(
                this->weak_from_this(), scheduler,
                std::chrono::duration_cast<SchedulerClockType::duration>(
                    std::chrono::seconds(durationSec))));
        }
        else if (dataArea == "DA2")
        {
            lg2::debug("{PATH}: applied polling interval {DURATION}s for DA2",
                       "PATH", path, "DURATION", durationSec);
            metrics.push_back(std::make_shared<HostTelemetryMetricDA2>(
                this->weak_from_this(), scheduler,
                std::chrono::duration_cast<SchedulerClockType::duration>(
                    std::chrono::seconds(durationSec))));
        }
        else if (dataArea == "DA3")
        {
            lg2::debug("{PATH}: applied polling interval {DURATION}s for DA3",
                       "PATH", path, "DURATION", durationSec);
            metrics.push_back(std::make_shared<HostTelemetryMetricDA3>(
                this->weak_from_this(), scheduler,
                std::chrono::duration_cast<SchedulerClockType::duration>(
                    std::chrono::seconds(durationSec))));
        }
        else if (dataArea == "DA4")
        {
            lg2::debug("{PATH}: applied polling interval {DURATION}s for DA4",
                       "PATH", path, "DURATION", durationSec);
            metrics.push_back(std::make_shared<HostTelemetryMetricDA4>(
                this->weak_from_this(), scheduler,
                std::chrono::duration_cast<SchedulerClockType::duration>(
                    std::chrono::seconds(durationSec))));
        }
    }

    // Command Lockdown (Log Page 14h) is dynamically registered only on
    // NVMe 2.0+ controllers that explicitly report support via Supported Log
    // Pages (00h) check.
    if (isLogPageSupported(NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN))
    {
        metrics.push_back(std::make_shared<LockdownMetric>(
            this->weak_from_this(), scheduler, defaultLogpageRefreshDuration));
    }

    this->metricStore.emplace(
        this->NVMeController::io, this->NVMeController::conn,
        this->NVMeController::path, metrics.begin(), metrics.end());
}

void NVMeControllerEnabled::discoverSupportedLogPages()
{
    if (nvmeVersion < kMinNvmeVerLogLid00hSupport)
    {
        populateMetricStore();
        return;
    }

    lg2::info(
        "[{PATH}] Querying Supported Log Pages (00h) for NVMe 2.0+ controller",
        "PATH", path);

    discoverLogsToken = std::make_shared<bool>();
    std::weak_ptr<bool> weakToken = discoverLogsToken;

    fetchSupportedLogPages(0, weakToken);
}

void NVMeControllerEnabled::fetchSupportedLogPages(
    int retryCount, const std::weak_ptr<bool>& weakToken)
{
    std::weak_ptr<NVMeControllerEnabled> weakSelf = weak_from_this();

    nvmeIntf->adminGetLogPage(
        nvmeCtrl, NVME_LOG_LID_SUPPORTED_LOG_PAGES, NVME_NSID_NONE, 0, 0,
        [weakSelf, retryCount, weakToken, path = this->path](
            const std::error_code& ec, std::span<uint8_t> data) mutable {
        auto self = weakSelf.lock();
        if (!self || weakToken.expired())
        {
            lg2::info(
                "[{PATH}]Skipping fetchSupportedLogPages as token expired "
                "or controller destroyed",
                "PATH", path);
            return;
        }

        if (ec)
        {
            if (retryCount < kDiscoverLogsMaxRetries)
            {
                // Adaptive timer: exponential backoff
                int discoverLogsBackoffMs = kDiscoverLogsBaseBackoffMs
                                            << retryCount;
                self->discoverLogsRetryTimer =
                    std::make_shared<boost::asio::steady_timer>(self->io);
                self->discoverLogsRetryTimer->expires_after(
                    std::chrono::milliseconds(discoverLogsBackoffMs));
                self->discoverLogsRetryTimer->async_wait(
                    [weakSelf, retryCount, weakToken,
                     path](const boost::system::error_code& timerEc) {
                    auto self = weakSelf.lock();
                    if (!self || weakToken.expired() ||
                        timerEc == boost::asio::error::operation_aborted)
                    {
                        lg2::info(
                            "[{PATH}]Skipping fetchSupportedLogPages as token "
                            "expired or timer canceled or controller "
                            "destroyed",
                            "PATH", path);
                        return; // Destructed or cancelled naturally!
                    }
                    self->fetchSupportedLogPages(retryCount + 1, weakToken);
                });
                return;
            }

            lg2::error(
                "[{PATH}] Failed to get Supported Log Pages (00h): {ERROR}",
                "PATH", path, "ERROR", ec.message());
            self->supportedLogPages.clear();
            self->populateMetricStore();
            return;
        }

        if (data.size() < 1024)
        {
            lg2::error(
                "[{PATH}] Undersized Supported Log Pages payload ({SIZE} bytes)",
                "PATH", path, "SIZE", data.size());
            self->supportedLogPages.clear();
            self->populateMetricStore();
            return;
        }

        self->supportedLogPages.assign(data.begin(), data.end());
        self->populateMetricStore();
    });
}

void NVMeControllerEnabled::initializeFeatureStore()
{
    if (featureStore)
    {
        return;
    }

    this->featureStore =
        std::make_shared<FeatureStore>(io, objServer, conn, path, nvmeIntf,
                                       nvmeCtrl, 0, FeatureScope::Controller);

    this->featureStore->init([selfWeak{weak_from_this()},
                              path = this->path](const std::error_code& ec) {
        if (ec)
        {
            if (ec == std::errc::no_such_device ||
                ec == std::errc::not_supported)
            {
                lg2::info("[{PATH}]Feature store not supported: {ERROR}",
                          "PATH", path, "ERROR", ec.message());
            }
            else
            {
                lg2::error(
                    "[{PATH}]Failed to initialize feature store: {ERROR}",
                    "PATH", path, "ERROR", ec.message());
            }
            auto self = selfWeak.lock();
            if (self)
            {
                self->featureStore.reset();
            }
        }
    });
}
void NVMeControllerEnabled::start(
    const std::shared_ptr<NVMeControllerPlugin>& nvmePlugin)
{
    this->NVMeController::start(nvmePlugin);

    status = Status::Enabled;

    if (isPrimary)
    {
        this->initializeMetricStore();
        this->initializeFeatureStore();
    }
}

void NVMeControllerEnabled::stop()
{
    status = Status::Disabled;

    // Resetting the discovery token here instantly revokes it, guaranteeing
    // that any stale async callbacks from fetchSupportedLogPages still pending
    // in the ASIO queue are invalidated upon execution.
    discoverLogsToken.reset();
    this->metricStore.reset();
    if (discoverLogsRetryTimer)
    {
        discoverLogsRetryTimer->cancel();
    }
    this->featureStore.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("[{PATH}]makeAssociation() after shutdown", "PATH", path);
        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("[{PATH}]Controller has been disabled", "PATH", path);
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    std::array<int, 2> pipe{};
    if (::pipe(pipe.data()) < 0)
    {
        lg2::error("[{PATH}]GetLogPage fails to open pipe: {ERROR}", "PATH",
                   path, "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, path = this->path](const std::error_code& ec,
                                                      std::span<uint8_t> data) {
            if (ec)
            {
                lg2::error("[{PATH}]fail to GetLogPage: {ERROR}", "PATH", path,
                           "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, path](
                                         const boost::system::error_code& error,
                                         std::size_t /* transferredSize */) {
                if (error)
                {
                    lg2::error("[{PATH}]GetLogPage fails to write fd: {ERROR}",
                               "PATH", path, "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, path = this->path](
                    std::error_code ec, std::span<uint8_t> data) {
                if (ec)
                {
                    lg2::error("[{PATH}]fail to GetLogPage: {ERROR}", "PATH",
                               path, "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,
                     path](const boost::system::error_code& error,
                           std::size_t /* transferredSize */) {
                    if (error)
                    {
                        lg2::error(
                            "[{PATH}]GetLogPage fails to write fd: {ERROR}",
                            "PATH", path, "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("[{PATH}]Controller has been disabled", "PATH", path);
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    std::array<int, 2> pipe{};
    if (::pipe(pipe.data()) < 0)
    {
        lg2::error("[{PATH}]Identify fails to open pipe: {ERROR}", "PATH", path,
                   "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, path = this->path](const nvme_ex_ptr& ex,
                                                  std::span<uint8_t> data) {
        if (ex)
        {
            lg2::error("[{PATH}]fail to Identify: {ERROR}", "PATH", path,
                       "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,
                                  path](const boost::system::error_code& error,
                                        std::size_t /* transferredSize */) {
            if (error)
            {
                lg2::error("[{PATH}]Identify fails to write fd: {ERROR}",
                           "PATH", path, "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("[{PATH}]Controller has been disabled", "PATH", path);
        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()}, path = this->path](
            const std::error_code& ec, nvme_status_field status) {
        if (ec)
        {
            lg2::error("[{PATH}]firmware commit failed: {ERROR}", "PATH", path,
                       "ERROR", ec.message());
            self->NVMeAdmin::firmwareCommitStatus(FwCommitStatus::Failed);
            return;
        }
        if (status != NVME_SC_SUCCESS)
        {
            lg2::error(
                "[{PATH}]firmware commit status is not success: {STATUS}",
                "PATH", path, "STATUS", status);
            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()
{
    if (discoverLogsRetryTimer)
    {
        discoverLogsRetryTimer->cancel();
    }
    objServer.remove_interface(nvmeControllerInterface);
    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("[{PATH}]Controller has been disabled", "PATH", path);
        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("[{PATH}]Controller has been disabled", "PATH", path);
        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("[{PATH}]nvme_status:{STATUS}, dw0:{DW0}", "PATH", path,
               "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("[{PATH}]NVMe command result: status={STATUS}, dw0={DW0}",
               "PATH", path, "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("[{PATH}]Controller has been disabled", "PATH", path);
        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(
                    "[{PATH}]Fail to attach NS({NSID}) to controller: {ERROR}",
                    "PATH", path, "NSID", nsid, "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("[{PATH}]Controller has been disabled", "PATH", path);
        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(
                    "[{PATH}]Fail to detach NS({NSID}) from controller: {ERROR}",
                    "PATH", path, "NSID", nsid, "ERROR", e.what());
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InternalFailure();
            }
        }
        updateAssociation();
    }
}

void NVMeController::setNvmeVersion(uint32_t version)
{
    nvmeVersion = version;
}

bool NVMeController::isLogPageSupported(uint8_t lid) const
{
    if (nvmeVersion < kMinNvmeVerLogLid00hSupport)
    {
        return false;
    }

    if (lid == 0x00)
    {
        return true;
    }

    if (supportedLogPages.size() < 1024)
    {
        return false; // Under-sized payload or error condition
    }

    size_t byteOffset = static_cast<size_t>(lid) * 4;
    if (byteOffset >= supportedLogPages.size())
    {
        return false;
    }

    return (supportedLogPages[byteOffset] & 0x01) != 0;
}
