#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_NVME_FEATURES_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_NVME_FEATURES_H_

#include <systemd/sd-bus.h>

#include <array>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <variant>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "boost/beast/http/verb.hpp"  // NOLINT
#include "boost/system/error_code.hpp"  // NOLINT
#include "app.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "dbus_utils.hpp"
#include "json_utils.hpp"
#include "storage_utils.hpp"
#include "storage.hpp"
#include <nlohmann/json_fwd.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message.hpp"
#include "sdbusplus/message/native_types.hpp"

namespace redfish {

inline void processNvmeFeaturesCollectionGet(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& parentUri, const std::string& service,
    const std::string& path) {
  managedStore::ManagedObjectStoreContext context(asyncResp);
  dbus_utils::getProperty<
      std::vector<std::tuple<std::string, std::string, std::string>>>(
      service, path, "xyz.openbmc_project.NVMe.FeatureStore",
      "FeatureCollection", context,
      [asyncResp, parentUri](
          const boost::system::error_code& ec,
          const std::vector<std::tuple<std::string, std::string, std::string>>&
              features) {
        if (ec) {
          BMCWEB_LOG_ERROR << "Failed to get FeatureCollection: " << ec;
          messages::internalError(asyncResp->res);
          return;
        }

        nlohmann::json& members = asyncResp->res.jsonValue["Members"];
        members = nlohmann::json::array();
        for (const auto& feature : features) {
          nlohmann::json::object_t member;
          member["@odata.id"] =
              absl::StrCat(parentUri, "/", std::get<0>(feature));
          members.push_back(member);
        }

        asyncResp->res.jsonValue["@odata.id"] = parentUri;
        asyncResp->res.jsonValue["@odata.type"] =
            "#GoogleNvmeFeatureCollection.GoogleNvmeFeatureCollection";
        asyncResp->res.jsonValue["Name"] = "NVMe Features Collection";
        asyncResp->res.jsonValue["Members@odata.count"] = members.size();
      });
}

inline void processNvmeFeatureGet(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& parentUri, const std::string& featureName,
    const std::string& service, const std::string& path) {
  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      service, path, "xyz.openbmc_project.NVMe.FeatureStore", context,
      [asyncResp, parentUri, featureName, service, path](
          const boost::system::error_code& ec,
          const std::vector<std::pair<
              std::string, dbus::utility::DbusVariantType>>& properties) {
        if (ec) {
          BMCWEB_LOG_ERROR << "Failed to get properties: " << ec;
          messages::internalError(asyncResp->res);
          return;
        }

        std::string revision;
        std::vector<std::tuple<std::string, std::string, std::string>>
            featureCollection;

        bool revisionFound = false;
        bool featureCollectionFound = false;
        for (const auto& [propName, propVar] : properties) {
          if (propName == "ProtoLibraryVersion") {
            const std::string* revisionPtr = std::get_if<std::string>(&propVar);
            if (revisionPtr != nullptr) {
              revision = *revisionPtr;
              revisionFound = true;
            }
          } else if (propName == "FeatureCollection") {
            const auto* fcPtr = std::get_if<
                std::vector<std::tuple<std::string, std::string, std::string>>>(
                &propVar);
            if (fcPtr != nullptr) {
              featureCollection = *fcPtr;
              featureCollectionFound = true;
            }
          }
        }

        if (!revisionFound || !featureCollectionFound) {
          BMCWEB_LOG_ERROR << "Failed to read ProtoLibraryVersion or "
                              "FeatureCollection";
          messages::internalError(asyncResp->res);
          return;
        }

        std::string featureIdStr;
        std::string className;
        bool featureFoundInCollection = false;
        for (const auto& feature : featureCollection) {
          if (std::get<0>(feature) == featureName) {
            featureIdStr = std::get<1>(feature);
            className = std::get<2>(feature);
            featureFoundInCollection = true;
            break;
          }
        }

        if (!featureFoundInCollection) {
          messages::resourceNotFound(asyncResp->res, "GoogleNvmeFeature",
                                     featureName);
          return;
        }

        asyncResp->res.jsonValue["@odata.id"] =
            absl::StrCat(parentUri, "/", featureName);
        asyncResp->res.jsonValue["@odata.type"] =
            "#GoogleNvmeFeature.v1_0_0.GoogleNvmeFeature";
        asyncResp->res.jsonValue["Id"] = featureName;
        asyncResp->res.jsonValue["Name"] = featureName;
        asyncResp->res.jsonValue["FeatureId"] = featureIdStr;

        size_t pos = featureName.rfind('_');
        if (pos != std::string::npos) {
          asyncResp->res.jsonValue["Select"] = featureName.substr(pos + 1);
        }

        asyncResp->res.jsonValue["DataProto"]["ClassName"] = className;
        asyncResp->res.jsonValue["DataProto"]["Revision"] = revision;

        managedStore::GetManagedObjectStore()
            ->PostDbusCallToIoContextThreadSafe(
                asyncResp->strand_,
                absl::AnyInvocable<void(const boost::system::error_code&,
                                        const sdbusplus::message_t&,
                                        const std::vector<uint8_t>&)>(
                    [asyncResp](const boost::system::error_code& ec2,
                                const sdbusplus::message_t& msg,
                                const std::vector<uint8_t>& payload) {
                      if (ec2) {
                        BMCWEB_LOG_ERROR << "Failed to call GetFeature: "
                                         << ec2;
                        messages::internalError(asyncResp->res);
                        return;
                      }
                      const ::sd_bus_error* sd_err = nullptr;
                      if (msg) {
                        sd_err = msg.get_error();
                      }
                      if (sd_err != nullptr) {
                        storageAddDbusError(asyncResp->res, "GetFeature", "",
                                            sd_err->name, sd_err->message);
                        return;
                      }
                      asyncResp->res.jsonValue["DataProto"]["PayloadBase64"] =
                          crow::utility::base64encode(std::string_view(
                              reinterpret_cast<const char*>(payload.data()),
                              payload.size()));
                    }),
                service, path, "xyz.openbmc_project.NVMe.FeatureStore",
                "GetFeature", featureName);
      });
}

