#include "NVMeFeatureStore.hpp"

#include "nvme_features.pb.h"

#include <endian.h>

#include <boost/asio/async_result.hpp>
#include <boost/asio/post.hpp>
#include <phosphor-logging/lg2.hpp>

#include <algorithm>
#include <cstring>
#include <iomanip>
#include <map>
#include <sstream>
#include <tuple>
#include <utility>
#include <vector>

static constexpr uint32_t nvmeGetFeaturesCapSaveable = 0x1;
static constexpr uint32_t nvmeGetFeaturesCapChangeable = 0x4;

struct FeatureMeta
{
    uint8_t fid;            ///< NVMe Feature Identifier
    std::string protoClass; ///< Fully qualified Protobuf class name
    FeatureScope scope;     ///< Applicability scope
};

/**
 * @brief Map of P0 features defined in the design document.
 */
static const std::map<std::string, FeatureMeta> supportedFeatures = {
    {"Arbitration",
     {0x01, "google.gbmc.nvme.base.Arbitration", FeatureScope::Controller}},
    {"PowerManagement",
     {0x02, "google.gbmc.nvme.base.PowerManagement", FeatureScope::Controller}},
    {"TemperatureThreshold",
     {0x04, "google.gbmc.nvme.base.TemperatureThreshold",
      FeatureScope::Controller}},
    {"ErrorRecovery",
     {0x05, "google.gbmc.nvme.base.ErrorRecovery", FeatureScope::Namespace}},
    {"VolatileWriteCache",
     {0x06, "google.gbmc.nvme.base.VolatileWriteCache",
      FeatureScope::Controller}},
    {"NumberOfQueues",
     {0x07, "google.gbmc.nvme.base.NumberOfQueues", FeatureScope::Controller}},
    {"InterruptCoalescing",
     {0x08, "google.gbmc.nvme.base.InterruptCoalescing",
      FeatureScope::Controller}},
    {"InterruptVectorConfiguration",
     {0x09, "google.gbmc.nvme.base.InterruptVectorConfiguration",
      FeatureScope::Controller}},
    {"WriteAtomicityNormal",
     {0x0A, "google.gbmc.nvme.base.WriteAtomicityNormal",
      FeatureScope::Controller}},
    {"AsynchronousEventConfiguration",
     {0x0B, "google.gbmc.nvme.base.AsynchronousEventConfiguration",
      FeatureScope::Controller}},
};

template <typename T>
static T parseProto(const std::vector<uint8_t>& data)
{
    T msg;
    if (!msg.ParseFromArray(data.data(), static_cast<int>(data.size())))
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }
    return msg;
}

// Helper for async_initiate
static std::tuple<nvme_ex_ptr, uint32_t, std::vector<uint8_t>>
    asyncAdminGetFeatures(boost::asio::io_context& io,
                          const std::shared_ptr<NVMeMiIntf>& nvmeIntf,
                          nvme_mi_ctrl_t ctrl,
                          const NVMeMiIntf::GetFeaturesRequest& req,
                          boost::asio::yield_context yield)
{
    return boost::asio::async_initiate<boost::asio::yield_context,
                                       void(nvme_ex_ptr, uint32_t,
                                            std::vector<uint8_t>)>(
        [&io](auto&& callback, const std::shared_ptr<NVMeMiIntf>& nvmeIntf,
              nvme_mi_ctrl_t ctrl, const NVMeMiIntf::GetFeaturesRequest& req) {
        auto sharedCb = std::make_shared<std::decay_t<decltype(callback)>>(
            std::forward<decltype(callback)>(callback));
        nvmeIntf->adminGetFeatures(
            ctrl, req,
            [sharedCb, &io](nvme_ex_ptr ex, uint32_t resp,
                            std::span<uint8_t> data) mutable {
            std::vector<uint8_t> dataCopy(data.begin(), data.end());
            boost::asio::post(io, [sharedCb = std::move(sharedCb), ex, resp,
                                   dataCopy = std::move(dataCopy)]() mutable {
                (*sharedCb)(ex, resp, dataCopy);
            });
        });
    },
        yield, nvmeIntf, ctrl, req);
}

static std::tuple<nvme_ex_ptr, uint32_t> asyncAdminSetFeatures(
    boost::asio::io_context& io, const std::shared_ptr<NVMeMiIntf>& nvmeIntf,
    nvme_mi_ctrl_t ctrl, const NVMeMiIntf::SetFeaturesRequest& req,
    boost::asio::yield_context yield)
{
    return boost::asio::async_initiate<boost::asio::yield_context,
                                       void(nvme_ex_ptr, uint32_t)>(
        [&io](auto&& callback, const std::shared_ptr<NVMeMiIntf>& nvmeIntf,
              nvme_mi_ctrl_t ctrl, const NVMeMiIntf::SetFeaturesRequest& req) {
        auto sharedCb = std::make_shared<std::decay_t<decltype(callback)>>(
            std::forward<decltype(callback)>(callback));
        nvmeIntf->adminSetFeatures(
            ctrl, req, [sharedCb, &io](nvme_ex_ptr ex, uint32_t resp) mutable {
            boost::asio::post(io, [sharedCb = std::move(sharedCb), ex,
                                   resp]() mutable { (*sharedCb)(ex, resp); });
        });
    },
        yield, nvmeIntf, ctrl, req);
}

static std::tuple<nvme_ex_ptr, std::vector<uint8_t>> asyncAdminIdentify(
    boost::asio::io_context& io, const std::shared_ptr<NVMeMiIntf>& nvmeIntf,
    nvme_mi_ctrl_t ctrl, nvme_identify_cns cns, uint32_t nsid, uint16_t cntid,
    boost::asio::yield_context yield)
{
    return boost::asio::async_initiate<boost::asio::yield_context,
                                       void(nvme_ex_ptr, std::vector<uint8_t>)>(
        [&io](auto&& callback, const std::shared_ptr<NVMeMiIntf>& nvmeIntf,
              nvme_mi_ctrl_t ctrl, nvme_identify_cns cns, uint32_t nsid,
              uint16_t cntid) {
        auto sharedCb = std::make_shared<std::decay_t<decltype(callback)>>(
            std::forward<decltype(callback)>(callback));
        nvmeIntf->adminIdentify(
            ctrl, cns, nsid, cntid,
            [sharedCb, &io](nvme_ex_ptr ex, std::span<uint8_t> data) mutable {
            std::vector<uint8_t> dataCopy(data.begin(), data.end());
            boost::asio::post(io, [sharedCb = std::move(sharedCb), ex,
                                   dataCopy = std::move(dataCopy)]() mutable {
                (*sharedCb)(ex, dataCopy);
            });
        });
    },
        yield, nvmeIntf, ctrl, cns, nsid, cntid);
}

static std::tuple<std::error_code, std::vector<uint8_t>> asyncAdminGetLogPage(
    boost::asio::io_context& io, const std::shared_ptr<NVMeMiIntf>& nvmeIntf,
    nvme_mi_ctrl_t ctrl, nvme_cmd_get_log_lid lid, uint32_t nsid, uint8_t lsp,
    uint16_t lsi, boost::asio::yield_context yield)
{
    return boost::asio::async_initiate<boost::asio::yield_context,
                                       void(std::error_code,
                                            std::vector<uint8_t>)>(
        [&io](auto&& callback, const std::shared_ptr<NVMeMiIntf>& nvmeIntf,
              nvme_mi_ctrl_t ctrl, nvme_cmd_get_log_lid lid, uint32_t nsid,
              uint8_t lsp, uint16_t lsi) {
        auto sharedCb = std::make_shared<std::decay_t<decltype(callback)>>(
            std::forward<decltype(callback)>(callback));
        nvmeIntf->adminGetLogPage(
            ctrl, lid, nsid, lsp, lsi,
            [sharedCb, &io](const std::error_code& ec,
                            std::span<uint8_t> data) mutable {
            std::vector<uint8_t> dataCopy(data.begin(), data.end());
            boost::asio::post(io, [sharedCb = std::move(sharedCb), ec,
                                   dataCopy = std::move(dataCopy)]() mutable {
                (*sharedCb)(ec, dataCopy);
            });
        });
    },
        yield, nvmeIntf, ctrl, lid, nsid, lsp, lsi);
}