inline absl::StatusOr<std::string> getPayloadBase64(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  nlohmann::json dataProto;
  if (!json_util::readJsonPatch(req, asyncResp->res, "DataProto", dataProto)) {
    return absl::InvalidArgumentError("Invalid or Missing DataProto");
  }

  std::string payloadBase64;
  if (!json_util::readJson(dataProto, asyncResp->res, "PayloadBase64",
                           payloadBase64)) {
    return absl::InvalidArgumentError("Invalid or Missing PayloadBase64");
  }

  return payloadBase64;
}

inline void processNvmeFeaturePatch(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& featureName, const std::string& payloadBase64,
    const std::string& service, const std::string& path) {
  std::string decodedPayload;
  if (!crow::utility::base64Decode(payloadBase64, decodedPayload)) {
    messages::propertyValueFormatError(asyncResp->res, payloadBase64,
                                       "DataProto/PayloadBase64");
    return;
  }
  std::vector<uint8_t> payload(decodedPayload.begin(), decodedPayload.end());

  BMCWEB_LOG_DEBUG << "Patching NVMeFeature " << featureName << " on " << path;

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp, featureName](const boost::system::error_code& ec,
                               const sdbusplus::message_t& msg) {
        const ::sd_bus_error* sd_err = msg.get_error();
        if (sd_err != nullptr) {
          storageAddDbusError(asyncResp->res, "SetFeature", featureName,
                              sd_err->name, sd_err->message);
          return;
        }
        if (ec) {
          BMCWEB_LOG_ERROR << "Failed to call SetFeature: " << ec;
          messages::internalError(asyncResp->res);
          return;
        }
        messages::success(asyncResp->res);
      },
      service, path, "xyz.openbmc_project.NVMe.FeatureStore", "SetFeature",
      featureName, payload);
}

inline void getFeatureStoreServiceForPath(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& path,
    std::function<void(const std::string& service)> cb) {
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.NVMe.FeatureStore"};
  managedStore::ManagedObjectStoreContext context(asyncResp);
  storage_utils::getDbusObject(
      path, interfaces, context,
      [asyncResp, path, cb = std::move(cb)](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetObject& objects) mutable {
        if (ec || objects.empty()) {
          BMCWEB_LOG_ERROR << "Failed to find FeatureStore interface for "
                           << path;
          messages::internalError(asyncResp->res);
          return;
        }
        std::move(cb)(objects.front().first);
      });
}

inline void handleControllerNvmeFeaturesCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId,
    const std::string& controllerId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  BMCWEB_LOG_DEBUG << "Get NVMeFeatures Collection for controller "
                   << controllerId;

  storage_utils::findStorageAndController(
      asyncResp, storageId, controllerId,
      [asyncResp, systemName, storageId, controllerId](
          const sdbusplus::message::object_path& path,
          const dbus::utility::MapperServiceMap& ifaces) {
        std::optional<std::string> service = storage_utils::matchServiceName(
            ifaces, "xyz.openbmc_project.NVMe.FeatureStore");
        if (!service) {
          BMCWEB_LOG_ERROR << "Failed to find FeatureStore interface for "
                           << path.str;
          messages::internalError(asyncResp->res);
          return;
        }

        std::string parentUri(crow::utility::urlFromPieces(
                                  "redfish", "v1", "Systems", systemName,
                                  "Storage", storageId, "Controllers",
                                  controllerId, "Oem", "Google", "Features")
                                  .buffer());
        processNvmeFeaturesCollectionGet(asyncResp, parentUri, *service,
                                         path.str);
      });
}

inline bool parseNvmeFeatureProperties(
    const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
        properties,
    const std::string& featureName, std::string& revision,
    std::string& featureIdStr, std::string& className, crow::Response& res) {
  std::vector<std::tuple<std::string, std::string, std::string>>
      featureCollection;

  bool revisionFound = false;
  bool featureCollectionFound = false;
  for (const auto& [propName, propVar] : properties) {
    if (propName == "ProtoLibraryVersion") {
      const std::string* revisionPtr = std::get_if<std::string>(&propVar);
      if (revisionPtr != nullptr) {
        revision = *revisionPtr;
        revisionFound = true;
      }
    } else if (propName == "FeatureCollection") {
      const auto* fcPtr = std::get_if<
          std::vector<std::tuple<std::string, std::string, std::string>>>(
          &propVar);
      if (fcPtr != nullptr) {
        featureCollection = *fcPtr;
        featureCollectionFound = true;
      }
    }
  }

  if (!revisionFound || !featureCollectionFound) {
    BMCWEB_LOG_ERROR << "Failed to read ProtoLibraryVersion or "
                        "FeatureCollection";
    messages::internalError(res);
    return false;
  }

  bool featureFoundInCollection = false;
  for (const auto& feature : featureCollection) {
    if (std::get<0>(feature) == featureName) {
      featureIdStr = std::get<1>(feature);
      className = std::get<2>(feature);
      featureFoundInCollection = true;
      break;
    }
  }

  if (!featureFoundInCollection) {
    messages::resourceNotFound(res, "GoogleNvmeFeature", featureName);
    return false;
  }

  return true;
}

inline void handleControllerNvmeFeatureGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId,
    const std::string& controllerId, const std::string& featureName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  BMCWEB_LOG_DEBUG << "Get NVMeFeature " << featureName;

  storage_utils::findStorageAndController(
      asyncResp, storageId, controllerId,
      [asyncResp, systemName, storageId, controllerId, featureName](
          const sdbusplus::message::object_path& path,
          const dbus::utility::MapperServiceMap& ifaces) {
        std::optional<std::string> service = storage_utils::matchServiceName(
            ifaces, "xyz.openbmc_project.NVMe.FeatureStore");
        if (!service) {
          BMCWEB_LOG_ERROR << "Failed to find FeatureStore interface for "
                           << path.str;
          messages::internalError(asyncResp->res);
          return;
        }

        std::string parentUri(crow::utility::urlFromPieces(
                                  "redfish", "v1", "Systems", systemName,
                                  "Storage", storageId, "Controllers",
                                  controllerId, "Oem", "Google", "Features")
                                  .buffer());
        processNvmeFeatureGet(asyncResp, parentUri, featureName, *service,
                              path.str);
      });
}

inline void handleControllerNvmeFeaturePatch(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& /*systemName*/, const std::string& storageId,
    const std::string& controllerId, const std::string& featureName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  absl::StatusOr<std::string> payloadBase64 = getPayloadBase64(req, asyncResp);
  if (!payloadBase64.ok()) {
    BMCWEB_LOG_ERROR << "Failed to parse Request Payload for " << featureName
                     << " Base64: " << payloadBase64.status();
    return;
  }

  storage_utils::findStorageAndController(
      asyncResp, storageId, controllerId,
      [asyncResp, featureName, payloadBase64 = std::move(*payloadBase64)](
          const sdbusplus::message::object_path& path,
          const dbus::utility::MapperServiceMap& ifaces) {
        auto service = storage_utils::matchServiceName(
            ifaces, "xyz.openbmc_project.NVMe.FeatureStore");
        if (!service) {
          messages::internalError(asyncResp->res);
          return;
        }

        processNvmeFeaturePatch(asyncResp, featureName, payloadBase64, *service,
                                path.str);
      });
}

inline void handleStorageNvmeFeaturesCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  BMCWEB_LOG_DEBUG << "Get NVMeFeatures Collection for storage " << storageId;

  storage_utils::findStorage(
      asyncResp, storageId,
      [asyncResp, systemName,
       storageId](const sdbusplus::message::object_path& storagePath) {
        getFeatureStoreServiceForPath(
            asyncResp, storagePath.str,
            [asyncResp, systemName, storageId,
             storagePath](const std::string& service) {
              std::string parentUri(
                  crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                               systemName, "Storage", storageId,
                                               "Oem", "Google", "Features")
                      .buffer());
              processNvmeFeaturesCollectionGet(asyncResp, parentUri, service,
                                               storagePath.str);
            });
      });
}

inline void handleStorageNvmeFeatureGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId,
    const std::string& featureName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  BMCWEB_LOG_DEBUG << "Get NVMeFeature " << featureName;

  storage_utils::findStorage(
      asyncResp, storageId,
      [asyncResp, systemName, storageId,
       featureName](const sdbusplus::message::object_path& storagePath) {
        getFeatureStoreServiceForPath(
            asyncResp, storagePath.str,
            [asyncResp, systemName, storageId, featureName,
             storagePath](const std::string& service) {
              std::string parentUri(
                  crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                               systemName, "Storage", storageId,
                                               "Oem", "Google", "Features")
                      .buffer());
              processNvmeFeatureGet(asyncResp, parentUri, featureName, service,
                                    storagePath.str);
            });
      });
}

inline void handleStorageNvmeFeaturePatch(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& /*systemName*/, const std::string& storageId,
    const std::string& featureName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  absl::StatusOr<std::string> payloadBase64 = getPayloadBase64(req, asyncResp);
  if (!payloadBase64.ok()) {
    BMCWEB_LOG_ERROR << "Failed to parse Request Payload for " << featureName
                     << " Base64: " << payloadBase64.status();
    return;
  }

  storage_utils::findStorage(
      asyncResp, storageId,
      [asyncResp, featureName, payloadBase64 = std::move(*payloadBase64)](
          const sdbusplus::message::object_path& storagePath) {
        getFeatureStoreServiceForPath(
            asyncResp, storagePath.str,
            [asyncResp, featureName, payloadBase64,
             storagePath](const std::string& service) {
              processNvmeFeaturePatch(asyncResp, featureName, payloadBase64,
                                      service, storagePath.str);
            });
      });
}

inline void findVolumePath(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& storageId, const std::string& volumeId,
    std::function<void(const sdbusplus::message::object_path& path)> cb) {
  storage_utils::findStorage(
      asyncResp, storageId,
      [asyncResp, volumeId, cb = std::move(cb)](
          const sdbusplus::message::object_path& storagePath) mutable {
        constexpr std::array<std::string_view, 1> interfaces = {
            "xyz.openbmc_project.Inventory.Item.Volume"};
        managedStore::ManagedObjectStoreContext requestContext(asyncResp);
        managedStore::GetManagedObjectStore()->getAssociatedSubTree(
            storagePath / "containing",
            sdbusplus::message::object_path("/xyz/openbmc_project/inventory"),
            0, interfaces, requestContext,
            [asyncResp, volumeId, cb = std::move(cb)](
                const boost::system::error_code& ec,
                const dbus::utility::MapperGetSubTreeResponse&
                    subtree) mutable {
              if (ec) {
                messages::internalError(asyncResp->res);
                return;
              }
              for (const auto& [path, ifaces] : subtree) {
                if (sdbusplus::message::object_path(path).filename() ==
                    volumeId) {
                  std::move(cb)(path);
                  return;
                }
              }
              messages::resourceNotFound(asyncResp->res, "Volume", volumeId);
            });
      });
}

inline void handleVolumeNvmeFeaturesCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId,
    const std::string& volumeId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  BMCWEB_LOG_DEBUG << "Get NVMeFeatures Collection for volume " << volumeId;

  findVolumePath(
      asyncResp, storageId, volumeId,
      [asyncResp, systemName, storageId,
       volumeId](const sdbusplus::message::object_path& volumePath) {
        getFeatureStoreServiceForPath(
            asyncResp, volumePath.str,
            [asyncResp, systemName, storageId, volumeId,
             volumePath](const std::string& service) {
              std::string parentUri(crow::utility::urlFromPieces(
                                        "redfish", "v1", "Systems", systemName,
                                        "Storage", storageId, "Volumes",
                                        volumeId, "Oem", "Google", "Features")
                                        .buffer());
              processNvmeFeaturesCollectionGet(asyncResp, parentUri, service,
                                               volumePath.str);
            });
      });
}

inline void handleVolumeNvmeFeatureGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId,
    const std::string& volumeId, const std::string& featureName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  BMCWEB_LOG_DEBUG << "Get NVMeFeature " << featureName;

  findVolumePath(
      asyncResp, storageId, volumeId,
      [asyncResp, systemName, storageId, volumeId,
       featureName](const sdbusplus::message::object_path& volumePath) {
        getFeatureStoreServiceForPath(
            asyncResp, volumePath.str,
            [asyncResp, systemName, storageId, volumeId, featureName,
             volumePath](const std::string& service) {
              std::string parentUri(crow::utility::urlFromPieces(
                                        "redfish", "v1", "Systems", systemName,
                                        "Storage", storageId, "Volumes",
                                        volumeId, "Oem", "Google", "Features")
                                        .buffer());
              processNvmeFeatureGet(asyncResp, parentUri, featureName, service,
                                    volumePath.str);
            });
      });
}

inline void handleVolumeNvmeFeaturePatch(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& /*systemName*/, const std::string& storageId,
    const std::string& volumeId, const std::string& featureName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  absl::StatusOr<std::string> payloadBase64 = getPayloadBase64(req, asyncResp);
  if (!payloadBase64.ok()) {
    BMCWEB_LOG_ERROR << "Failed to parse Request Payload for " << featureName
                     << " Base64: " << payloadBase64.status();
    return;
  }

  findVolumePath(
      asyncResp, storageId, volumeId,
      [asyncResp, featureName, payloadBase64 = std::move(*payloadBase64)](
          const sdbusplus::message::object_path& volumePath) {
        getFeatureStoreServiceForPath(
            asyncResp, volumePath.str,
            [asyncResp, featureName, payloadBase64,
             volumePath](const std::string& service) {
              processNvmeFeaturePatch(asyncResp, featureName, payloadBase64,
                                      service, volumePath.str);
            });
      });
}

inline void requestRoutesNvmeFeatures(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Controllers/<str>/Oem/"
               "Google/Features/")
      .privileges(redfish::privileges::getStorageController)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleControllerNvmeFeaturesCollectionGet, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Controllers/<str>/Oem/"
               "Google/Features/<str>/")
      .privileges(redfish::privileges::getStorageController)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleControllerNvmeFeatureGet, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Controllers/<str>/Oem/"
               "Google/Features/<str>/")
      .privileges(redfish::privileges::patchStorageController)
      .methods(boost::beast::http::verb::patch)(
          std::bind_front(handleControllerNvmeFeaturePatch, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Oem/Google/Features/")
      .privileges(redfish::privileges::getStorage)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleStorageNvmeFeaturesCollectionGet, std::ref(app)));

  BMCWEB_ROUTE(
      app, "/redfish/v1/Systems/<str>/Storage/<str>/Oem/Google/Features/<str>/")
      .privileges(redfish::privileges::getStorage)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleStorageNvmeFeatureGet, std::ref(app)));

  BMCWEB_ROUTE(
      app, "/redfish/v1/Systems/<str>/Storage/<str>/Oem/Google/Features/<str>/")
      .privileges(redfish::privileges::patchStorage)
      .methods(boost::beast::http::verb::patch)(
          std::bind_front(handleStorageNvmeFeaturePatch, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Volumes/<str>/Oem/"
               "Google/Features/")
      .privileges(redfish::privileges::getVolume)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleVolumeNvmeFeaturesCollectionGet, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Volumes/<str>/Oem/"
               "Google/Features/<str>/")
      .privileges(redfish::privileges::getVolume)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleVolumeNvmeFeatureGet, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Volumes/<str>/Oem/"
               "Google/Features/<str>/")
      .privileges(redfish::privileges::patchVolume)
      .methods(boost::beast::http::verb::patch)(
          std::bind_front(handleVolumeNvmeFeaturePatch, std::ref(app)));
}
}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_NVME_FEATURES_H_