FeatureStore::FeatureStore(
    boost::asio::io_context& io, sdbusplus::asio::object_server& objServer,
    const std::shared_ptr<sdbusplus::asio::connection>& conn,
    const std::string& objectPath, std::shared_ptr<NVMeMiIntf> nvmeIntf,
    nvme_mi_ctrl_t ctrl, uint32_t nsid, FeatureScope scope) :
    io(io), objServer(objServer), conn(conn), objectPath(objectPath),
    nvmeIntf(std::move(nvmeIntf)), ctrl(ctrl), nsid(nsid), scope(scope)
{}

void FeatureStore::registerDbusInterface()
{
    dbusIntf = objServer.add_interface(objectPath,
                                       "xyz.openbmc_project.NVMe.FeatureStore");

    dbusIntf->register_property("ProtoLibraryVersion", std::string("2.0"),
                                sdbusplus::asio::PropertyPermission::readOnly);
    dbusIntf->register_property("FeatureCollection", featureCollection,
                                sdbusplus::asio::PropertyPermission::readOnly);
    dbusIntf->register_method(
        "GetFeature",
        [weakSelf = weak_from_this()](const boost::asio::yield_context& yield,
                                      const std::string& featureName) {
        auto self = weakSelf.lock();
        if (!self)
        {
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }
        return self->getFeature(yield, featureName);
    });

    dbusIntf->register_method(
        "SetFeature",
        [weakSelf = weak_from_this()](const boost::asio::yield_context& yield,
                                      const std::string& featureName,
                                      const std::vector<uint8_t>& data) {
        auto self = weakSelf.lock();
        if (!self)
        {
            throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
        }
        self->setFeature(yield, featureName, data);
    });

    dbusIntf->initialize();
}

void FeatureStore::init(std::function<void(const std::error_code&)>&& cb)
{
    (void)boost::asio::spawn(
        io, [self{shared_from_this()}, cb{std::move(cb)}](
                const boost::asio::yield_context& yield) mutable {
        self->fetchIdentifyData(yield);
        self->registerDbusInterface();
        cb({});
    });
}

void FeatureStore::fetchIdentifyData(const boost::asio::yield_context& yield)
{
    auto [ex, data] = asyncAdminIdentify(
        io, nvmeIntf, ctrl, NVME_IDENTIFY_CNS_CTRL, NVME_NSID_NONE, 0, yield);

    if (ex)
    {
        lg2::error(
            "Identify Controller failed during FeatureStore init: {ERROR}",
            "ERROR", ex->what());
        discoverFeatures(yield);
        return;
    }

    if (data.size() < sizeof(nvme_id_ctrl))
    {
        lg2::error("Identify Controller returned insufficient data");
        discoverFeatures(yield);
        return;
    }
    nvme_id_ctrl idCtrl = {};
    std::memcpy(&idCtrl, data.data(), sizeof(nvme_id_ctrl));
    vwcSupported = (idCtrl.vwc & NVME_CTRL_VWC_PRESENT) != 0;
    oncs = le16toh(idCtrl.oncs);

    if (!vwcSupported)
    {
        lg2::info("Volatile Write Cache (FID 0x06) not supported by hardware");
    }

    discoverFeatures(yield);
}

void FeatureStore::discoverFeatures(const boost::asio::yield_context& yield)
{
    bool oncsBit4 = (oncs & (1 << 4)) != 0;

    featureCollection.clear();

    std::vector<std::pair<std::string, FeatureMeta>> featuresToCheck;
    for (const auto& [name, meta] : supportedFeatures)
    {
        if (meta.scope == scope)
        {
            if (name == "VolatileWriteCache" && !vwcSupported)
            {
                continue;
            }
            featuresToCheck.emplace_back(name, meta);
        }
    }

    // Fetch Log Page 12h (Feature Identifiers Supported and Effects)
    std::vector<uint8_t> fidSupportedEffects;
    auto [ec, logData] = asyncAdminGetLogPage(
        io, nvmeIntf, ctrl, NVME_LOG_LID_FID_SUPPORTED_EFFECTS, NVME_NSID_NONE,
        0, 0, yield);
    if (!ec)
    {
        if (logData.size() == sizeof(struct nvme_fid_supported_effects_log))
        {
            fidSupportedEffects = std::move(logData);
        }
        else
        {
            lg2::error(
                "Log Page 12h size mismatch: expected {EXPECTED}, got {GOT}",
                "EXPECTED", sizeof(struct nvme_fid_supported_effects_log),
                "GOT", logData.size());
        }
    }
    else
    {
        lg2::error("Failed to fetch Log Page 12h: {ERROR}", "ERROR",
                   ec.message());
    }

    for (const auto& [name, meta] : featuresToCheck)
    {
        if (!fidSupportedEffects.empty())
        {
            size_t offset = static_cast<size_t>(meta.fid) * 4;
            if (offset + sizeof(uint32_t) <= fidSupportedEffects.size())
            {
                uint32_t entry = 0;
                std::memcpy(&entry, fidSupportedEffects.data() + offset,
                            sizeof(entry));
                entry = le32toh(entry);
                if ((entry & 0x1) == 0) // FSUPP bit
                {
                    lg2::info(
                        "Feature {NAME} (FID {FID}) not supported per Log Page 12h",
                        "NAME", name, "FID", meta.fid);
                    continue;
                }
            }
            else
            {
                lg2::error("Log Page 12h data too short for FID {FID}", "FID",
                           meta.fid);
                continue;
            }
        }
        std::stringstream ss;
        ss << "0x" << std::setfill('0') << std::setw(2) << std::hex
           << static_cast<int>(meta.fid);
        std::string fidStr = ss.str();

        if (!oncsBit4)
        {
            featureCollection.emplace_back(name + "_Current", fidStr,
                                           meta.protoClass);
            continue;
        }

        NVMeMiIntf::GetFeaturesRequest args{};
        args.fid = meta.fid;
        args.sel = NVME_GET_FEATURES_SEL_SUPPORTED; // 011b
        args.nsid = (scope == FeatureScope::Namespace) ? nsid : NVME_NSID_NONE;
        args.cdw11 = 0;
        args.data_len = 0;

        auto [ex, cdw0, data] = asyncAdminGetFeatures(io, nvmeIntf, ctrl, args,
                                                      yield);

        if (ex)
        {
            lg2::error("Failed to query capabilities for FID {FID}: {ERROR}",
                       "FID", meta.fid, "ERROR", ex->what());
            featureCollection.emplace_back(name + "_Current", fidStr,
                                           meta.protoClass);
        }
        else
        {
            featureCaps[meta.fid] = cdw0;

            featureCollection.emplace_back(name + "_Current", fidStr,
                                           meta.protoClass);

            if ((cdw0 & nvmeGetFeaturesCapChangeable) != 0)
            {
                featureCollection.emplace_back(name + "_Default", fidStr,
                                               meta.protoClass);
            }

            if ((cdw0 & nvmeGetFeaturesCapSaveable) != 0)
            {
                featureCollection.emplace_back(name + "_Saved", fidStr,
                                               meta.protoClass);
            }
        }
    }
}

bool FeatureStore::isFeatureSupported(const std::string& featureName) const
{
    return std::any_of(featureCollection.begin(), featureCollection.end(),
                       [&featureName](const auto& item) {
        return std::get<0>(item) == featureName;
    });
}

std::vector<uint8_t>
    FeatureStore::getFeature(const boost::asio::yield_context& yield,
                             const std::string& featureName)
{
    if (!isFeatureSupported(featureName))
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }
    size_t lastUnderscore = featureName.find_last_of('_');
    if (lastUnderscore == std::string::npos)
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }

    std::string baseName = featureName.substr(0, lastUnderscore);
    std::string selectStr = featureName.substr(lastUnderscore + 1);

    auto it = supportedFeatures.find(baseName);
    if (it == supportedFeatures.end() || it->second.scope != scope)
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }

    uint8_t fid = it->second.fid;
    uint8_t sel = 0;
    if (selectStr == "Current")
    {
        sel = 0;
    }
    else if (selectStr == "Default")
    {
        sel = 1;
    }
    else if (selectStr == "Saved")
    {
        sel = 2;
    }
    else
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }

    NVMeMiIntf::GetFeaturesRequest args{};
    args.fid = fid;
    args.sel = sel;
    args.nsid = (scope == FeatureScope::Namespace) ? nsid : NVME_NSID_NONE;
    args.cdw11 = 0;
    args.data_len = 0;

    auto [ex, cdw0, data] = asyncAdminGetFeatures(io, nvmeIntf, ctrl, args,
                                                  yield);

    if (ex)
    {
        lg2::error("NVMe Get Features (FID {FID}) failed: {ERROR}", "FID", fid,
                   "ERROR", ex->what());
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }

    std::vector<uint8_t> protoData;

    switch (fid)
    {
        case 0x01:
        {
            google::gbmc::nvme::base::Arbitration msg;
            msg.set_arbitration_burst(cdw0 & 0xFF);
            msg.set_low_priority_weight((cdw0 >> 8) & 0xFF);
            msg.set_medium_priority_weight((cdw0 >> 16) & 0xFF);
            msg.set_high_priority_weight((cdw0 >> 24) & 0xFF);
            protoData.resize(msg.ByteSizeLong());
            if (!msg.SerializeToArray(protoData.data(),
                                      static_cast<int>(protoData.size())))
            {
                lg2::error("Failed to serialize Arbitration");
            }
            break;
        }
        case 0x02:
        {
            google::gbmc::nvme::base::PowerManagement msg;
            msg.set_power_state(cdw0 & 0x1F);
            msg.set_workload_hint((cdw0 >> 8) & 0x7);
            protoData.resize(msg.ByteSizeLong());
            if (!msg.SerializeToArray(protoData.data(),
                                      static_cast<int>(protoData.size())))
            {
                lg2::error("Failed to serialize PowerManagement");
            }
            break;
        }
        case 0x04:
        {
            google::gbmc::nvme::base::TemperatureThreshold msg;
            msg.set_temperature_threshold(cdw0 & 0xFFFF);
            msg.set_threshold_temperature_select((cdw0 >> 16) & 0xF);
            msg.set_threshold_type_select(
                static_cast<google::gbmc::nvme::base::
                                TemperatureThreshold_ThresholdType>(
                    (cdw0 >> 20) & 0x3));
            protoData.resize(msg.ByteSizeLong());
            if (!msg.SerializeToArray(protoData.data(),
                                      static_cast<int>(protoData.size())))
            {
                lg2::error("Failed to serialize TemperatureThreshold");
            }
            break;
        }
        case 0x05:
        {
            google::gbmc::nvme::base::ErrorRecovery msg;
            msg.set_tler(cdw0 & 0xFFFF);
            msg.set_dulbe_enable(
                static_cast<google::gbmc::nvme::base::ErrorRecovery_State>(
                    (cdw0 >> 16) & 0x1));
            protoData.resize(msg.ByteSizeLong());
            if (!msg.SerializeToArray(protoData.data(),
                                      static_cast<int>(protoData.size())))
            {
                lg2::error("Failed to serialize ErrorRecovery");
            }
            break;
        }
        case 0x06:
        {
            google::gbmc::nvme::base::VolatileWriteCache msg;
            msg.set_write_cache_enable(
                static_cast<google::gbmc::nvme::base::VolatileWriteCache_State>(
                    cdw0 & 0x1));
            protoData.resize(msg.ByteSizeLong());
            if (!msg.SerializeToArray(protoData.data(),
                                      static_cast<int>(protoData.size())))
            {
                lg2::error("Failed to serialize VolatileWriteCache");
            }
            break;
        }
        case 0x07:
        {
            google::gbmc::nvme::base::NumberOfQueues msg;
            msg.set_number_of_submission_queues(cdw0 & 0xFFFF);
            msg.set_number_of_completion_queues((cdw0 >> 16) & 0xFFFF);
            protoData.resize(msg.ByteSizeLong());
            if (!msg.SerializeToArray(protoData.data(),
                                      static_cast<int>(protoData.size())))
            {
                lg2::error("Failed to serialize NumberOfQueues");
            }
            break;
        }
        case 0x08:
        {
            google::gbmc::nvme::base::InterruptCoalescing msg;
            msg.set_aggregation_threshold(cdw0 & 0xFF);
            msg.set_aggregation_time((cdw0 >> 8) & 0xFF);
            protoData.resize(msg.ByteSizeLong());
            if (!msg.SerializeToArray(protoData.data(),
                                      static_cast<int>(protoData.size())))
            {
                lg2::error("Failed to serialize Interrupt Coalescing");
            }
            break;
        }
        case 0x09:
        {
            google::gbmc::nvme::base::InterruptVectorConfiguration msg;
            msg.set_interrupt_vector(cdw0 & 0xFFFF);
            msg.set_coalescing_disable(
                static_cast<google::gbmc::nvme::base::
                                InterruptVectorConfiguration_CoalescingState>(
                    (cdw0 >> 16) & 0x1));
            protoData.resize(msg.ByteSizeLong());
            if (!msg.SerializeToArray(protoData.data(),
                                      static_cast<int>(protoData.size())))
            {
                lg2::error("Failed to serialize InterruptVectorConfiguration");
            }
            break;
        }
        case 0x0A:
        {
            google::gbmc::nvme::base::WriteAtomicityNormal msg;
            msg.set_disable_normal(
                static_cast<google::gbmc::nvme::base::
                                WriteAtomicityNormal_NormalWriteAtomicityState>(
                    cdw0 & 0x1));
            protoData.resize(msg.ByteSizeLong());
            if (!msg.SerializeToArray(protoData.data(),
                                      static_cast<int>(protoData.size())))
            {
                lg2::error("Failed to serialize WriteAtomicityNormal");
            }
            break;
        }
        case 0x0B:
        {
            google::gbmc::nvme::base::AsynchronousEventConfiguration msg;
            msg.set_smart_critical_warning_config(cdw0 & 0xFF);
            protoData.resize(msg.ByteSizeLong());
            if (!msg.SerializeToArray(protoData.data(),
                                      static_cast<int>(protoData.size())))
            {
                lg2::error(
                    "Failed to serialize AsynchronousEventConfiguration");
            }
            break;
        }
        default:
            break;
    }

    return protoData;
}

void FeatureStore::setFeature(const boost::asio::yield_context& yield,
                              const std::string& featureName,
                              const std::vector<uint8_t>& data)
{
    if (!isFeatureSupported(featureName))
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }
    size_t lastUnderscore = featureName.find_last_of('_');
    if (lastUnderscore == std::string::npos)
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }

    std::string baseName = featureName.substr(0, lastUnderscore);
    std::string selectStr = featureName.substr(lastUnderscore + 1);

    auto it = supportedFeatures.find(baseName);
    if (it == supportedFeatures.end() || it->second.scope != scope)
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }

    if (selectStr == "Default")
    {
        // Default endpoint is read-only
        throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed();
    }
    if (selectStr != "Current" && selectStr != "Saved")
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }

    uint8_t fid = it->second.fid;
    bool save = (selectStr == "Saved");

    auto capIt = featureCaps.find(fid);
    if (capIt != featureCaps.end())
    {
        uint32_t caps = capIt->second;
        bool changeable = (caps & nvmeGetFeaturesCapChangeable) != 0;
        bool saveable = (caps & nvmeGetFeaturesCapSaveable) != 0;

        if (save && !saveable)
        {
            lg2::error("SetFeature: FID {FID} is not saveable per SEL=011b",
                       "FID", lg2::hex, fid);
            throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed();
        }

        if (!save && !changeable)
        {
            lg2::error("SetFeature: FID {FID} is not changeable per SEL=011b",
                       "FID", lg2::hex, fid);
            throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed();
        }
    }

    uint32_t cdw11 = 0;

    switch (fid)
    {
        case 0x01:
        {
            auto msg = parseProto<google::gbmc::nvme::base::Arbitration>(data);
            if (msg.arbitration_burst() > 0xFF ||
                msg.low_priority_weight() > 0xFF ||
                msg.medium_priority_weight() > 0xFF ||
                msg.high_priority_weight() > 0xFF)
            {
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InvalidArgument();
            }
            cdw11 = (msg.arbitration_burst() & 0xFF) |
                    ((msg.low_priority_weight() & 0xFF) << 8) |
                    ((msg.medium_priority_weight() & 0xFF) << 16) |
                    ((msg.high_priority_weight() & 0xFF) << 24);
            break;
        }
        case 0x02:
        {
            auto msg =
                parseProto<google::gbmc::nvme::base::PowerManagement>(data);
            if (msg.power_state() > 0x1F || msg.workload_hint() > 0x7)
            {
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InvalidArgument();
            }
            cdw11 = (msg.power_state() & 0x1F) |
                    ((msg.workload_hint() & 0x7) << 8);
            break;
        }
        case 0x04:
        {
            auto msg =
                parseProto<google::gbmc::nvme::base::TemperatureThreshold>(
                    data);
            if (msg.temperature_threshold() > 0xFFFF ||
                msg.threshold_temperature_select() > 0xF)
            {
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InvalidArgument();
            }
            cdw11 = (msg.temperature_threshold() & 0xFFFF) |
                    ((msg.threshold_temperature_select() & 0xF) << 16) |
                    ((static_cast<uint32_t>(msg.threshold_type_select()) & 0x3)
                     << 20);
            break;
        }
        case 0x05:
        {
            auto msg =
                parseProto<google::gbmc::nvme::base::ErrorRecovery>(data);
            if (msg.tler() > 0xFFFF)
            {
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InvalidArgument();
            }
            cdw11 = (msg.tler() & 0xFFFF) |
                    ((static_cast<uint32_t>(msg.dulbe_enable()) & 0x1) << 16);
            break;
        }
        case 0x06:
        {
            auto msg =
                parseProto<google::gbmc::nvme::base::VolatileWriteCache>(data);
            cdw11 = static_cast<uint32_t>(msg.write_cache_enable()) & 0x1;
            break;
        }
        case 0x07:
        {
            auto msg =
                parseProto<google::gbmc::nvme::base::NumberOfQueues>(data);
            if (msg.number_of_submission_queues() > 0xFFFF ||
                msg.number_of_completion_queues() > 0xFFFF)
            {
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InvalidArgument();
            }
            cdw11 = (msg.number_of_submission_queues() & 0xFFFF) |
                    ((msg.number_of_completion_queues() & 0xFFFF) << 16);
            break;
        }
        case 0x08:
        {
            auto msg =
                parseProto<google::gbmc::nvme::base::InterruptCoalescing>(data);
            if (msg.aggregation_threshold() > 0xFF ||
                msg.aggregation_time() > 0xFF)
            {
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InvalidArgument();
            }
            cdw11 = (msg.aggregation_threshold() & 0xFF) |
                    ((msg.aggregation_time() & 0xFF) << 8);
            break;
        }
        case 0x09:
        {
            auto msg = parseProto<
                google::gbmc::nvme::base::InterruptVectorConfiguration>(data);
            if (msg.interrupt_vector() > 0xFFFF)
            {
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InvalidArgument();
            }
            cdw11 = (msg.interrupt_vector() & 0xFFFF) |
                    ((static_cast<uint32_t>(msg.coalescing_disable()) & 0x1)
                     << 16);
            break;
        }
        case 0x0A:
        {
            auto msg =
                parseProto<google::gbmc::nvme::base::WriteAtomicityNormal>(
                    data);
            cdw11 = static_cast<uint32_t>(msg.disable_normal()) & 0x1;
            break;
        }
        case 0x0B:
        {
            auto msg = parseProto<
                google::gbmc::nvme::base::AsynchronousEventConfiguration>(data);
            if (msg.smart_critical_warning_config() > 0xFF)
            {
                throw sdbusplus::xyz::openbmc_project::Common::Error::
                    InvalidArgument();
            }
            cdw11 = msg.smart_critical_warning_config() & 0xFF;
            break;
        }
        default:
            break;
    }

    NVMeMiIntf::SetFeaturesRequest args{};
    args.fid = fid;
    args.save = save;
    args.cdw11 = cdw11;
    args.nsid = (scope == FeatureScope::Namespace) ? nsid : NVME_NSID_NONE;
    args.data = {};

    auto [ex, resp] = asyncAdminSetFeatures(io, nvmeIntf, ctrl, args, yield);

    if (ex)
    {
        lg2::error("NVMe Set Features (FID {FID}) failed: {ERROR}", "FID", fid,
                   "ERROR", ex->what());
        throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
    }
}
