#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_STORAGE_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_STORAGE_H_

/*
// Copyright (c) 2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/

/**
 * The following requirments on Dbus should be satisfied for storage stack
 * working properly:
 * * system name and the storage name are globally unique
 * * On Single System system, the default system DBus object can be omitted.
 * * On Multi System system, the system DBus object and the association
 * (containing/contained_by) to Storage are manditory.
 */

#include <systemd/sd-bus.h>

#include <algorithm>
#include <array>
#include <charconv>
#include <chrono>  // NOLINT
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <filesystem>  // NOLINT
#include <functional>
#include <iostream>
#include <iterator>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <tuple>
#include <unordered_set>
#include <utility>
#include <variant>
#include <vector>

#include "boost/system/error_code.hpp"  // NOLINT
#include "bmcweb_config.h"
#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 "human_sort.hpp"
#include "error_messages.hpp"
#include "generated/enums/drive.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "collection.hpp"
#include "dbus_utils.hpp"
#include "hex_utils.hpp"
#include "json_utils.hpp"
#include "nvme_metric_utils.hpp"
#include "storage_utils.hpp"
#include "system_utils.hpp"  // NOLINT
#include "health.hpp"
#include "task.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message.hpp"
#include "sdbusplus/message/native_types.hpp"
#include "sdbusplus/unpack_properties.hpp"
#include "system_utils.hpp"

namespace redfish {

/* Converts a NVMe dbus error to a redfish equivalent, adds to the response */
inline void storageAddDbusError(crow::Response& res, std::string_view func,
                                const std::string& storageId,
                                std::string_view errorName,
                                std::string_view errorDesc) {
  (void)storageId;

  crow::Response err;

  BMCWEB_LOG_DEBUG << func << " " << errorName << ", " << errorDesc;
  if (errorName == "xyz.openbmc_project.Common.Error.TooManyResources") {
    messages::createLimitReachedForResource(err);
  } else if (errorName == "xyz.openbmc_project.Common.Error.InvalidArgument") {
    messages::propertyValueError(err, "");
  } else if (errorName ==
                 "xyz.openbmc_project.Common.Error.DeviceOperationFailed" ||
             errorName ==
                 "xyz.openbmc_project.Common.Error.UnsupportedRequest") {
    messages::operationFailed(err);
  } else if (errorName == "xyz.openbmc_project.Common.Error.NotAllowed") {
    messages::operationNotAllowed(err);
  } else {
    messages::internalError(err);
  }

  // Some messages have "error" toplevel, others have "@Message.ExtendedInfo"
  // (addMessageToErrorJson() versus addMessageToJson()). Choose which.
  nlohmann::json extInfo;
  if (err.jsonValue.contains("error")) {
    extInfo = err.jsonValue["error"][messages::messageAnnotation][0];
  } else {
    extInfo = err.jsonValue[messages::messageAnnotation][0];
  }

  // Keep the specific error message provided from the NVMe software.
  extInfo["Message"] = errorDesc;

  messages::moveErrorsToErrorJson(res.jsonValue, extInfo);
  res.result(err.result());
}

/**
 * @brief Makes sure the target Storage can be accessed through given System
 * @param asyncResp     Pointer to object holding response data
 * @param systemName    ID (D-Bus filename) of the System
 * @param storageId     ID (D-Bus filename) of the Storage
//  * @param cb            Callback function to call if the access is valid
 *
 * Sets an error response if the Storage can't be accessed through this System
 */
inline void checkSystemAndStorage(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId) {
  storage_utils::findStorage(
      asyncResp, storageId,
      [asyncResp, systemName,
       storageId](const sdbusplus::message::object_path& storagePath) {
        storage_utils::getSystemPathFromStorage(
            asyncResp, storagePath,
            [asyncResp, systemName,
             storageId](std::optional<std::string_view> systemPath) {
              if ((!systemPath &&
                   systemName != "system")  // default single system system
                  || (systemPath &&
                      std::filesystem::path(*systemPath).filename() !=
                          systemName)) {
                BMCWEB_LOG_ERROR
                    << "No association between System and Storage: "
                    << systemName << ", " << storageId;
                messages::internalError(asyncResp->res);
                return;
              }
              // cb();
            });
      });
}

inline void handleGetSystemStorageCollection(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  asyncResp->res.jsonValue["@odata.type"] =
      "#StorageCollection.StorageCollection";
  asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
      "redfish", "v1", "Systems", systemName, "Storage");
  asyncResp->res.jsonValue["Name"] = "Storage Collection";

  storage_utils::getSystemPathFromName(
      asyncResp, systemName,
      [asyncResp, systemName](std::optional<std::string_view> systemPath) {
        if (!systemPath)  // fall back to single-system system
        {
          if (systemName != "system") {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
          }
          collection_util::getCollectionMembers(
              asyncResp,
              crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                           systemName, "Storage"),
              std::array<std::string_view, 1>{
                  {"xyz.openbmc_project.Inventory.Item.Storage"}});
          return;
        }
        collection_util::getAssociatedCollectionMembers(
            asyncResp,
            crow::utility::urlFromPieces("redfish", "v1", "Systems", systemName,
                                         "Storage"),
            std::array<std::string_view, 1>{
                {"xyz.openbmc_project.Inventory.Item.Storage"}},
            (std::string(*systemPath) + "/containing").c_str());
      });
}

inline void handleGetStorageCollection(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.jsonValue["@odata.type"] =
      "#StorageCollection.StorageCollection";
  asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Storage";
  asyncResp->res.jsonValue["Name"] = "Storage Collection";
  constexpr std::array<std::string_view, 1> interface{
      "xyz.openbmc_project.Inventory.Item.Storage"};
  collection_util::getCollectionMembers(
      asyncResp, crow::utility::urlFromPieces("redfish", "v1", "Storage"),
      interface);
}

inline void requestRoutesStorageCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/")
      .privileges(redfish::privileges::getStorageCollection)
      .methods(boost::beast::http::verb::get)(
                  [&app](const crow::Request& req,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
               const std::string& systemName) {

              if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
                  return;
              }

               redfish::system_utils::getSystemInformation(
                  asyncResp, systemName,
                  [systemName](
                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                      const std::string& systemPath) {
                        handleGetSystemStorageCollection(asyncResp, systemName);
                        (void)systemPath;
                    });
        });

  BMCWEB_ROUTE(app, "/redfish/v1/Storage/")
      .privileges(redfish::privileges::getStorageCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetStorageCollection, std::ref(app)));
}

inline void getDrives(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                      const std::shared_ptr<HealthPopulate>& health,
                      const sdbusplus::message::object_path& storagePath,
                      const std::string& chassisId) {
  const std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Inventory.Item.Drive"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getAssociatedSubTreePaths(
      storagePath / "drive",
      sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
      interfaces, requestContext,
      [asyncResp, health, chassisId](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreePathsResponse& driveList) {
        if (ec) {
          BMCWEB_LOG_ERROR << "Drive mapper call error";
          messages::internalError(asyncResp->res);
          return;
        }

        nlohmann::json& driveArray = asyncResp->res.jsonValue["Drives"];
        driveArray = nlohmann::json::array();
        auto& count = asyncResp->res.jsonValue["Drives@odata.count"];
        count = 0;

#ifdef HEALTH_POPULATE
        health->inventory.insert(health->inventory.end(), driveList.begin(),
                                 driveList.end());
#endif

        for (const std::string& drive : driveList) {
          sdbusplus::message::object_path object(drive);
          if (object.filename().empty()) {
            BMCWEB_LOG_ERROR << "Failed to find filename in " << drive;
            return;
          }

          nlohmann::json::object_t driveJson;
          driveJson["@odata.id"] = crow::utility::urlFromPieces(
              "redfish", "v1", "Chassis", chassisId, "Drives",
              object.filename());
          driveArray.emplace_back(std::move(driveJson));
        }

        count = driveArray.size();
      });
}

inline void populateCustomSSDInfo(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const dbus::utility::MapperServiceMap& ifaces, const std::string& path) {
  std::string connection;
  std::string customSSDDbusInterface =
      "com.google.gbmc.ssd." +
      boost::algorithm::to_lower_copy(std::string(customSSD));

  for (const auto& x : ifaces) {
    for (const std::string& y : x.second) {
      if (y == customSSDDbusInterface) {
        connection = x.first;
        break;
      }
    }
    if (!connection.empty()) {
      break;
    }
  }
  if (connection.empty()) {
    return;
  }

  managedStore::ManagedObjectStoreContext context(asyncResp);
  asyncResp->res.jsonValue["Links"]["Oem"]["Google"][std::string(customSSD)] =
      nlohmann::json::object_t();
  dbus_utils::getProperty<bool>(
      connection, path, customSSDDbusInterface, "PwrseqPgood", context,
      [asyncResp, path](const boost::system::error_code& ec, bool pwrseqPgood) {
        // this interface isn't necessary, only check it if
        // we get a good return
        if (ec) {
          return;
        }

        asyncResp->res.jsonValue["Links"]["Oem"]["Google"]
                                [std::string(customSSD)]["PwrseqPgood"] =
            pwrseqPgood;
      });
  managedStore::GetManagedObjectStore()->getAllProperties(
      connection, path, customSSDDbusInterface, context,
      [asyncResp, connection, path, context](
          const boost::system::error_code ec2,
          const std::vector<std::pair<
              std::string, dbus::utility::DbusVariantType>>& propertiesList) {
        if (ec2) {
          // this interface isn't necessary
          return;
        }

        const bool* manufacturingMode = nullptr;
        const bool* watchdogTriggered = nullptr;
        const bool* fruEepromWriteProtect = nullptr;
        const bool* controllerOtpWriteProtect = nullptr;
        const bool* triggerPowerCycle = nullptr;
        const bool* triggerReset = nullptr;
        const bool* disableWatchdog = nullptr;
        const bool* debugMode = nullptr;
        const bool* controllerOtpWriteEnable = nullptr;
        const uint64_t* spiImgSelect = nullptr;
        const uint64_t* bootFailureCount = nullptr;
        const std::string* pwrseqState = nullptr;
        const uint64_t* uptimeInSeconds = nullptr;
        const uint64_t* uptimeInMinutes = nullptr;
        const bool* pgoodVdd12v0Ssd = nullptr;
        const bool* pgoodVddPcMor = nullptr;
        const bool* pgoodVdd3v3Pcie = nullptr;
        const bool* pgoodVdd0v83Mor = nullptr;
        const bool* pgoodVttVrefca = nullptr;
        const bool* pgoodVddFlashVcc = nullptr;
        const bool* pgood12vFlashVpp = nullptr;
        const std::string* cpldVersion = nullptr;

        std::string otpWriteProtectProperty =
            customSSDController + std::string("OtpWriteProtect");
        std::string otpWriteEnableProperty =
            customSSDController + std::string("OtpWriteEnable");

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), propertiesList,
            "ManufacturingMode", manufacturingMode, "WatchdogTriggered",
            watchdogTriggered, "FruEepromWriteProtect", fruEepromWriteProtect,
            otpWriteProtectProperty, controllerOtpWriteProtect,
            "TriggerPowerCycle", triggerPowerCycle, "TriggerReset",
            triggerReset, "DisableWatchdog", disableWatchdog, "DebugMode",
            debugMode, otpWriteEnableProperty, controllerOtpWriteEnable,
            "SpiImgSelect", spiImgSelect, "BootFailureCount", bootFailureCount,
            "PwrseqState", pwrseqState, "UptimeInSeconds", uptimeInSeconds,
            "UptimeInMinutes", uptimeInMinutes, "PgoodVdd12v0Ssd",
            pgoodVdd12v0Ssd, "PgoodVddPcMor", pgoodVddPcMor, "PgoodVdd3v3Pcie",
            pgoodVdd3v3Pcie, "PgoodVdd0v83Mor", pgoodVdd0v83Mor,
            "PgoodVttVrefca", pgoodVttVrefca, "PgoodVddFlashVcc",
            pgoodVddFlashVcc, "Pgood12vFlashVpp", pgood12vFlashVpp,
            "CpldVersion", cpldVersion);

        if (!success) {
          BMCWEB_LOG_CRITICAL << "Failed to parse Arguments for "
                              << std::string(customSSD);
          messages::internalError(asyncResp->res);
          return;
        }

        nlohmann::json& customSSDJsonObj =
            asyncResp->res
                .jsonValue["Links"]["Oem"]["Google"][std::string(customSSD)];
        customSSDJsonObj["@odata.type"] = customSSDOdataType;
        // Write Only and will always read as false.
        customSSDJsonObj["CpldReset"] = false;

        if (manufacturingMode != nullptr) {
          customSSDJsonObj["ManufacturingMode"] = *manufacturingMode;
        }
        if (watchdogTriggered != nullptr) {
          customSSDJsonObj["WatchdogTriggered"] = *watchdogTriggered;
        }
        if (fruEepromWriteProtect != nullptr) {
          customSSDJsonObj["FruEepromWriteProtect"] = *fruEepromWriteProtect;
        }
        if (controllerOtpWriteProtect != nullptr) {
          customSSDJsonObj[otpWriteProtectProperty] =
              *controllerOtpWriteProtect;
        }
        if (triggerPowerCycle != nullptr) {
          customSSDJsonObj["TriggerPowerCycle"] = *triggerPowerCycle;
        }
        if (triggerReset != nullptr) {
          customSSDJsonObj["TriggerReset"] = *triggerReset;
        }
        if (disableWatchdog != nullptr) {
          customSSDJsonObj["DisableWatchdog"] = *disableWatchdog;
        }
        if (debugMode != nullptr) {
          customSSDJsonObj["DebugMode"] = *debugMode;
        }
        if (controllerOtpWriteEnable != nullptr) {
          customSSDJsonObj[otpWriteEnableProperty] = *controllerOtpWriteEnable;
        }
        if (spiImgSelect != nullptr) {
          customSSDJsonObj["SpiImgSelect"] = *spiImgSelect;
        }
        if (bootFailureCount != nullptr) {
          customSSDJsonObj["BootFailureCount"] = *bootFailureCount;
        }
        if (pwrseqState != nullptr) {
          customSSDJsonObj["PwrseqState"] = *pwrseqState;
        }
        if (uptimeInSeconds != nullptr) {
          customSSDJsonObj["UptimeInSeconds"] = *uptimeInSeconds;
        }
        if (uptimeInMinutes != nullptr) {
          customSSDJsonObj["UptimeInMinutes"] = *uptimeInMinutes;
        }
        if (pgoodVdd12v0Ssd != nullptr) {
          customSSDJsonObj["PgoodVdd12v0Ssd"] = *pgoodVdd12v0Ssd;
        }
        if (pgoodVddPcMor != nullptr) {
          customSSDJsonObj["PgoodVddPcMor"] = *pgoodVddPcMor;
        }
        if (pgoodVdd3v3Pcie != nullptr) {
          customSSDJsonObj["PgoodVdd3v3Pcie"] = *pgoodVdd3v3Pcie;
        }
        if (pgoodVdd0v83Mor != nullptr) {
          customSSDJsonObj["PgoodVdd0v83Mor"] = *pgoodVdd0v83Mor;
        }
        if (pgoodVttVrefca != nullptr) {
          customSSDJsonObj["PgoodVttVrefca"] = *pgoodVttVrefca;
        }
        if (pgoodVddFlashVcc != nullptr) {
          customSSDJsonObj["PgoodVddFlashVcc"] = *pgoodVddFlashVcc;
        }
        if (pgood12vFlashVpp != nullptr) {
          customSSDJsonObj["Pgood12vFlashVpp"] = *pgood12vFlashVpp;
        }
        if (cpldVersion != nullptr) {
          customSSDJsonObj["CpldVersion"] = *cpldVersion;
        }

        customSSDJsonObj["Name"] = std::string(customSSD) + " GPIO Action Info";
      });

  managedStore::GetManagedObjectStore()->getAllProperties(
      connection, path, "xyz.openbmc_project.Inventory.Decorator.Asset",
      context,
      [asyncResp](
          const boost::system::error_code ec3,
          const std::vector<
              std::pair<std::string, dbus::utility::DbusVariantType>>& asset) {
        if (ec3) {
          // this interface isn't necessary
          return;
        }
        nlohmann::json::object_t customSSDFruEeprom;

        const std::string* partNumber = nullptr;
        const std::string* serialNumber = nullptr;
        const std::string* manufacturer = nullptr;
        const std::string* model = nullptr;
        const std::string* manufactureDate = nullptr;

        const bool assetSuccess = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), asset, "PartNumber", partNumber,
            "SerialNumber", serialNumber, "Manufacturer", manufacturer, "Model",
            model, "ManufactureDate", manufactureDate);
        if (!assetSuccess) {
          BMCWEB_LOG_CRITICAL << "Failed to parse Arguments for "
                              << std::string(customSSD);
          return;
        }
        customSSDFruEeprom["DeviceName"] = std::string(customSSD);
        // If we get to this point, then it is enabled.
        customSSDFruEeprom["Validity"] = "Enabled";
        if (partNumber != nullptr) {
          customSSDFruEeprom["BrdPartNumber"] = *partNumber;
        }
        if (serialNumber != nullptr) {
          customSSDFruEeprom["BrdSerialNumber"] = *serialNumber;
        }
        if (manufacturer != nullptr) {
          customSSDFruEeprom["BrdMfgName"] = *manufacturer;
        }
        if (model != nullptr) {
          customSSDFruEeprom["BrdProductName"] = *model;
        }
        if (manufactureDate != nullptr) {
          customSSDFruEeprom["BrdMfgTime"] = *manufactureDate;
        }
        asyncResp->res.jsonValue["Links"]["Oem"]["Google"]
                                [std::string(customSSD)]["FruEeprom"] =
            std::move(customSSDFruEeprom);
      });
}

inline void getDriveFromChassis(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::shared_ptr<HealthPopulate>& health,
    const sdbusplus::message::object_path& storagePath) {
  const std::array<std::string_view, 2> interfaces = {
      "xyz.openbmc_project.Inventory.Item.Board",
      "xyz.openbmc_project.Inventory.Item.Chassis"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getAssociatedSubTreePaths(
      storagePath / "chassis",
      sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
      interfaces, requestContext,
      [asyncResp, health, storagePath](
          const boost::system::error_code ec,
          const dbus::utility::MapperGetSubTreePathsResponse& chassisList) {
        if (ec) {
          BMCWEB_LOG_ERROR << "Chassis mapper call error";
          messages::internalError(asyncResp->res);
          return;
        }

        if (chassisList.empty()) {
          BMCWEB_LOG_DEBUG << "Can not find the Chassis containing the drive";
          return;
        }

        if (chassisList.size() != 1) {
          BMCWEB_LOG_ERROR << "Storage is not associated with only one chassis";
          messages::internalError(asyncResp->res);
          return;
        }

        const std::string& chassisPath = chassisList.front();
        std::string chassisId =
            sdbusplus::message::object_path(chassisPath).filename();
        if (chassisId.empty()) {
          BMCWEB_LOG_ERROR << "Failed to find filename in " << chassisPath;
          return;
        }
        getDrives(asyncResp, health, storagePath, chassisId);
      });
}

inline void handleGetSystemStorage(
    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;
  }

  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Inventory.Item.Storage"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
      [asyncResp, systemName, storageId](
          const boost::system::error_code ec,
          const dbus::utility::MapperGetSubTreePathsResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "requestRoutesStorage DBUS response error";
          messages::resourceNotFound(asyncResp->res, "#Storage.v1_13_0.Storage",
                                     storageId);
          return;
        }
        auto storage = std::find_if(
            subtree.begin(), subtree.end(),
            [&storageId](const std::string& path) {
              return sdbusplus::message::object_path(path).filename() ==
                     storageId;
            });
        if (storage == subtree.end()) {
          messages::resourceNotFound(asyncResp->res, "#Storage.v1_13_0.Storage",
                                     storageId);
          return;
        }

        checkSystemAndStorage(asyncResp, systemName, storageId);
        asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_13_0.Storage";
        asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
            "redfish", "v1", "Systems", systemName.c_str(), "Storage",
            storageId);
        asyncResp->res.jsonValue["Name"] = "Storage";
        asyncResp->res.jsonValue["Id"] = storageId;
        asyncResp->res.jsonValue["Status"]["State"] = "Enabled";

        auto health = std::make_shared<HealthPopulate>(asyncResp);
#ifdef HEALTH_POPULATE
        health->populate();
#endif

        getDriveFromChassis(asyncResp, health, *storage);
        asyncResp->res.jsonValue["Controllers"]["@odata.id"] =
            crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                         systemName.c_str(), "Storage",
                                         storageId, "Controllers");
        asyncResp->res.jsonValue["Volumes"]["@odata.id"] =
            crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                         systemName.c_str(), "Storage",
                                         storageId, "Volumes");
      });
}

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

  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Inventory.Item.Storage"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
      [asyncResp, storageId](
          const boost::system::error_code ec,
          const dbus::utility::MapperGetSubTreePathsResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "requestRoutesStorage DBUS response error";
          messages::resourceNotFound(asyncResp->res, "#Storage.v1_13_0.Storage",
                                     storageId);
          return;
        }
        auto storage = std::find_if(
            subtree.begin(), subtree.end(),
            [&storageId](const std::string& storage) {
              return sdbusplus::message::object_path(storage).filename() ==
                     storageId;
            });
        if (storage == subtree.end()) {
          messages::resourceNotFound(asyncResp->res, "#Storage.v1_13_0.Storage",
                                     storageId);
          return;
        }

        asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_13_0.Storage";
        asyncResp->res.jsonValue["@odata.id"] =
            crow::utility::urlFromPieces("redfish", "v1", "Storage", storageId);
        asyncResp->res.jsonValue["Name"] = "Storage";
        asyncResp->res.jsonValue["Id"] = storageId;
        asyncResp->res.jsonValue["Status"]["State"] = "Enabled";

        // Storage subsystem to Stroage link.
        storage_utils::getSystemPathFromStorage(
            asyncResp, *storage,
            [asyncResp, storageId](std::optional<std::string_view> systemPath) {
              nlohmann::json::array_t storageServices;
              nlohmann::json::object_t storageService;

              std::string systemName =
                  systemPath ? std::filesystem::path(*systemPath).filename()
                             : "system";
              storageService["@odata.id"] = crow::utility::urlFromPieces(
                  "redfish", "v1", "Systems", systemName, "Storage", storageId);
              storageServices.emplace_back(storageService);
              asyncResp->res.jsonValue["Links"]["StorageServices"] =
                  std::move(storageServices);
              asyncResp->res.jsonValue["Links"]["StorageServices@odata.count"] =
                  1;
            });
      });
}

inline void requestRoutesStorage(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/<str>/")
      .privileges(redfish::privileges::getStorage)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetSystemStorage, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Storage/<str>/")
      .privileges(redfish::privileges::getStorage)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetStorage, std::ref(app)));
}

inline void getDriveAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& connectionName,
                          const std::string& path) {
  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      connectionName, path, "xyz.openbmc_project.Inventory.Decorator.Asset",
      context,
      [asyncResp](const boost::system::error_code& ec,
                  const std::vector<
                      std::pair<std::string, dbus::utility::DbusVariantType>>&
                      propertiesList) {
        if (ec) {
          // this interface isn't necessary
          return;
        }

        const std::string* partNumber = nullptr;
        const std::string* serialNumber = nullptr;
        const std::string* manufacturer = nullptr;
        const std::string* model = nullptr;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
            partNumber, "SerialNumber", serialNumber, "Manufacturer",
            manufacturer, "Model", model);

        if (!success) {
          messages::internalError(asyncResp->res);
          return;
        }

        if (partNumber != nullptr) {
          asyncResp->res.jsonValue["PartNumber"] = *partNumber;
        }

        if (serialNumber != nullptr) {
          asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
        }

        if (manufacturer != nullptr) {
          asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
        }

        if (model != nullptr) {
          asyncResp->res.jsonValue["Model"] = *model;
        }
      });
}

inline void getDrivePresent(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                            const std::string& connectionName,
                            const std::string& path) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  dbus_utils::getProperty<bool>(
      connectionName, path, "xyz.openbmc_project.Inventory.Item", "Present",
      requestContext,
      [asyncResp, path](const boost::system::error_code& ec,
                        const bool isPresent) {
        // this interface isn't necessary, only check it if
        // we get a good return
        if (ec) {
          return;
        }

        if (!isPresent) {
          asyncResp->res.jsonValue["Status"]["State"] = "Absent";
        }
      });
}

inline void getDriveState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& connectionName,
                          const std::string& path) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  dbus_utils::getProperty<bool>(
      connectionName, path, "xyz.openbmc_project.State.Drive", "Rebuilding",
      requestContext,
      [asyncResp](const boost::system::error_code& ec, const bool updating) {
        // this interface isn't necessary, only check it
        // if we get a good return
        if (ec) {
          return;
        }

        // updating and disabled in the backend shouldn't be
        // able to be set at the same time, so we don't need
        // to check for the race condition of these two
        // calls
        if (updating) {
          asyncResp->res.jsonValue["Status"]["State"] = "Updating";
        }
      });
}

inline std::optional<std::string> convertDriveType(const std::string& type) {
  if (type == "xyz.openbmc_project.Inventory.Item.Drive.DriveType.HDD") {
    return "HDD";
  }
  if (type == "xyz.openbmc_project.Inventory.Item.Drive.DriveType.SSD") {
    return "SSD";
  }

  return std::nullopt;
}

inline void addResetLinks(nlohmann::json& driveReset,
                          const std::string& driveId,
                          const std::string& chassisId) {
  driveReset["target"] =
      crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId,
                                   "Drives", driveId, "Actions", "Drive.Reset");
  driveReset["@Redfish.ActionInfo"] =
      crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId,
                                   "Drives", driveId, "ResetActionInfo");
}

inline std::optional<std::string> convertDriveProtocol(
    const std::string& proto) {
  if (proto == "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol.SAS") {
    return "SAS";
  }
  if (proto == "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol.SATA") {
    return "SATA";
  }
  if (proto == "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol.NVMe") {
    return "NVMe";
  }
  if (proto == "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol.FC") {
    return "FC";
  }
  if (proto == "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol.eMMC") {
    return "eMMC";
  }

  return std::nullopt;
}

inline void getDriveItemProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& driveId, const std::optional<std::string>& chassisId,
    const std::string& connectionName, const std::string& path,
    bool hasDriveState) {
  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      connectionName, path, "xyz.openbmc_project.Inventory.Item.Drive", context,
      [asyncResp, driveId, chassisId, hasDriveState](
          const boost::system::error_code& ec,
          const std::vector<std::pair<
              std::string, dbus::utility::DbusVariantType>>& propertiesList) {
        if (ec) {
          // this interface isn't required
          return;
        }
        const std::string* encryptionStatus = nullptr;
        const bool* isLocked = nullptr;
        for (const std::pair<std::string, dbus::utility::DbusVariantType>&
                 property : propertiesList) {
          const std::string& propertyName = property.first;
          if (propertyName == "Type") {
            const std::string* value =
                std::get_if<std::string>(&property.second);
            if (value == nullptr) {
              // illegal property
              BMCWEB_LOG_ERROR << "Illegal property: Type";
              messages::internalError(asyncResp->res);
              return;
            }

            std::optional<std::string> mediaType = convertDriveType(*value);
            if (!mediaType) {
              BMCWEB_LOG_ERROR << "Unsupported DriveType Interface: " << *value;
              messages::internalError(asyncResp->res);
              return;
            }

            asyncResp->res.jsonValue["MediaType"] = *mediaType;
          } else if (propertyName == "Capacity") {
            const uint64_t* capacity = std::get_if<uint64_t>(&property.second);
            if (capacity == nullptr) {
              BMCWEB_LOG_ERROR << "Illegal property: Capacity";
              messages::internalError(asyncResp->res);
              return;
            }
            if (*capacity == 0) {
              // drive capacity not known
              continue;
            }

            asyncResp->res.jsonValue["CapacityBytes"] = *capacity;
          } else if (propertyName == "Protocol") {
            const std::string* value =
                std::get_if<std::string>(&property.second);
            if (value == nullptr) {
              BMCWEB_LOG_ERROR << "Illegal property: Protocol";
              messages::internalError(asyncResp->res);
              return;
            }

            std::optional<std::string> proto = convertDriveProtocol(*value);
            if (!proto) {
              BMCWEB_LOG_ERROR << "Unsupported DrivePrototype Interface: "
                               << *value;
              messages::internalError(asyncResp->res);
              return;
            }
            asyncResp->res.jsonValue["Protocol"] = *proto;
          } else if (propertyName == "PredictedMediaLifeLeftPercent") {
            const uint8_t* lifeLeft = std::get_if<uint8_t>(&property.second);
            if (lifeLeft == nullptr) {
              BMCWEB_LOG_ERROR
                  << "Illegal property: PredictedMediaLifeLeftPercent";
              messages::internalError(asyncResp->res);
              return;
            }
            // 255 means reading the value is not supported
            if (*lifeLeft != 255) {
              asyncResp->res.jsonValue["PredictedMediaLifeLeftPercent"] =
                  *lifeLeft;
            }
          } else if (propertyName == "Resettable" && hasDriveState) {
            const bool* value = std::get_if<bool>(&property.second);
            // If Resettable flag is not present, its not considered a
            // failure.
            if (value != nullptr && *value && chassisId.has_value()) {
              addResetLinks(asyncResp->res.jsonValue["Actions"]["#Drive.Reset"],
                            driveId, *chassisId);
            }
          } else if (propertyName == "EncryptionStatus") {
            encryptionStatus = std::get_if<std::string>(&property.second);
            if (encryptionStatus == nullptr) {
              BMCWEB_LOG_ERROR << "Illegal property: EncryptionStatus";
              messages::internalError(asyncResp->res);
              return;
            }
          } else if (propertyName == "Locked") {
            isLocked = std::get_if<bool>(&property.second);
            if (isLocked == nullptr) {
              BMCWEB_LOG_ERROR << "Illegal property: Locked";
              messages::internalError(asyncResp->res);
              return;
            }
          }
        }

        if (encryptionStatus == nullptr || isLocked == nullptr ||
            *encryptionStatus ==
                "xyz.openbmc_project.Inventory.Item.Drive.DriveEncryptionState."
                "Unknown") {
          return;
        }
        if (*encryptionStatus !=
            "xyz.openbmc_project.Inventory.Item.Drive.DriveEncryptionState."
            "Encrypted") {
          // "The drive is not currently encrypted."
          asyncResp->res.jsonValue["EncryptionStatus"] =
              drive::EncryptionStatus::Unencrypted;
          return;
        }
        if (*isLocked) {
          // "The drive is currently encrypted and the data is not
          // accessible to the user."
          asyncResp->res.jsonValue["EncryptionStatus"] =
              drive::EncryptionStatus::Locked;
          return;
        }
        // if not locked
        // "The drive is currently encrypted but the data is accessible
        // to the user in unencrypted form."
        asyncResp->res.jsonValue["EncryptionStatus"] =
            drive::EncryptionStatus::Unlocked;
      });
}

inline void getDriveErase(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& chassisId,
                          const std::string& driveName) {
  auto eraseUrl = crow::utility::urlFromPieces("redfish", "v1", "Chassis",
                                               chassisId, "Drives", driveName,
                                               "Actions", "Drive.SecureErase");
  asyncResp->res.jsonValue["Actions"]["#Drive.SecureErase"]["target"] =
      eraseUrl;
}

static void addAllDriveInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                            const std::string& driveId,
                            const std::string& connectionName,
                            const std::string& path,
                            const std::vector<std::string>& interfaces,
                            const std::string& chassisId) {
  bool driveInterface = false;
  bool driveStateInterface = false;
  for (const std::string& interface : interfaces) {
    if (interface == "xyz.openbmc_project.Inventory.Decorator.Asset") {
      getDriveAsset(asyncResp, connectionName, path);
    } else if (interface == "xyz.openbmc_project.Inventory.Item") {
      getDrivePresent(asyncResp, connectionName, path);
    } else if (interface == "xyz.openbmc_project.State.Drive") {
      driveStateInterface = true;
      getDriveState(asyncResp, connectionName, path);
    } else if (interface == "xyz.openbmc_project.Inventory.Item.Drive") {
      driveInterface = true;
    } else if (interface == "xyz.openbmc_project.Inventory.Item.DriveErase") {
      getDriveErase(asyncResp, chassisId, driveId);
    }
  }

  if (driveInterface) {
    getDriveItemProperties(asyncResp, driveId, chassisId, connectionName, path,
                           driveStateInterface);
    storage_utils::tryGetLocation(asyncResp, connectionName, path,
                                  storage_utils::driveInterface, interfaces,
                                  "/PhysicalLocation"_json_pointer);
  }
}

/**
 * Chassis drives, this URL will show all the DriveCollection
 * information
 */
inline void chassisDriveCollectionGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  // mapper call lambda
  constexpr std::array<std::string_view, 2> interfaces = {
      "xyz.openbmc_project.Inventory.Item.Board",
      "xyz.openbmc_project.Inventory.Item.Chassis"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
      [asyncResp, chassisId, requestContext](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          if (ec == boost::system::errc::host_unreachable) {
            messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
            return;
          }
          messages::internalError(asyncResp->res);
          return;
        }

        // Iterate over all retrieved ObjectPaths.
        for (const auto& [path, connectionNames] : subtree) {
          sdbusplus::message::object_path objPath(path);
          if (objPath.filename() != chassisId) {
            continue;
          }

          if (connectionNames.empty()) {
            BMCWEB_LOG_ERROR << "Got 0 Connection names";
            continue;
          }

          asyncResp->res.jsonValue["@odata.type"] =
              "#DriveCollection.DriveCollection";
          asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
              "redfish", "v1", "Chassis", chassisId, "Drives");
          asyncResp->res.jsonValue["Name"] = "Drive Collection";

          // Association lambda
          dbus_utils::getAssociationEndPoints(
              path + "/drive", requestContext,
              [asyncResp, chassisId](
                  const boost::system::error_code& ec3,
                  const dbus::utility::MapperEndPoints& resp) {
                if (ec3) {
                  BMCWEB_LOG_ERROR << "Error in chassis Drive association ";
                }
                nlohmann::json& members = asyncResp->res.jsonValue["Members"];
                // important if array is empty
                members = nlohmann::json::array();

                std::vector<std::string> leafNames;
                for (const auto& drive : resp) {
                  sdbusplus::message::object_path drivePath(drive);
                  leafNames.emplace_back(drivePath.filename());
                }

                std::sort(leafNames.begin(), leafNames.end(),
                          AlphanumLess<std::string>());

                for (const auto& leafName : leafNames) {
                  nlohmann::json::object_t member;
                  member["@odata.id"] = crow::utility::urlFromPieces(
                      "redfish", "v1", "Chassis", chassisId, "Drives",
                      leafName);
                  members.emplace_back(std::move(member));
                  // navigation links will be registered in next patch set
                }
                asyncResp->res.jsonValue["Members@odata.count"] = resp.size();
              });  // end association lambda
        }  // end Iterate over all retrieved ObjectPaths
      });
}

inline void requestRoutesChassisDrive(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Drives/")
      .privileges(redfish::privileges::getDriveCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(chassisDriveCollectionGet, std::ref(app)));
}

inline void storageVolumes(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const sdbusplus::message::object_path& storagePath,
    std::function<void(const boost::system::error_code& ec,
                       const std::vector<std::string>& volPaths)>&& cb) {
  // Get list of attached volumes
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Inventory.Item.Volume"};
  managedStore::ManagedObjectStoreContext context(asyncResp);
  redfish::storage_utils::getAssociatedSubTreePaths(
      storagePath / "containing",
      sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
      interfaces, context,
      [cb](const boost::system::error_code& ec,
           const std::vector<std::string>& volPaths) { cb(ec, volPaths); });
}

inline void buildDrive(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::string& chassisId,
                       const std::string& driveName,
                       const boost::system::error_code& ec,
                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
  if (ec) {
    BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
    messages::internalError(asyncResp->res);
    return;
  }

  // Iterate over all retrieved ObjectPaths.
  for (const auto& [path, connectionNames] : subtree) {
    sdbusplus::message::object_path objPath(path);
    if (objPath.filename() != driveName) {
      continue;
    }

    if (connectionNames.empty()) {
      BMCWEB_LOG_ERROR << "Got 0 Connection names";
      continue;
    }

    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisId, "Drives", driveName);

    asyncResp->res.jsonValue["@odata.type"] = "#Drive.v1_7_0.Drive";
    asyncResp->res.jsonValue["Name"] = driveName;
    asyncResp->res.jsonValue["Id"] = driveName;
    // default it to Enabled
    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";

    nlohmann::json::object_t linkChassisNav;
    linkChassisNav["@odata.id"] =
        crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId);
    asyncResp->res.jsonValue["Links"]["Chassis"] = linkChassisNav;

    // mapper call chassis
    storage_utils::findStorage(
        asyncResp, driveName,
        [asyncResp,
         driveName](const sdbusplus::message::object_path& storagePath) {
          storage_utils::getSystemPathFromStorage(
              asyncResp, storagePath,
              [asyncResp, storagePath,
               driveName](std::optional<std::string_view> systemPath) {
                std::string systemName =
                    systemPath ? std::filesystem::path(*systemPath).filename()
                               : "system";
                storageVolumes(
                    asyncResp, storagePath,
                    [asyncResp, systemName, driveName](
                        const boost::system::error_code& ec,
                        const dbus::utility::MapperGetSubTreePathsResponse&
                            volumeList) {
                      nlohmann::json::array_t volumes;
                      if (ec || volumeList.empty()) {
                        // No association found, just return.
                        return;
                      }

                      for (const std::string& path : volumeList) {
                        std::string id =
                            sdbusplus::message::object_path(path).filename();
                        if (id.empty()) {
                          // Empty list, just return.
                          return;
                        }
                        nlohmann::json::object_t volume;
                        volume["@odata.id"] = crow::utility::urlFromPieces(
                            "redfish", "v1", "Systems", systemName, "Storage",
                            driveName, "Volumes", id);
                        volumes.emplace_back(volume);
                      }
                      asyncResp->res.jsonValue["Links"]["Volumes@odata.count"] =
                          volumes.size();
                      asyncResp->res.jsonValue["Links"]["Volumes"] =
                          std::move(volumes);
                    });
              });
        });

    addAllDriveInfo(asyncResp, driveName, connectionNames[0].first, path,
                    connectionNames[0].second, chassisId);
  }
}

inline void matchAndFillDrive(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& driveName,
    const std::vector<std::string>& resp) {
  for (const std::string& drivePath : resp) {
    sdbusplus::message::object_path path(drivePath);
    std::string leaf = path.filename();
    if (leaf != driveName) {
      continue;
    }
    //  mapper call drive
    constexpr std::array<std::string_view, 1> driveInterface = {
        "xyz.openbmc_project.Inventory.Item.Drive"};
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        "/xyz/openbmc_project/inventory", 0, driveInterface, requestContext,
        [asyncResp, chassisId, driveName](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreeResponse& subtree) {
          buildDrive(asyncResp, chassisId, driveName, ec, subtree);
        });
    return;
  }
  messages::resourceNotFound(asyncResp->res, "#Drive.v1_7_0.Drive", driveName);
}

struct EraseParams {
  enum Action : std::uint8_t {
    CryptoErase,
    BlockErase,
    Overwrite,
  } action;

  static std::optional<EraseParams> parse(
      const crow::Request& req,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
    // Redfish allows sanitizationType to be defaulted, though we don't
    // know a good default at present, leave it mandatory.
    std::string sanitizationType;

    if (!json_util::readJsonAction(req, asyncResp->res, "SanitizationType",
                                   sanitizationType)) {
      BMCWEB_LOG_DEBUG << "Missing request json parameters";
      return std::nullopt;
    }

    Action action = Action::CryptoErase;
    if (sanitizationType == "BlockErase") {
      action = Action::BlockErase;
    } else if (sanitizationType == "CryptographicErase") {
      action = Action::CryptoErase;
    } else if (sanitizationType == "Overwrite") {
      // Redfish defines an optional "OverwritePasses" parameter, we
      // don't handle that at the moment. If the client passes it, the
      // readJsonAction will fail it.
      action = Action::Overwrite;
    } else {
      messages::actionParameterValueNotInList(asyncResp->res, sanitizationType,
                                              "SanitizationType",
                                              "Drive.SecureErase");
      return std::nullopt;
    }

    return EraseParams{.action = action};
  }

  std::string actionName() const {
    switch (action) {
      case Action::CryptoErase:
        return "xyz.openbmc_project.Inventory.Item.DriveErase.EraseAction."
               "CryptoErase";
      case Action::BlockErase:
        return "xyz.openbmc_project.Inventory.Item.DriveErase.EraseAction."
               "BlockErase";
      case Action::Overwrite:
        return "xyz.openbmc_project.Inventory.Item.DriveErase.EraseAction."
               "Overwrite";
    }
    return "unreachable";
  }
};

inline void eraseTaskUpdate(bool eraseInProgress,
                            const std::shared_ptr<task::TaskData>& taskData,
                            const std::string& connectionName,
                            const std::string& drivePath) {
  if (eraseInProgress) {
    // nothing to do
    return;
  }

  // has finished, either success or failure
  taskData->stopMonitor();

  // Have to create a new Resp here as we cannot use the original resp or it
  // never goes out of scope This resp will not have a strand associated with it
  // which is okay because this will never be multithreaded
  auto resp = std::make_shared<bmcweb::AsyncResp>(nullptr);
  managedStore::ManagedObjectStoreContext context(resp);
  redfish::storage_utils::getAllProperties(
      connectionName, drivePath,
      "xyz.openbmc_project.Inventory.Item.DriveErase", context,
      [taskData](
          const boost::system::error_code& ec,
          const std::vector<
              std::pair<std::string, dbus::utility::DbusVariantType>>& props) {
        if (ec) {
          taskData->messages.emplace_back(messages::internalError());
          taskData->state = "Exception";
          taskData->complete(nlohmann::json(),
                             boost::beast::http::status::internal_server_error);
          return;
        }

        std::string errorName;
        std::string errorDescription;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), props, "ErrorName", errorName,
            "ErrorDescription", errorDescription);

        if (!success) {
          taskData->messages.emplace_back(messages::internalError());
          taskData->state = "Exception";
          taskData->complete(nlohmann::json(),
                             boost::beast::http::status::internal_server_error);
          return;
        }

        if (errorName.empty()) {
          // Erase Success
          taskData->state = "Completed";
          taskData->percentComplete = 100;
          taskData->messages.emplace_back(messages::success());
          taskData->complete();
        } else {
          // Erase Failed
          bmcweb::AsyncResp resp(nullptr);
          storageAddDbusError(resp.res, "eraseTaskUpdate", "", errorName,
                              errorDescription);
          for (auto& m :
               resp.res.jsonValue["error"][messages::messageAnnotation]) {
            taskData->messages.emplace_back(m);
          }
          taskData->state = "Exception";
          taskData->complete(std::move(resp.res.jsonValue), resp.res.result());
        }
      });
}

inline bool eraseTaskHandler(sdbusplus::message_t& msg,
                             const std::shared_ptr<task::TaskData>& taskData,
                             const std::string& connectionName,
                             const std::string& drivePath) {
  dbus::utility::DBusPropertiesMap props;
  std::string iface;
  msg.read(iface, props);

  if (iface != "xyz.openbmc_project.Inventory.Item.DriveErase") {
    BMCWEB_LOG_DEBUG << "eraseTaskHandler wrong interface";
    return !task::completed;
  }

  std::optional<bool> inProgress;
  std::optional<double> erasePercentage;
  sdbusplus::unpackPropertiesNoThrow(dbus_utils::UnpackErrorPrinter(), props,
                                     "EraseInProgress", inProgress,
                                     "ErasePercentage", erasePercentage);

  if (erasePercentage) {
    BMCWEB_LOG_DEBUG << "eraseTaskHandler update erasePercentage "
                     << *erasePercentage;
    taskData->percentComplete = static_cast<int>(*erasePercentage);
  }

  if (inProgress) {
    BMCWEB_LOG_DEBUG << "eraseTaskHandler update iniProgress " << *inProgress;
    eraseTaskUpdate(*inProgress, taskData, connectionName, drivePath);
  }

  // completion is handled asynchronously so always return !completed
  return !task::completed;
}

// Clang believes that req is unused even though its captured in lambda
inline void eraseDrive(const crow::Request& req,
                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::string& connectionName,
                       const std::string& drivePath,
                       const EraseParams& params) {
#ifdef UNIT_TEST_BUILD
  dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
      managedStore::GetManagedObjectStore())
      ->PostDbusCallToIoContextThreadSafe(
#else
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
#endif
          asyncResp->strand_,
          [req, asyncResp, connectionName, drivePath](
              const boost::system::error_code ec,
              const sdbusplus::message_t& msg) {
            // Failure returned from NVMe
            const ::sd_bus_error* sd_err = msg.get_error();
            if (sd_err != nullptr) {
              storageAddDbusError(asyncResp->res, "Drive Erase", "",
                                  sd_err->name, sd_err->message);
              return;
            }

            if (ec) {
              BMCWEB_LOG_DEBUG << "Erase dbus error " << ec;
              messages::internalError(asyncResp->res);
              return;
            }

            // success, create the async task
            BMCWEB_LOG_DEBUG << "erase started";
            std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
                [connectionName, drivePath](
                    const boost::system::error_code& err,
                    sdbusplus::message_t& taskMsg,
                    const std::shared_ptr<task::TaskData>& taskData) {
                  if (err) {
                    // Internal error in property signal callback?
                    BMCWEB_LOG_ERROR << drivePath << ": Error in task";
                    taskData->messages.emplace_back(messages::internalError());
                    taskData->state = "Cancelled";
                    return task::completed;
                  }

                  return eraseTaskHandler(taskMsg, taskData, connectionName,
                                          drivePath);
                },
                "type='signal',interface='org.freedesktop.DBus.Properties',"
                "member='PropertiesChanged',arg0='xyz.openbmc_project."
                "Inventory."
                "Item.DriveErase',"
                "path='" +
                    drivePath + "'");

            task->startTimer(std::chrono::minutes(180));
            task->populateResp(asyncResp->res);
            task->payload.emplace(req);

            // Erase may have completed prior to Task watching for signals, so
            // poll once.
            managedStore::ManagedObjectStoreContext context(asyncResp);
            redfish::storage_utils::getProperty<bool>(
                connectionName, drivePath,
                "xyz.openbmc_project.Inventory.Item.DriveErase",
                "EraseInProgress", context,
                [task, connectionName, drivePath](
                    const boost::system::error_code& ec2, bool inProgress) {
                  if (ec2) {
                    BMCWEB_LOG_DEBUG << "erase poll error: " << ec2;
                    return;
                  }

                  eraseTaskUpdate(inProgress, task, connectionName, drivePath);
                });
          },
          connectionName, drivePath,
          "xyz.openbmc_project.Inventory.Item.DriveErase", "Erase",
          params.actionName());
}

inline void matchAndEraseDrive(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::vector<std::string>& drivePaths, const std::string& driveName,
    const EraseParams& params) {
  // Match the driveName
  int found = 0;
  std::string drivePath;
  for (const std::string& d : drivePaths) {
    sdbusplus::message::object_path path(d);
    std::string leaf = path.filename();
    if (leaf == driveName) {
      found++;
      drivePath = d;
    }
  }

  if (found > 1) {
    // Sanity check
    BMCWEB_LOG_DEBUG << "Multiple drives match name " << driveName;
    messages::internalError(asyncResp->res);
    return;
  }
  if (found == 0) {
    messages::resourceNotFound(asyncResp->res, "#Drive.v1_7_0.Drive",
                               driveName);
    return;
  }

  // Find the connection
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Inventory.Item.DriveErase"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getDbusObject(
      drivePath, interfaces, requestContext,
      [req, asyncResp, params, drivePath](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetObject& services) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          messages::internalError(asyncResp->res);
          return;
        }

        if (services.size() != 1) {
          BMCWEB_LOG_DEBUG << "multiple serviceInterfaces entries";
          messages::internalError(asyncResp->res);
          return;
        }
        auto connectionName = services.front().first;

        // Perform the erase
        eraseDrive(req, asyncResp, connectionName, drivePath, params);
      });
}

// Find Chassis with chassisId and the Drives associated to it.
inline void findChassisDrive(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId,
    std::function<void(const boost::system::error_code ec3,
                       const std::vector<std::string>& resp)>&& cb) {
  constexpr std::array<std::string_view, 2> interfaces = {
      "xyz.openbmc_project.Inventory.Item.Board",
      "xyz.openbmc_project.Inventory.Item.Chassis"};
  // mapper call chassis
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
      [asyncResp, chassisId, cb, requestContext](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          messages::internalError(asyncResp->res);
          return;
        }

        // Iterate over all retrieved ObjectPaths.
        int found = 0;
        std::string chassisPath;
        for (const auto& [path, connectionNames] : subtree) {
          sdbusplus::message::object_path objPath(path);
          if (objPath.filename() != chassisId) {
            continue;
          }

          if (connectionNames.empty()) {
            BMCWEB_LOG_ERROR << "Got 0 Connection names";
            continue;
          }
          found++;
          chassisPath = path;
        }
        if (found > 1) {
          BMCWEB_LOG_ERROR << "Multiple chassis match";
          messages::internalError(asyncResp->res);
          return;
        }
        if (found == 0) {
          messages::resourceNotFound(asyncResp->res, "#Chassis.v1_14_0.Chassis",
                                     chassisId);
          return;
        }
        dbus_utils::getAssociationEndPoints(chassisPath + "/drive",
                                            requestContext, cb);
      });
}

inline void handleChassisDriveGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& driveName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  findChassisDrive(
      asyncResp, chassisId,
      [asyncResp, chassisId, driveName](const boost::system::error_code ec,
                                        const std::vector<std::string>& resp) {
        if (ec) {
          return;  // no drives = no failures
        }
        matchAndFillDrive(asyncResp, chassisId, driveName, resp);
      });
}

inline void handleDriveSecureErase(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& driveName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  auto p = EraseParams::parse(req, asyncResp);
  if (!p) {
    return;
  }
  EraseParams params = *p;

  // Find paths of drives associated with the ChassisId
  findChassisDrive(asyncResp, chassisId,
                   [req, asyncResp, chassisId, driveName, params](
                       const boost::system::error_code ec,
                       const std::vector<std::string>& drivePaths) {
                     if (ec) {
                       BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
                       messages::internalError(asyncResp->res);
                       return;
                     }
                     matchAndEraseDrive(req, asyncResp, drivePaths, driveName,
                                        params);
                   });
}

/**
 * This URL will show the drive interface for the specific drive in the chassis
 */
inline void requestRoutesChassisDriveName(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Drives/<str>/")
      .privileges(redfish::privileges::getChassis)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleChassisDriveGet, std::ref(app)));

  BMCWEB_ROUTE(
      app, "/redfish/v1/Chassis/<str>/Drives/<str>/Actions/Drive.SecureErase")
      .privileges(redfish::privileges::postDrive)
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handleDriveSecureErase, std::ref(app)));
}

inline void setResetType(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& driveId, const std::string& action,
    const dbus::utility::MapperGetSubTreeResponse& subtree) {
  auto driveState =
      std::find_if(subtree.begin(), subtree.end(), [&driveId](auto& object) {
        const sdbusplus::message::object_path path(object.first);
        return path.filename() == driveId;
      });

  if (driveState == subtree.end()) {
    messages::resourceNotFound(asyncResp->res, "Drive Action", driveId);
    return;
  }

  const std::string& path = driveState->first;
  const std::vector<std::pair<std::string, std::vector<std::string>>>&
      connectionNames = driveState->second;

  if (connectionNames.size() != 1) {
    BMCWEB_LOG_ERROR << "Connection size " << connectionNames.size()
                     << ", not equal to 1";
    messages::internalError(asyncResp->res);
    return;
  }

#ifdef UNIT_TEST_BUILD
  dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
      managedStore::GetManagedObjectStore())
      ->setProperty(
#else
  managedStore::GetManagedObjectStore()->setProperty(
#endif
          connectionNames[0].first, path, "xyz.openbmc_project.State.Drive",
          "RequestedDriveTransition", action,
          [asyncResp, action](const boost::system::error_code ec) {
            if (ec) {
              BMCWEB_LOG_ERROR << "[Set] Bad D-Bus request error for " << action
                               << " : " << ec;
              messages::internalError(asyncResp->res);
              return;
            }
            messages::success(asyncResp->res);
          });
}

/**
 * Performs drive reset action.
 *
 * @param[in] asyncResp - Shared pointer for completing asynchronous calls
 * @param[in] driveId   - D-bus filename to identify the Drive
 * @param[in] resetType - Reset type for the Drive
 */
inline void performDriveReset(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& driveId, std::optional<std::string> resetType) {
  std::string action;
  if (!resetType || *resetType == "PowerCycle") {
    action = "xyz.openbmc_project.State.Drive.Transition.Powercycle";
  } else if (*resetType == "ForceReset") {
    action = "xyz.openbmc_project.State.Drive.Transition.Reboot";
  } else {
    BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: " << *resetType;
    messages::actionParameterNotSupported(asyncResp->res, *resetType,
                                          "ResetType");
    return;
  }

  BMCWEB_LOG_DEBUG << "Reset Drive with " << action;

  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.State.Drive"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
      [asyncResp, driveId, action](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS response error";
          messages::internalError(asyncResp->res);
          return;
        }
        setResetType(asyncResp, driveId, action, subtree);
      });
}

inline void handleChassisDriveReset(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& driveId, const std::optional<std::string>& resetType,
    const std::vector<std::string>& drives) {
  std::unordered_set<std::string> drivesMap(drives.begin(), drives.end());
  constexpr std::array<std::string_view, 2> interfaces = {
      "xyz.openbmc_project.Inventory.Item.Drive",
      "xyz.openbmc_project.State.Drive"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
      [asyncResp, driveId, resetType, drivesMap, requestContext](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_ERROR << "Drive mapper call error ";
          messages::internalError(asyncResp->res);
          return;
        }

        auto drive = std::find_if(
            subtree.begin(), subtree.end(),
            [&driveId, &drivesMap](
                const std::pair<std::string, dbus::utility::MapperServiceMap>&
                    object) {
              return sdbusplus::message::object_path(object.first).filename() ==
                         driveId &&
                     drivesMap.contains(object.first);
            });

        if (drive == subtree.end()) {
          messages::resourceNotFound(asyncResp->res, "Drive Action Reset",
                                     driveId);
          return;
        }

        const std::string& drivePath = drive->first;
        const dbus::utility::MapperServiceMap& driveConnections = drive->second;
        if (driveConnections.size() != 1) {
          BMCWEB_LOG_ERROR << "Connection size " << driveConnections.size()
                           << ", not equal to 1";
          messages::internalError(asyncResp->res);
          return;
        }

        bool driveInterface = false;
        bool driveStateInterface = false;
        for (const std::string& interface : driveConnections[0].second) {
          if (interface == "xyz.openbmc_project.Inventory.Item.Drive") {
            driveInterface = true;
          }
          if (interface == "xyz.openbmc_project.State.Drive") {
            driveStateInterface = true;
          }
        }
        if (!driveInterface || !driveStateInterface) {
          BMCWEB_LOG_ERROR << "Drive does not have the required interfaces ";
          messages::internalError(asyncResp->res);
          return;
        }

        dbus_utils::getProperty<bool>(
            driveConnections[0].first, drivePath,
            "xyz.openbmc_project.Inventory.Item.Drive", "Resettable",
            requestContext,
            [asyncResp, driveId, resetType](
                const boost::system::error_code propEc, bool resettable) {
              if (propEc) {
                BMCWEB_LOG_ERROR << "Failed to get resettable property ";
                messages::internalError(asyncResp->res);
                return;
              }
              if (!resettable) {
                messages::actionNotSupported(
                    asyncResp->res, "The drive does not support resets.");
                return;
              }
              performDriveReset(asyncResp, driveId, resetType);
            });
      });
}

inline void handlePostDriveResetAction(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& driveId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  BMCWEB_LOG_DEBUG << "Post Drive Reset.";

  nlohmann::json jsonRequest;
  std::optional<std::string> resetType;
  if (json_util::processJsonFromRequest(asyncResp->res, req, jsonRequest) &&
      !jsonRequest["ResetType"].empty()) {
    resetType = jsonRequest["ResetType"];
  }

  findChassisDrive(
      asyncResp, chassisId,
      [asyncResp, driveId, resetType](const boost::system::error_code ec,
                                      const std::vector<std::string>& drives) {
        if (ec) {
          BMCWEB_LOG_ERROR << "failed to find drives";
          messages::internalError(asyncResp->res);
          return;  // no drives = no failures
        }
        handleChassisDriveReset(asyncResp, driveId, resetType, drives);
      });
}

/**
 * DriveResetAction class supports the POST method for the Reset (reboot)
 * action.
 */
inline void requestDriveResetAction(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Chassis/<str>/Drives/<str>/Actions/Drive.Reset/")
      .privileges(redfish::privileges::postDrive)
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handlePostDriveResetAction, std::ref(app)));
}

inline void handleChassisDriveResetActionInfo(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& driveId,
    const std::vector<std::string>& drives) {
  std::unordered_set<std::string> drivesMap(drives.begin(), drives.end());

  constexpr std::array<std::string_view, 2> interfaces = {
      "xyz.openbmc_project.Inventory.Item.Drive",
      "xyz.openbmc_project.State.Drive"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
      [asyncResp, chassisId, driveId, drivesMap, requestContext](
          const boost::system::error_code ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_ERROR << "Drive mapper call error";
          messages::internalError(asyncResp->res);
          return;
        }

        auto drive = std::find_if(
            subtree.begin(), subtree.end(),
            [&driveId, &drivesMap](
                const std::pair<std::string,
                                std::vector<std::pair<
                                    std::string, std::vector<std::string>>>>&
                    object) {
              return sdbusplus::message::object_path(object.first).filename() ==
                         driveId &&
                     drivesMap.contains(object.first);
            });

        if (drive == subtree.end()) {
          messages::resourceNotFound(asyncResp->res, "Drive ResetActionInfo",
                                     driveId);
          return;
        }

        const std::string& drivePath = drive->first;
        const dbus::utility::MapperServiceMap& driveConnections = drive->second;

        if (driveConnections.size() != 1) {
          BMCWEB_LOG_ERROR << "Connection size " << driveConnections.size()
                           << ", not equal to 1";
          messages::internalError(asyncResp->res);
          return;
        }

        bool driveInterface = false;
        bool driveStateInterface = false;
        for (const std::string& interface : driveConnections[0].second) {
          if (interface == "xyz.openbmc_project.Inventory.Item.Drive") {
            driveInterface = true;
          }
          if (interface == "xyz.openbmc_project.State.Drive") {
            driveStateInterface = true;
          }
        }
        if (!driveInterface || !driveStateInterface) {
          BMCWEB_LOG_ERROR << "Drive does not have the required interfaces ";
          messages::internalError(asyncResp->res);
          return;
        }

        dbus_utils::getProperty<bool>(
            driveConnections[0].first, drivePath,
            "xyz.openbmc_project.Inventory.Item.Drive", "Resettable",
            requestContext,
            [asyncResp, chassisId, driveId](
                const boost::system::error_code propEc, bool resettable) {
              if (propEc) {
                BMCWEB_LOG_ERROR << "Failed to get resettable property ";
                messages::internalError(asyncResp->res);
                return;
              }
              if (!resettable) {
                messages::actionNotSupported(
                    asyncResp->res, "The drive does not support resets.");
                return;
              }
              asyncResp->res.jsonValue["@odata.type"] =
                  "#ActionInfo.v1_1_2.ActionInfo";
              asyncResp->res.jsonValue["@odata.id"] =
                  crow::utility::urlFromPieces("redfish", "v1", "Chassis",
                                               chassisId, "Drives", driveId,
                                               "ResetActionInfo");
              asyncResp->res.jsonValue["Name"] = "Reset Action Info";
              asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
              nlohmann::json::array_t parameters;
              nlohmann::json::object_t parameter;
              parameter["Name"] = "ResetType";
              parameter["Required"] = true;
              parameter["DataType"] = "String";
              nlohmann::json::array_t allowableValues;
              allowableValues.emplace_back("PowerCycle");
              allowableValues.emplace_back("ForceRestart");
              parameter["AllowableValues"] = std::move(allowableValues);
              parameters.emplace_back(parameter);
              asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
            });
      });
}

inline void handleGetDriveResetActionInfo(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& driveId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  findChassisDrive(
      asyncResp, chassisId,
      [asyncResp, chassisId, driveId](const boost::system::error_code ec,
                                      const std::vector<std::string>& drives) {
        if (ec) {
          BMCWEB_LOG_ERROR << "failed to find drives";
          messages::internalError(asyncResp->res);
          return;  // no drives = no failures
        }
        handleChassisDriveResetActionInfo(asyncResp, chassisId, driveId,
                                          drives);
      });
}

/**
 * DriveResetActionInfo derived class for delivering Drive
 * ResetType AllowableValues using ResetInfo schema.
 */
inline void requestRoutesDriveResetActionInfo(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Drives/<str>/ResetActionInfo/")
      .privileges(redfish::privileges::getActionInfo)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetDriveResetActionInfo, std::ref(app)));
}

inline void getStorageControllerAsset(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const boost::system::error_code& ec,
    const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
        propertiesList) {
  if (ec) {
    // this interface isn't necessary
    BMCWEB_LOG_DEBUG << "Failed to get StorageControllerAsset";
    return;
  }

  const std::string* partNumber = nullptr;
  const std::string* serialNumber = nullptr;
  const std::string* manufacturer = nullptr;
  const std::string* model = nullptr;
  if (!sdbusplus::unpackPropertiesNoThrow(
          dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
          partNumber, "SerialNumber", serialNumber, "Manufacturer",
          manufacturer, "Model", model)) {
    messages::internalError(asyncResp->res);
    return;
  }

  if (partNumber != nullptr) {
    asyncResp->res.jsonValue["PartNumber"] = *partNumber;
  }

  if (serialNumber != nullptr) {
    asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
  }

  if (manufacturer != nullptr) {
    asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
  }

  if (model != nullptr) {
    asyncResp->res.jsonValue["Model"] = *model;
  }
}

inline void tryPopulateControllerNvme(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& path, const dbus::utility::MapperServiceMap& ifaces) {
  if (storage_utils::matchServiceName(ifaces,
                                      "xyz.openbmc_project.NVMe.NVMeAdmin")) {
    auto& nvprop = asyncResp->res.jsonValue["NVMeControllerProperties"];
    // TODO(matt) fetch other properties, don't use hardcoded values
    nvprop["ControllerType"] = "IO";
    nvprop["NVMeVersion"] = "1.4";
  }

  if (auto service = storage_utils::matchServiceName(
          ifaces, "xyz.openbmc_project.Software.ExtendedVersion")) {
    managedStore::ManagedObjectStoreContext context(asyncResp);
    redfish::storage_utils::getProperty<std::string>(
        *service, path, "xyz.openbmc_project.Software.ExtendedVersion",
        "ExtendedVersion", context,
        [asyncResp](const boost::system::error_code& ec,
                    const std::string& extVers) {
          if (ec) {
            return;
          }

          std::string v("xyz.openbmc_project.NVMe.ControllerFirmwareVersion:");
          if (extVers.starts_with(v)) {
            asyncResp->res.jsonValue["FirmwareVersion"] =
                extVers.substr(v.size());
          }
        });
  }
}

inline void tryPopulateControllerSecurity(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const boost::urls::url& controllerUrl,
    const dbus::utility::MapperServiceMap& ifaces) {
  if (!storage_utils::matchServiceName(
          ifaces,
          "xyz.openbmc_project.Inventory.Item.StorageControllerSecurity")) {
    return;
  }

  boost::urls::url sendUrl(controllerUrl);
  crow::utility::appendUrlPieces(sendUrl, "Actions",
                                 "StorageController.SecuritySend");
  boost::urls::url receiveUrl(controllerUrl);
  crow::utility::appendUrlPieces(receiveUrl, "Actions",
                                 "StorageController.SecurityReceive");

  auto& actions = asyncResp->res.jsonValue["Actions"];
  actions["#StorageController.SecuritySend"]["target"] = sendUrl;
  actions["#StorageController.SecurityReceive"]["target"] = receiveUrl;
}

inline void storageCtrlAttachedVolumes(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const sdbusplus::message::object_path& controllerPath,
    std::function<void(const boost::system::error_code& ec,
                       const std::vector<std::string>& volPaths)>&& cb) {
  // Get list of attached volumes
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Inventory.Item.Volume"};
  managedStore::ManagedObjectStoreContext context(asyncResp);
  redfish::storage_utils::getAssociatedSubTreePaths(
      controllerPath / "attaching",
      sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
      interfaces, context,
      [cb](const boost::system::error_code& ec,
           const std::vector<std::string>& volPaths) { cb(ec, volPaths); });
}

inline void populateStorageControllerAttached(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId,
    const std::string& path) {
  storageCtrlAttachedVolumes(
      asyncResp, path,
      [asyncResp, systemName, storageId](
          const boost::system::error_code& ec,
          const std::vector<std::string>& attachedVolumeList) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "populating attached volumes failed";
          messages::internalError(asyncResp->res);
          return;
        }
        std::vector<boost::urls::url> redfishVolumes;
        for (const std::string& volumePath : attachedVolumeList) {
          std::string id =
              sdbusplus::message::object_path(volumePath).filename();
          if (id.empty()) {
            BMCWEB_LOG_ERROR << "Failed to find filename in " << volumePath;
            return;
          }
          boost::urls::url volumeUrl = crow::utility::urlFromPieces(
              "redfish", "v1", "Systems", systemName, "Storage", storageId,
              "Volumes", id);
          redfishVolumes.emplace_back(volumeUrl);
        }
        asyncResp->res.jsonValue["Links"]["AttachedVolumes"] = redfishVolumes;
      });
}

inline void populateStorageController(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId,
    const std::string& controllerId, const std::string& path,
    const dbus::utility::MapperServiceMap& ifaces) {
  if (ifaces.size() != 1) {
    BMCWEB_LOG_ERROR << "Connection size " << ifaces.size()
                     << ", greater than 1";
    messages::internalError(asyncResp->res);
    return;
  }

  const std::string& connectionName = ifaces.front().first;
  const std::vector<std::string>& interfaces = ifaces.front().second;

  asyncResp->res.jsonValue["@odata.type"] =
      "#StorageController.v1_7_0.StorageController";
  auto url = crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                          systemName, "Storage", storageId,
                                          "Controllers", controllerId);
  asyncResp->res.jsonValue["@odata.id"] = url;
  asyncResp->res.jsonValue["Name"] = controllerId;
  asyncResp->res.jsonValue["Id"] = controllerId;
  asyncResp->res.jsonValue["Status"]["State"] = "Enabled";

  if (storage_utils::matchServiceName(
          ifaces, "xyz.openbmc_project.NVMe.FeatureStore")) {
    asyncResp->res.jsonValue["Oem"]["Google"]["Features"]["@odata.id"] =
        crow::utility::urlFromPieces("redfish", "v1", "Systems", systemName,
                                     "Storage", storageId, "Controllers",
                                     controllerId, "Oem", "Google", "Features");
  }

  storage_utils::tryGetLocation(asyncResp, connectionName, path,
                                storage_utils::controllerInterface, interfaces);
  populateStorageControllerAttached(asyncResp, systemName, storageId, path);
  tryPopulateControllerNvme(asyncResp, path, ifaces);
  tryPopulateMetricCollection(asyncResp, path, ifaces, url);
  tryPopulateControllerSecurity(asyncResp, url, ifaces);
  if (enableCustomSSD) {
    populateCustomSSDInfo(asyncResp, ifaces, path);
  }

  managedStore::ManagedObjectStoreContext context(asyncResp);
  dbus_utils::getProperty<bool>(
      connectionName, path, "xyz.openbmc_project.Inventory.Item", "Present",
      context,
      [asyncResp](const boost::system::error_code& ec, bool isPresent) {
        // this interface isn't necessary, only check it
        // if we get a good return
        if (ec) {
          BMCWEB_LOG_DEBUG << "Failed to get Present property";
          return;
        }
        if (!isPresent) {
          asyncResp->res.jsonValue["Status"]["State"] = "Absent";
        }
      });

  managedStore::GetManagedObjectStore()->getAllProperties(
      connectionName, path, "xyz.openbmc_project.Inventory.Decorator.Asset",
      context,
      [asyncResp](const boost::system::error_code& ec,
                  const std::vector<
                      std::pair<std::string, dbus::utility::DbusVariantType>>&
                      propertiesList) {
        getStorageControllerAsset(asyncResp, ec, propertiesList);
      });
}

inline void securitySendAction(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& path, const dbus::utility::MapperServiceMap& ifaces,
    uint8_t proto, uint16_t protoSpecific, const std::string& dataBase64) {
  std::string dataString;
  if (!crow::utility::base64Decode(dataBase64, dataString)) {
    BMCWEB_LOG_DEBUG << "base data base64decode";
    messages::actionParameterValueFormatError(asyncResp->res, "<data>", "Data",
                                              "StorageController.SecuritySend");
    return;
  }

  // base64Decode outputs a string not bytes
  uint8_t* buffer = reinterpret_cast<uint8_t*>(dataString.data());  // NOLINT
  std::vector<uint8_t> data(buffer, buffer + dataString.size());    // NOLINT

  auto service = storage_utils::matchServiceName(
      ifaces, "xyz.openbmc_project.Inventory.Item.StorageControllerSecurity");
  if (!service) {
    BMCWEB_LOG_DEBUG << "No servicename";
    messages::internalError(asyncResp->res);
    return;
  }

#ifdef UNIT_TEST_BUILD
  dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
      managedStore::GetManagedObjectStore())
      ->PostDbusCallToIoContextThreadSafe(
#else
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
#endif
          asyncResp->strand_,
          [asyncResp](const boost::system::error_code ec,
                      const sdbusplus::message_t& msg) {
            // Failure returned from NVMe
            const ::sd_bus_error* sd_err = msg.get_error();
            if (sd_err != nullptr) {
              messages::generalError(asyncResp->res);
              BMCWEB_LOG_DEBUG << "SecuritySend NVMe error";
              if (sd_err->message != nullptr) {
                BMCWEB_LOG_DEBUG << "Error: " << sd_err->name << " message "
                                 << sd_err->message;
                asyncResp->res.jsonValue["error"]["message"] = sd_err->message;
              }
              return;
            }

            if (ec) {
              BMCWEB_LOG_DEBUG << "SecuritySend dbus error " << ec;
              messages::internalError(asyncResp->res);
              return;
            }

            // success
            asyncResp->res.result(boost::beast::http::status::no_content);
          },
          *service, path,
          "xyz.openbmc_project.Inventory.Item.StorageControllerSecurity",
          "SecuritySend", proto, protoSpecific, data);
}

inline void securityReceiveAction(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& path, const dbus::utility::MapperServiceMap& ifaces,
    uint8_t proto, uint16_t protoSpecific, uint32_t transferLength) {
  auto service = storage_utils::matchServiceName(
      ifaces, "xyz.openbmc_project.Inventory.Item.StorageControllerSecurity");
  if (!service) {
    BMCWEB_LOG_DEBUG << "No servicename";
    messages::internalError(asyncResp->res);
    return;
  }

#ifdef UNIT_TEST_BUILD
  dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
      managedStore::GetManagedObjectStore())
      ->PostDbusCallToIoContextThreadSafe(
#else
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
#endif
          asyncResp->strand_,
          [asyncResp](const boost::system::error_code ec,
                      const sdbusplus::message_t& msg,
                      const std::vector<uint8_t>& data) {
            // Failure returned from NVMe
            const ::sd_bus_error* sd_err = msg.get_error();
            if (sd_err != nullptr) {
              messages::generalError(asyncResp->res);
              BMCWEB_LOG_DEBUG << "SecurityReceive NVMe error";
              if (sd_err->message != nullptr) {
                BMCWEB_LOG_DEBUG << "Error: " << sd_err->name << " message "
                                 << sd_err->message;
                asyncResp->res.jsonValue["error"]["message"] = sd_err->message;
              }
              return;
            }

            if (ec) {
              BMCWEB_LOG_DEBUG << "SecurityReceive dbus error " << ec;
              messages::internalError(asyncResp->res);
              return;
            }

            // Success
            asyncResp->res.jsonValue["Data"] = crow::utility::base64encode(
                std::string_view(reinterpret_cast<const char*>(data.data()),
                                 data.size()));  // NOLINT
          },
          *service, path,
          "xyz.openbmc_project.Inventory.Item.StorageControllerSecurity",
          "SecurityReceive", proto, protoSpecific, transferLength);
}

inline static void setCustomSSDOemGpio(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& path, const std::string& property, bool value) {
  std::string customSSDDbusInterface =
      "com.google.gbmc.ssd." +
      boost::algorithm::to_lower_copy(std::string(customSSD));

#ifdef UNIT_TEST_BUILD
  dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
      managedStore::GetManagedObjectStore())
      ->setProperty(
#else
  managedStore::GetManagedObjectStore()->setProperty(
#endif
          "com.google.gbmc.ssd", path, customSSDDbusInterface, property, value,
          [asyncResp](const boost::system::error_code ec) {
            if (ec) {
              BMCWEB_LOG_ERROR << "setCustomSSDOemGpio D-Bus responses error: "
                               << ec;
              messages::internalError(asyncResp->res);
              return;
            }
            messages::success(asyncResp->res);
          });
}

inline static void setCustomSSDSpiImage(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& path, const std::string& property,
    const std::string& value) {
  std::string customSSDDbusInterface =
      "com.google.gbmc.ssd." +
      boost::algorithm::to_lower_copy(std::string(customSSD));

#ifdef UNIT_TEST_BUILD
  dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
      managedStore::GetManagedObjectStore())
      ->setProperty(
#else
  managedStore::GetManagedObjectStore()->setProperty(
#endif
          "com.google.gbmc.ssd", path, customSSDDbusInterface, property, value,
          [asyncResp](const boost::system::error_code ec) {
            if (ec) {
              BMCWEB_LOG_ERROR << "setCustomSSDSpiImage D-Bus responses error: "
                               << ec;
              messages::internalError(asyncResp->res);
              return;
            }
            messages::success(asyncResp->res);
          });
}

inline void storagePatchCustomSSDOem(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& storageId, const std::string& controllerId,
    nlohmann::json& customSSDOem) {
  storage_utils::findStorageAndController(
      asyncResp, storageId, controllerId,
      [asyncResp, storageId, controllerId, customSSDOem](
          const std::string& path, const dbus::utility::MapperServiceMap&) {
        if (customSSDOem.contains("MorristownOtpWriteEnable")) {
          setCustomSSDOemGpio(asyncResp, path, "MorristownOtpWriteEnable",
                              customSSDOem["MorristownOtpWriteEnable"]);
        }
        if (customSSDOem.contains("TriggerPowerCycle")) {
          setCustomSSDOemGpio(asyncResp, path, "TriggerPowerCycle",
                              customSSDOem["TriggerPowerCycle"]);
        }
        if (customSSDOem.contains("DisableWatchdog")) {
          setCustomSSDOemGpio(asyncResp, path, "DisableWatchdog",
                              customSSDOem["DisableWatchdog"]);
        }
        if (customSSDOem.contains("TriggerReset")) {
          setCustomSSDOemGpio(asyncResp, path, "TriggerReset",
                              customSSDOem["TriggerReset"]);
        }
        if (customSSDOem.contains("CpldReset")) {
          setCustomSSDOemGpio(asyncResp, path, "CpldReset",
                              customSSDOem["CpldReset"]);
        }
        if (customSSDOem.contains("SpiImgSelect")) {
          setCustomSSDSpiImage(asyncResp, path, "SpiImgSelect",
                               customSSDOem["SpiImgSelect"]);
        }
      });
}

// Performs storage attach and detach operations.
// Will be called pseudo-recursively (asio dbus callbacks) to perform
// the operations.
inline void storageApplyAttachDetach(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& connectionName, const std::string& controllerPath,
    const std::shared_ptr<std::vector<std::string>>& attaches,
    const std::shared_ptr<std::vector<std::string>>& detaches) {
  if (!detaches->empty()) {
    sdbusplus::message::object_path v = detaches->back();
    detaches->pop_back();
    BMCWEB_LOG_DEBUG << "detaching " << v.str << " from " << controllerPath
                     << "\n";
#ifdef UNIT_TEST_BUILD
    dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
        managedStore::GetManagedObjectStore())
        ->PostDbusCallToIoContextThreadSafe(
#else
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
#endif
            asyncResp->strand_,
            [asyncResp, connectionName, controllerPath, attaches, detaches](
                const boost::system::error_code ec,
                const sdbusplus::message_t& msg) {
              // Failure returned from NVMe
              const ::sd_bus_error* sd_err = msg.get_error();
              if (sd_err != nullptr) {
                // TODO remove "" argument
                storageAddDbusError(asyncResp->res, "detach volume NVMe", "",
                                    sd_err->name, sd_err->message);
                return;
              }

              if (ec) {
                BMCWEB_LOG_DEBUG << "detach volume dbus error " << ec;
                messages::internalError(asyncResp->res);
                return;
              }

              // "recurse"
              storageApplyAttachDetach(asyncResp, connectionName,
                                       controllerPath, attaches, detaches);
            },
            connectionName, controllerPath,
            "xyz.openbmc_project.Inventory.Item.StorageController",
            "DetachVolume", v);
    return;
  }

  if (!attaches->empty()) {
    sdbusplus::message::object_path v = attaches->back();
    attaches->pop_back();
    BMCWEB_LOG_DEBUG << "attaching " << v.str << " to " << controllerPath
                     << "\n";
#ifdef UNIT_TEST_BUILD
    dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
        managedStore::GetManagedObjectStore())
        ->PostDbusCallToIoContextThreadSafe(
#else
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
#endif
            asyncResp->strand_,
            [asyncResp, connectionName, controllerPath, attaches, detaches](
                const boost::system::error_code ec,
                const sdbusplus::message_t& msg) {
              // Failure returned from NVMe
              const ::sd_bus_error* sd_err = msg.get_error();
              if (sd_err != nullptr) {
                // TODO remove "" argument
                storageAddDbusError(asyncResp->res, "attach volume NVMe", "",
                                    sd_err->name, sd_err->message);
                return;
              }

              if (ec) {
                BMCWEB_LOG_DEBUG << "attach volume dbus error " << ec;
                messages::internalError(asyncResp->res);
                return;
              }

              // "recurse"
              storageApplyAttachDetach(asyncResp, connectionName,
                                       controllerPath, attaches, detaches);
            },
            connectionName, controllerPath,
            "xyz.openbmc_project.Inventory.Item.StorageController",
            "AttachVolume", v);
    return;
  }

  // both lists are complete, return success with the controller.
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Inventory.Item.StorageController"};
  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getDbusObject(
      controllerPath, interfaces, context,
      [asyncResp, connectionName, controllerPath](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetObject& interfaceDict) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "attach volume get controller dbus error " << ec;
          messages::internalError(asyncResp->res);
          return;
        }
        if (interfaceDict.size() != 1) {
          BMCWEB_LOG_DEBUG << "attachdetach extra services";
          for (const auto& x : interfaceDict) {
            BMCWEB_LOG_DEBUG << "if " << x.first;
          }
          messages::internalError(asyncResp->res);
        }

        auto c = sdbusplus::message::object_path(controllerPath);
        auto storagePath = c.parent_path().parent_path();
        std::string storageId = storagePath.filename();
        std::string controllerId = c.filename();
        storage_utils::getSystemPathFromStorage(
            asyncResp, storagePath,
            [asyncResp, storageId, controllerId, controllerPath,
             interfaceDict](std::optional<std::string_view> systemPath) {
              std::string systemName =
                  (systemPath) ? std::filesystem::path(*systemPath).filename()
                               : "system";
              populateStorageController(asyncResp, systemName, storageId,
                                        controllerId, controllerPath,
                                        interfaceDict);
            });
      });
}

inline void storagePatchAttachedVolumes(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId,
    const std::string& controllerId,
    std::vector<std::string>& updateVolumeURIs) {
  // vector of {parsed storageId, URI}
  std::vector<std::pair<std::string, std::string>> updateVolIDs;
  for (auto& u : updateVolumeURIs) {
    auto parsedUrl = boost::urls::parse_relative_ref(u);
    if (!parsedUrl) {
      BMCWEB_LOG_DEBUG << "bad attached volume URI " << u;
      messages::invalidURI(asyncResp->res, u);
      return;
    }
    std::string urlStorageId;
    std::string volumeId;
    if (!crow::utility::readUrlSegments(
            *parsedUrl, "redfish", "v1", "Systems", systemName.c_str(),
            "Storage", std::ref(urlStorageId), "Volumes", std::ref(volumeId))) {
      BMCWEB_LOG_DEBUG << "bad attached volume URI " << u;
      messages::invalidURI(asyncResp->res, u);
      return;
    }

    if (urlStorageId != storageId) {
      BMCWEB_LOG_DEBUG << "bad attached volume URI " << u;
      messages::invalidURI(asyncResp->res, u);
      return;
    }

    updateVolIDs.emplace_back(volumeId, u);
  }

  storage_utils::findStorageAndController(
      asyncResp, storageId, controllerId,
      [asyncResp, updateVolIDs](const std::string& controllerPath,
                                const dbus::utility::MapperServiceMap& ifaces) {
        const auto& connectionName = ifaces.front().first;

        // Create dbus paths to update. Elements are {dbus_path, URI}
        std::vector<std::pair<std::string, std::string>> updateVolumes;
        auto storagePath = sdbusplus::message::object_path(controllerPath)
                               .parent_path()
                               .parent_path();
        updateVolumes.reserve(updateVolIDs.size());
        for (const auto& [u, uri] : updateVolIDs) {
          updateVolumes.emplace_back((storagePath / "volumes" / u).str, uri);
        }
        std::sort(updateVolumes.begin(), updateVolumes.end());

        // Get list of available volumes
        storageVolumes(
            asyncResp, storagePath,
            [asyncResp, updateVolumes, connectionName, controllerPath](
                const boost::system::error_code& ec,
                const std::vector<std::string>& volPaths) {
              if (ec) {
                BMCWEB_LOG_DEBUG
                    << "patch attached volumes list volumes failed";
                messages::internalError(asyncResp->res);
                return;
              }

              for (const auto& a : volPaths) {
                BMCWEB_LOG_DEBUG << "vol is " << a;
              }

              std::vector<std::string> updatePaths;
              // Early check for bad volume paths
              for (const auto& [u, uri] : updateVolumes) {
                if (std::find(volPaths.begin(), volPaths.end(), u) ==
                    volPaths.end()) {
                  BMCWEB_LOG_DEBUG << "patch volume not found " << uri;
                  messages::invalidURI(asyncResp->res, uri);
                  return;
                }
                updatePaths.emplace_back(u);
              }

              // Fetch currently attached volumes
              storageCtrlAttachedVolumes(
                  asyncResp, controllerPath,
                  [asyncResp, updatePaths, connectionName, controllerPath](
                      const boost::system::error_code& ec2,
                      const std::vector<std::string>& ex) {
                    if (ec2) {
                      BMCWEB_LOG_DEBUG
                          << "patch attached volumes list attached failed";
                      messages::internalError(asyncResp->res);
                      return;
                    }

                    // Find changes
                    auto attaches =
                        std::make_shared<std::vector<std::string>>();
                    auto detaches =
                        std::make_shared<std::vector<std::string>>();
                    std::vector<std::string> existing(ex);
                    std::sort(existing.begin(), existing.end());
                    std::set_difference(updatePaths.begin(), updatePaths.end(),
                                        existing.begin(), existing.end(),
                                        std::back_inserter(*attaches));

                    std::set_difference(existing.begin(), existing.end(),
                                        updatePaths.begin(), updatePaths.end(),
                                        std::back_inserter(*detaches));

                    // Apply
                    storageApplyAttachDetach(asyncResp, connectionName,
                                             controllerPath, attaches,
                                             detaches);
                  });
            });
      });
}

inline void storagePatchController(
    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;
  }

  checkSystemAndStorage(asyncResp, systemName, storageId);

  if (!enableCustomSSD) {
    return;
  }

  std::optional<nlohmann::json> customSSDOem;
  std::optional<std::vector<std::string>> attachedVolumes;
  if (!json_util::readJsonPatch(
          req, asyncResp->res, "Links/AttachedVolumes", attachedVolumes,
          "Links/Oem/Google/" + std::string(customSSD), customSSDOem)) {
    BMCWEB_LOG_DEBUG << "Bad controller patch input";
    return;
  }

  if (customSSDOem && attachedVolumes) {
    BMCWEB_LOG_DEBUG << "Multiple values to controller patch";
    messages::generalError(asyncResp->res);
    asyncResp->res.jsonValue["error"]["message"] =
        "PATCH may only alter one resource type";
    return;
  }

  if (!(customSSDOem || attachedVolumes)) {
    BMCWEB_LOG_DEBUG << "No values to controller patch";
    messages::noOperation(asyncResp->res);
    return;
  }

  if (customSSDOem) {
    storagePatchCustomSSDOem(asyncResp, storageId, controllerId, *customSSDOem);
  }

  if (attachedVolumes) {
    storagePatchAttachedVolumes(asyncResp, systemName, storageId, controllerId,
                                *attachedVolumes);
  }

  // TODO: we should setCompleteRequestHandler to return the modified
  // StorageController on completion, rather than handling in attachedVolumes.
}

inline void handlePostStorageControllerSecuritySend(
    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;
  }

  checkSystemAndStorage(asyncResp, systemName, storageId);

  uint8_t proto = 0;
  uint16_t protoSpecific = 0;
  std::string dataBase64;

  if (!json_util::readJsonAction(req, asyncResp->res, "SecurityProtocol", proto,
                                 "SecurityProtocolSpecific", protoSpecific,
                                 "Data", dataBase64)) {
    BMCWEB_LOG_DEBUG << "Missing request json parameters";
    return;
  }

  storage_utils::findStorageAndController(
      asyncResp, storageId, controllerId,
      [asyncResp, proto, protoSpecific, dataBase64](
          const sdbusplus::message::object_path& path,
          const dbus::utility::MapperServiceMap& ifaces) {
        securitySendAction(asyncResp, path, ifaces, proto, protoSpecific,
                           dataBase64);
      });
}

inline void handlePostStorageControllerSecurityReceive(
    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;
  }

  checkSystemAndStorage(asyncResp, systemName, storageId);

  uint8_t proto = 0;
  uint16_t protoSpecific = 0;
  uint32_t transferLength = 0;

  if (!json_util::readJsonAction(req, asyncResp->res, "SecurityProtocol", proto,
                                 "SecurityProtocolSpecific", protoSpecific,
                                 "AllocationLength", transferLength)) {
    BMCWEB_LOG_DEBUG << "Missing request json parameters";
    return;
  }

  storage_utils::findStorageAndController(
      asyncResp, storageId, controllerId,
      [asyncResp, proto, protoSpecific, transferLength](
          const sdbusplus::message::object_path& path,
          const dbus::utility::MapperServiceMap& ifaces) {
        securityReceiveAction(asyncResp, path, ifaces, proto, protoSpecific,
                              transferLength);
      });
}

inline void requestRoutesStorageControllerActions(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Controllers/<str>/"
               "Actions/StorageController.SecuritySend")
      .privileges(redfish::privileges::postStorageController)
      .methods(boost::beast::http::verb::post)(std::bind_front(
          handlePostStorageControllerSecuritySend, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Controllers/<str>/"
               "Actions/StorageController.SecurityReceive")
      .privileges(redfish::privileges::postStorageController)
      .methods(boost::beast::http::verb::post)(std::bind_front(
          handlePostStorageControllerSecurityReceive, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/<str>/Controllers/<str>")
      .privileges(redfish::privileges::patchStorageController)
      .methods(boost::beast::http::verb::patch)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& systemName, const std::string& storageId,
                 const std::string& controllerId) {
            storagePatchController(app, req, asyncResp, systemName, storageId,
                                   controllerId);
          });
}

inline void populateStorageControllerCollection(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId,
    const dbus::utility::MapperGetSubTreeResponse& controllerList) {
  if (!asyncResp->res.jsonValue["Members"].is_array()) {
    asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
  }
  asyncResp->res.jsonValue["Members@odata.count"] =
      asyncResp->res.jsonValue["Members"].size();

  for (const auto& controller : controllerList) {
    const sdbusplus::message::object_path controllerPath = controller.first;
    storage_utils::findStorageForController(
        asyncResp, storageId, controllerPath,
        [asyncResp, systemName,
         controllerPath](const std::optional<sdbusplus::message::object_path>&
                             canonStoragePath) {
          if (!canonStoragePath) {
            BMCWEB_LOG_DEBUG << "No storage associated with controller "
                             << std::string(controllerPath);
            return;
          }
          nlohmann::json::object_t member;
          std::string canonStorageId = (*canonStoragePath).filename();
          std::string controllerId = controllerPath.filename();
          member["@odata.id"] = crow::utility::urlFromPieces(
              "redfish", "v1", "Systems", systemName, "Storage", canonStorageId,
              "Controllers", controllerId);
          asyncResp->res.jsonValue["Members"].emplace_back(member);
          asyncResp->res.jsonValue["Members@odata.count"] =
              asyncResp->res.jsonValue["Members"].size();
        });
  }
}

inline void storageControllerCollectionHandler(
    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)) {
    BMCWEB_LOG_DEBUG
        << "Failed to setup Redfish Route for StorageController Collection";
    return;
  }

  checkSystemAndStorage(asyncResp, systemName, storageId);

  storage_utils::findStorage(
      asyncResp, storageId,
      [asyncResp, systemName,
       storageId](const sdbusplus::message::object_path& storagePath) {
        asyncResp->res.jsonValue["@odata.type"] =
            "#StorageControllerCollection.StorageControllerCollection";
        asyncResp->res.jsonValue["@odata.id"] =
            crow::utility::urlFromPieces("redfish", "v1", "Systems", systemName,
                                         "Storage", storageId, "Controllers");
        asyncResp->res.jsonValue["Name"] = "Storage Controller Collection";

        auto& cap = asyncResp->res.jsonValue["@Redfish.CollectionCapabilities"];
        cap["@odata.type"] =
            "#CollectionCapabilities.v1_3_0.CollectionCapabilities";
        auto& cs = cap["Capabilities"];
        if (!cs.is_array()) {
          cs = nlohmann::json::array_t();
        }
        auto& c = cs.emplace_back(nlohmann::json::object_t());
        c["CapabilitiesObject"]["@odata.id"] = crow::utility::urlFromPieces(
            "redfish", "v1", "Systems", systemName, "Storage", storageId,
            "Volumes", "Capabilities");
        c["Links"]["TargetCollection"]["@odata.id"] =
            asyncResp->res.jsonValue["@odata.id"];

        storage_utils::findControllersForStorage(
            asyncResp, storagePath,
            std::bind_front(populateStorageControllerCollection, asyncResp,
                            systemName, storageId));
      });
}

inline void tryPopulateVolumeNvme(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& connectionName, const std::string& path,
    const dbus::utility::MapperServiceMap& ifaces, const std::string& volumeId,
    size_t blockSize) {
  if (!storage_utils::matchServiceName(ifaces,
                                       "xyz.openbmc_project.Nvme.Volume")) {
    return;
  }

  asyncResp->res.jsonValue["Name"] = std::string("Namespace ") + volumeId;

  managedStore::ManagedObjectStoreContext context(asyncResp);
  redfish::storage_utils::getAllProperties(
      connectionName, path, "xyz.openbmc_project.Nvme.Volume", context,
      [asyncResp, blockSize](
          const boost::system::error_code& ec,
          const std::vector<std::pair<
              std::string, dbus::utility::DbusVariantType>>& propertiesList) {
        if (ec) {
          std::cerr << "error fetching nvme volume " << ec << '\n';
          // this interface isn't necessary
          return;
        }

        const uint32_t* namespaceId = nullptr;
        const size_t* lbaFormat = nullptr;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), propertiesList, "NamespaceId",
            namespaceId, "LBAFormat", lbaFormat);

        if (!success) {
          messages::internalError(asyncResp->res);
          return;
        }

        auto& nvprop = asyncResp->res.jsonValue["NVMeNamespaceProperties"];
        if (namespaceId != nullptr) {
          nvprop["NamespaceId"] =
              std::string("0x") + intToHexString(*namespaceId, 8);
        }
        if (lbaFormat != nullptr) {
          auto& lbafprop = nvprop["LBAFormat"];
          lbafprop["LBAFormatType"] =
              std::string("LBAFormat") + std::to_string(*lbaFormat);
          lbafprop["LBADataSizeBytes"] = blockSize;
          // TODO: populate other lbaformat attributes, and metadata_at_end
        }
      });
}

inline void populateStorageVolume(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& storageId,
    const std::string& volumeId, const std::string& connectionName,
    const std::string& path, const dbus::utility::MapperServiceMap& ifaces) {
  asyncResp->res.jsonValue["@odata.type"] = "#Volume.v1_9_0.Volume";
  auto url =
      crow::utility::urlFromPieces("redfish", "v1", "Systems", systemName,
                                   "Storage", storageId, "Volumes", volumeId);
  asyncResp->res.jsonValue["@odata.id"] = url;
  // May be overridden by nvme
  asyncResp->res.jsonValue["Name"] = std::string("Volume ") + volumeId;
  asyncResp->res.jsonValue["Id"] = volumeId;

  if (storage_utils::matchServiceName(
          ifaces, "xyz.openbmc_project.NVMe.FeatureStore")) {
    asyncResp->res.jsonValue["Oem"]["Google"]["Features"]["@odata.id"] =
        crow::utility::urlFromPieces("redfish", "v1", "Systems", systemName,
                                     "Storage", storageId, "Volumes", volumeId,
                                     "Oem", "Google", "Features");
  }

  managedStore::ManagedObjectStoreContext context(asyncResp);
  redfish::storage_utils::getAllProperties(
      connectionName, path, "xyz.openbmc_project.Inventory.Item.Volume",
      context,
      [asyncResp, connectionName, path, ifaces, volumeId](
          const boost::system::error_code& ec,
          const std::vector<std::pair<
              std::string, dbus::utility::DbusVariantType>>& propertiesList) {
        size_t volBlockSize = 0;
        // this interface isn't necessary
        if (!ec) {
          const uint64_t* size = nullptr;
          const size_t* blockSize = nullptr;

          const bool success = sdbusplus::unpackPropertiesNoThrow(
              dbus_utils::UnpackErrorPrinter(), propertiesList, "Size", size,
              "BlockSize", blockSize);

          if (!success) {
            messages::internalError(asyncResp->res);
            return;
          }

          auto& cap = asyncResp->res.jsonValue["Capacity"];
          auto& capdata = cap["Data"];
          if (size != nullptr) {
            capdata["ProvisionedBytes"] = *size;
          }
          // Capacity.Metadata or provisioned/allocated is not currently
          // handled by OpenBMC
          if (blockSize != nullptr) {
            asyncResp->res.jsonValue["BlockSizeBytes"] = *blockSize;
            volBlockSize = *blockSize;
          }
          tryPopulateVolumeNvme(asyncResp, connectionName, path, ifaces,
                                volumeId, volBlockSize);
        }
      });

  tryPopulateMetricCollection(asyncResp, path, ifaces, url);

  auto findIfaces = std::find_if(
      ifaces.begin(), ifaces.end(),
      [connectionName](
          const std::pair<std::string, std::vector<std::string>>& pair) {
        return pair.first == connectionName;
      });
  if (findIfaces != ifaces.end()) {
    storage_utils::tryGetLocation(asyncResp, connectionName, path,
                                  storage_utils::volumeInterface,
                                  findIfaces->second);
  }
}

inline void deleteStorageVolume(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& storageId, const std::string& connectionName,
    const std::string& path) {
#ifdef UNIT_TEST_BUILD
  dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
      managedStore::GetManagedObjectStore())
      ->PostDbusCallToIoContextThreadSafe(
#else
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
#endif
          asyncResp->strand_,
          [asyncResp, storageId](const boost::system::error_code ec,
                                 const sdbusplus::message_t& msg) {
            // Failure returned from NVMe
            const ::sd_bus_error* sd_err = msg.get_error();
            if (sd_err != nullptr) {
              storageAddDbusError(asyncResp->res, "delete Volume NVMe",
                                  storageId, sd_err->name, sd_err->message);
              return;
            }

            if (ec) {
              BMCWEB_LOG_DEBUG << "delete Volume dbus error " << ec;
              messages::internalError(asyncResp->res);
              return;
            }

            // success
            asyncResp->res.result(boost::beast::http::status::no_content);
          },
          connectionName, path, "xyz.openbmc_project.Object.Delete", "Delete");
}

inline void findStorageVolume(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& storageId, const std::string& volumeId,
    const std::function<
        void(const std::string& storagePath, const std::string& volumePath,
             const std::string& connectionName,
             const dbus::utility::MapperServiceMap& ifaces)>& cb) {
  storage_utils::findStorage(
      asyncResp, storageId,
      [asyncResp, storageId, volumeId,
       cb](const sdbusplus::message::object_path& storagePath) {
        constexpr std::array<std::string_view, 1> interfaces = {
            "xyz.openbmc_project.Inventory.Item.Volume"};
        managedStore::ManagedObjectStoreContext context(asyncResp);
        redfish::storage_utils::getAssociatedSubTree(
            storagePath / "containing",
            sdbusplus::message::object_path("/xyz/openbmc_project/inventory"),
            0, interfaces, context,
            [asyncResp, storageId, volumeId, storagePath, cb](
                const boost::system::error_code& ec,
                const dbus::utility::MapperGetSubTreeResponse& subtree) {
              if (ec || subtree.empty()) {
                BMCWEB_LOG_DEBUG << "findStorageVolume error" << ec;
                messages::resourceNotFound(asyncResp->res,
                                           "#Volume.v1_9_0.Volume", volumeId);
                return;
              }

              for (const auto& [path, interfaceDict] : subtree) {
                sdbusplus::message::object_path object(path);
                std::string id = object.filename();
                if (id.empty()) {
                  BMCWEB_LOG_ERROR << "Failed to find filename in " << path;
                  messages::resourceNotFound(asyncResp->res,
                                             "#Volume.v1_9_0.Volume", volumeId);
                  return;
                }
                if (id != volumeId) {
                  continue;
                }

                if (interfaceDict.size() != 1) {
                  BMCWEB_LOG_ERROR << "Connection size " << interfaceDict.size()
                                   << ", greater than 1";
                  messages::internalError(asyncResp->res);
                  return;
                }

                const std::string& connectionName = interfaceDict.front().first;
                cb(storagePath, path, connectionName, interfaceDict);
                return;
              }
              BMCWEB_LOG_DEBUG << "findStorageVolume not found";
              messages::resourceNotFound(asyncResp->res,
                                         "#Volume.v1_9_0.Volume", volumeId);
            });
      });
}

inline void createVolumeSuccess(const std::shared_ptr<task::TaskData>& taskData,
                                const std::string& service,
                                const std::string& storageId,
                                const std::string& progressPath) {
  taskData->stopMonitor();

  // Have to create a new Resp here as we cannot use the original resp or it
  // never goes out of scope This resp will not have a strand associated with it
  // which is okay because this will never be multithreaded
  auto resp = std::make_shared<bmcweb::AsyncResp>(nullptr);
  managedStore::ManagedObjectStoreContext context(resp);
  redfish::storage_utils::getProperty<sdbusplus::message::object_path>(
      service, progressPath,
      "xyz.openbmc_project.Nvme.CreateVolumeProgressSuccess", "VolumePath",
      context,
      [taskData, storageId, progressPath](
          const boost::system::error_code& ec,
          const sdbusplus::message::object_path& volumePath) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "createVolumeSuccess volumepath error " << ec;
          taskData->messages.emplace_back(messages::internalError());
          taskData->state = "Exception";
          taskData->complete(nlohmann::json(),
                             boost::beast::http::status::internal_server_error);
          return;
        }

        auto resp = std::make_shared<bmcweb::AsyncResp>(nullptr);
        resp->res.setCompleteRequestHandler([taskData](crow::Response& res) {
          if (res.result() == boost::beast::http::status::ok) {
            taskData->messages.emplace_back(messages::created());
            taskData->state = "Completed";
            taskData->complete(std::move(res.jsonValue),
                               boost::beast::http::status::created);
          } else {
            BMCWEB_LOG_DEBUG << "createVolumeSuccess error populating: "
                             << res.result();
            BMCWEB_LOG_DEBUG << res.jsonValue;
            taskData->messages.emplace_back(messages::internalError());
            taskData->state = "Exception";
            taskData->complete(
                nlohmann::json(),
                boost::beast::http::status::internal_server_error);
          }
        });

        auto volumeId = volumePath.filename();

        findStorageVolume(
            resp, storageId, volumeId,
            [resp, storageId, volumeId](
                const std::string& sPath, const std::string& vPath,
                const std::string& connectionName,
                const dbus::utility::MapperServiceMap& ifaces) {
              BMCWEB_LOG_DEBUG << "createVolumeSuccess connectionName is "
                               << connectionName;
              storage_utils::getSystemPathFromStorage(
                  resp, sPath,
                  [resp, storageId, volumeId, connectionName, vPath,
                   ifaces](std::optional<std::string_view> systemPath) {
                    std::string systemName =
                        systemPath
                            ? std::filesystem::path(*systemPath).filename()
                            : "system";
                    populateStorageVolume(resp, systemName, storageId, volumeId,
                                          connectionName, vPath, ifaces);
                  });
              // on completion completeRequestHandler above will copy the
              // response to taskData
            });
      });
}

inline void createVolumeFailure(const std::shared_ptr<task::TaskData>& taskData,
                                const std::string& service,
                                const std::string& storageId,
                                const std::string& progressPath) {
  taskData->stopMonitor();

  // Have to create a new Resp here as we cannot use the original resp or it
  // never goes out of scope This resp will not have a strand associated with it
  // which is okay because this will never be multithreaded
  auto resp = std::make_shared<bmcweb::AsyncResp>(nullptr);
  managedStore::ManagedObjectStoreContext context(resp);
  redfish::storage_utils::getAllProperties(
      service, progressPath,
      "xyz.openbmc_project.Nvme.CreateVolumeProgressFailure", context,
      [taskData, storageId](
          const boost::system::error_code& ec,
          const std::vector<
              std::pair<std::string, dbus::utility::DbusVariantType>>& props) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "createVolumeSuccess volumepath error " << ec;
          taskData->messages.emplace_back(messages::internalError());
          taskData->state = "Exception";
          taskData->complete(nlohmann::json(),
                             boost::beast::http::status::internal_server_error);
          return;
        }

        std::string errorName;
        std::string errorDesc;
        sdbusplus::unpackPropertiesNoThrow(dbus_utils::UnpackErrorPrinter(),
                                           props, "ErrorName", errorName,
                                           "ErrorDescription", errorDesc);
        bmcweb::AsyncResp resp(nullptr);
        storageAddDbusError(resp.res, "createVolumeFailure", storageId,
                            errorName, errorDesc);
        for (auto& m :
             resp.res.jsonValue["error"][messages::messageAnnotation]) {
          taskData->messages.emplace_back(m);
        }

        taskData->state = "Exception";
        taskData->complete(std::move(resp.res.jsonValue), resp.res.result());
      });
}

// Handles the Status property of Common.Progress interface
inline void createVolumeTaskUpdate(
    const std::string& status, const std::shared_ptr<task::TaskData>& taskData,
    const std::string& service, const std::string& storageId,
    const std::string& progressPath) {
  if (status ==
      "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress") {
    // nothing to do
  } else if (status ==
             "xyz.openbmc_project.Common.Progress.OperationStatus.Completed") {
    createVolumeSuccess(taskData, service, storageId, progressPath);
  } else if (
      status == "xyz.openbmc_project.Common.Progress.OperationStatus.Failed" ||
      status == "xyz.openbmc_project.Common.Progress.OperationStatus.Aborted") {
    createVolumeFailure(taskData, service, storageId, progressPath);
  } else {
    BMCWEB_LOG_DEBUG << "updateCreateVolumeTask unexpected state " << status;
  }
}

// Handler called by TaskData on Commmon.Progress property change
inline bool createVolumeTaskHandler(
    sdbusplus::message_t& msg, const std::shared_ptr<task::TaskData>& taskData,
    const std::string& service, const std::string& storageId,
    const std::string& progressPath) {
  dbus::utility::DBusPropertiesMap props;
  std::string iface;
  msg.read(iface, props);

  if (iface != "xyz.openbmc_project.Common.Progress") {
    BMCWEB_LOG_DEBUG << "updateCreateVolumeTask wrong interface";
    return !task::completed;
  }

  std::optional<std::string> status;
  sdbusplus::unpackPropertiesNoThrow(dbus_utils::UnpackErrorPrinter(), props,
                                     "Status", status);
  if (!status) {
    BMCWEB_LOG_DEBUG << "updateCreateVolumeTask not status update";
    return !task::completed;
  }

  createVolumeTaskUpdate(*status, taskData, service, storageId, progressPath);
  // completion is handled asynchronously so always return !completed
  return !task::completed;
}

inline void createStorageVolume(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& storagePath, const std::string& storageService,
    uint64_t size, size_t lbaIndex, bool metadataAtEnd) {
  auto storageId = sdbusplus::message::object_path(storagePath).filename();
#ifdef UNIT_TEST_BUILD
  dynamic_cast<managedStore::MockSerializedManagedObjectStore*>(
      managedStore::GetManagedObjectStore())
      ->PostDbusCallToIoContextThreadSafe(
#else
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
#endif
          asyncResp->strand_,
          [req, asyncResp, storageId, storageService](
              const boost::system::error_code ec,
              const sdbusplus::message_t& msg,
              const sdbusplus::message::object_path& progressPath) {
            const ::sd_bus_error* sd_err = msg.get_error();
            if (sd_err != nullptr) {
              storageAddDbusError(asyncResp->res, "create Volume NVMe",
                                  storageId, sd_err->name, sd_err->message);
              return;
            }

            if (ec) {
              BMCWEB_LOG_DEBUG << "create Volume dbus error " << ec;
              messages::internalError(asyncResp->res);
              return;
            }

            // success
            BMCWEB_LOG_DEBUG << "create volume success, progress path "
                             << progressPath.str;
            std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
                [storageService, storageId, progressPath](
                    const boost::system::error_code& err,
                    sdbusplus::message_t& taskMsg,
                    const std::shared_ptr<task::TaskData>& taskData) {
                  if (err) {
                    // Internal error in property signal callback?
                    BMCWEB_LOG_ERROR << progressPath.str << ": Error in task";
                    taskData->messages.emplace_back(messages::internalError());
                    taskData->state = "Cancelled";
                    return task::completed;
                  }

                  return createVolumeTaskHandler(taskMsg, taskData,
                                                 storageService, storageId,
                                                 progressPath);
                },
                "type='signal',interface='org.freedesktop.DBus.Properties',"
                "member='PropertiesChanged',arg0='xyz.openbmc_project.Common."
                "Progress',"
                "path='" +
                    progressPath.str + "'");

            task->startTimer(std::chrono::minutes(60));
            task->populateResp(asyncResp->res);
            task->payload.emplace(req);

            // Progress may have completed prior to Task watching for signals,
            // so poll Status once.
            managedStore::ManagedObjectStoreContext context(asyncResp);
            redfish::storage_utils::getProperty<std::string>(
                storageService, progressPath,
                "xyz.openbmc_project.Common.Progress", "Status", context,
                [task, storageService, storageId, progressPath](
                    const boost::system::error_code& ec2,
                    const std::string& status) {
                  if (ec2) {
                    BMCWEB_LOG_ERROR << "createVolume poll error: "
                                     << ec2.message();
                    return;
                  }

                  createVolumeTaskUpdate(status, task, storageService,
                                         storageId, progressPath);
                });
          },
          storageService, storagePath, "xyz.openbmc_project.Nvme.Storage",
          "CreateVolume", size, lbaIndex, metadataAtEnd);
}

inline void populateStorageVolumeCollection(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const boost::system::error_code& ec, const std::string& systemName,
    const std::string& storageId,
    const dbus::utility::MapperGetSubTreePathsResponse& volumeList) {
  nlohmann::json::array_t members;
  if (ec || volumeList.empty()) {
    asyncResp->res.jsonValue["Members"] = std::move(members);
    asyncResp->res.jsonValue["Members@odata.count"] = 0;
    BMCWEB_LOG_DEBUG << "Failed to find any storage Volumes";
    return;
  }

  for (const std::string& path : volumeList) {
    std::string id = sdbusplus::message::object_path(path).filename();
    if (id.empty()) {
      BMCWEB_LOG_ERROR << "Failed to find filename in " << path;
      return;
    }
    nlohmann::json::object_t member;
    member["@odata.id"] =
        crow::utility::urlFromPieces("redfish", "v1", "Systems", systemName,
                                     "Storage", storageId, "Volumes", id);
    members.emplace_back(member);
  }
  asyncResp->res.jsonValue["Members@odata.count"] = members.size();
  asyncResp->res.jsonValue["Members"] = std::move(members);
}

inline void storageVolumeHandler(
    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)) {
    BMCWEB_LOG_DEBUG << "Failed to setup Redfish Route for StorageVolume";
    return;
  }

  checkSystemAndStorage(asyncResp, systemName, storageId);

  findStorageVolume(
      asyncResp, storageId, volumeId,
      [asyncResp, systemName, storageId, volumeId](
          const std::string& /* sPath */, const std::string& vPath,
          const std::string& connectionName,
          const dbus::utility::MapperServiceMap& ifaces) {
        populateStorageVolume(asyncResp, systemName, storageId, volumeId,
                              connectionName, vPath, ifaces);
      });
}

inline std::optional<size_t> parseLbaFormatType(std::string_view ty) {
  // expects LBAFormat0, LBAFormat1 etc
  if (!ty.starts_with("LBAFormat")) {
    BMCWEB_LOG_DEBUG << "wrong start";
    return std::nullopt;
  }

  ty.remove_prefix(std::min(ty.size(), strlen("LBAFormat")));

  size_t v = 0;
  auto e = std::from_chars(ty.data(), ty.data() + ty.size(), v);
  if (e.ptr != ty.data() + ty.size() || e.ec != std::errc()) {
    return std::nullopt;
  }
  return v;
}

inline void storageVolumeCreateHandler(
    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)) {
    BMCWEB_LOG_DEBUG << "Failed to setup Redfish Route for StorageVolume";
    return;
  }

  checkSystemAndStorage(asyncResp, systemName, storageId);

  uint64_t size = 0;
  std::string lbaFormat;
  // allow to default, non-metadata formats ignore the parameter
  std::optional<bool> metadataAtEnd = false;
  std::optional<std::string> name;

  if (!json_util::readJsonAction(
          req, asyncResp->res, "Name", name, "Capacity/Data/ProvisionedBytes",
          size, "NVMeNamespaceProperties/LBAFormat/LBAFormatType", lbaFormat,
          "NVMeNamespaceProperties/LBAFormat/MetadataTransferredAtEndOfDataLBA",
          metadataAtEnd)) {
    BMCWEB_LOG_DEBUG << "create volume json input failed";
    return;
  }

  std::optional<size_t> lbaIndex = parseLbaFormatType(lbaFormat);
  if (!lbaIndex) {
    BMCWEB_LOG_DEBUG << "Bad parsing lbaFormatType";
    messages::propertyValueNotInList(
        asyncResp->res, lbaFormat,
        "NVMeNamespaceProperties.LBAFormat.LBAFormatType");
    return;
  }

  storage_utils::findStorageCallbackWithService(
      asyncResp, storageId,
      [req, asyncResp, size, lbaIndex, metadataAtEnd](
          const sdbusplus::message::object_path& storagePath,
          const std::string& storageService) {
        createStorageVolume(req, asyncResp, storagePath, storageService, size,
                            *lbaIndex, *metadataAtEnd);
      });
}

inline void storageVolumeDeleteHandler(
    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) {
  BMCWEB_LOG_DEBUG << "delete handler vol " << volumeId;
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    BMCWEB_LOG_DEBUG << "Failed to setup Redfish Route for StorageVolume";
    return;
  }

  checkSystemAndStorage(asyncResp, systemName, storageId);

  findStorageVolume(
      asyncResp, storageId, volumeId,
      [asyncResp, storageId, volumeId](
          const std::string& /* sPath */, const std::string& vPath,
          const std::string& connectionName,
          const dbus::utility::MapperServiceMap& ifaces) {
        (void)ifaces;
        deleteStorageVolume(asyncResp, storageId, connectionName, vPath);
      });
}

inline void storageVolumeCollectionHandler(
    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)) {
    BMCWEB_LOG_DEBUG
        << "Failed to setup Redfish Route for StorageVolume Collection";
    return;
  }

  checkSystemAndStorage(asyncResp, systemName, storageId);

  storage_utils::findStorage(
      asyncResp, storageId,
      [asyncResp, systemName,
       storageId](const sdbusplus::message::object_path& storagePath) {
        asyncResp->res.jsonValue["@odata.type"] =
            "#VolumeCollection.VolumeCollection";
        asyncResp->res.jsonValue["@odata.id"] =
            crow::utility::urlFromPieces("redfish", "v1", "Systems", systemName,
                                         "Storage", storageId, "Volumes");
        asyncResp->res.jsonValue["Name"] = "Storage Volume Collection";

        storageVolumes(asyncResp, storagePath,
                       [asyncResp, systemName, storageId](
                           const boost::system::error_code& ec,
                           const dbus::utility::MapperGetSubTreePathsResponse&
                               volumeList) {
                         populateStorageVolumeCollection(
                             asyncResp, ec, systemName, storageId, volumeList);
                       });
      });
}

inline std::string lookupRelativePerformance(const std::string& rp) {
  if (rp == "xyz.openbmc_project.Nvme.Storage.RelativePerformance.Best") {
    return "Best";
  }
  if (rp == "xyz.openbmc_project.Nvme.Storage.RelativePerformance.Better") {
    return "Better";
  }
  if (rp == "xyz.openbmc_project.Nvme.Storage.RelativePerformance.Good") {
    return "Good";
  }
  return "Degraded";
}

inline void storageVolumeCapabilitiesHandler(
    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)) {
    BMCWEB_LOG_DEBUG
        << "Failed to setup Redfish Route for StorageVolume Capabilities";
    return;
  }

  checkSystemAndStorage(asyncResp, systemName, storageId);

  storage_utils::findStorageCallbackWithService(
      asyncResp, storageId,
      [asyncResp, systemName, storageId](
          const sdbusplus::message::object_path& storagePath,
          const std::string& service) {
        managedStore::ManagedObjectStoreContext context(asyncResp);
        redfish::storage_utils::getProperty<
            std::vector<std::tuple<size_t, size_t, size_t, std::string>>>(
            service, storagePath, "xyz.openbmc_project.Nvme.Storage",
            "SupportedFormats", context,
            [asyncResp, systemName, storageId](
                const boost::system::error_code& ec,
                const std::vector<
                    std::tuple<size_t, size_t, size_t, std::string>>& formats) {
              asyncResp->res.jsonValue["@odata.type"] = "#Volume.v1_9_0.Volume";
              auto url = crow::utility::urlFromPieces(
                  "redfish", "v1", "Systems", systemName, "Storage", storageId,
                  "Volumes", "Capabilities");
              asyncResp->res.jsonValue["@odata.id"] = url;
              asyncResp->res.jsonValue["Id"] = "Capabilities";
              asyncResp->res.jsonValue["Name"] = "Capabilities for Volumes";
              auto& nv = asyncResp->res.jsonValue["NVMeNamespaceProperties"];
              auto& allowable =
                  nv["LBAFormatsSupported@Redfish.AllowableValues"] =
                      nlohmann::json::array_t();
              auto& formatDesc = nv["LBAFormats"] = nlohmann::json::array_t();

              if (ec) {
                BMCWEB_LOG_WARNING
                    << "Failed to get SupportedFormats property for "
                    << storageId << " : " << ec.message();
                return;
              }

              for (const auto& [index, blockSize, metadataSize, relPerf] :
                   formats) {
                auto name = std::string("LBAFormat") + std::to_string(index);
                allowable.emplace_back(name);
                auto& f = formatDesc.emplace_back(nlohmann::json::object_t());
                auto rp = lookupRelativePerformance(relPerf);
                f["LBAFormatType"] = name;
                f["RelativePerformance"] = rp;
                f["LBADataSizeBytes"] = blockSize;
                f["LBAMetadataSizeBytes"] = metadataSize;
              }
            });
      });
}
inline void storageControllerHandler(
    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)) {
    BMCWEB_LOG_DEBUG << "Failed to setup Redfish Route for StorageController";
    return;
  }

  checkSystemAndStorage(asyncResp, systemName, storageId);

  storage_utils::findStorageAndController(
      asyncResp, storageId, controllerId,
      [asyncResp, storageId, systemName, controllerId](
          const sdbusplus::message::object_path& path,
          const dbus::utility::MapperServiceMap& ifaces) {
        populateStorageController(asyncResp, systemName, storageId,
                                  controllerId, path, ifaces);
      });
}

// This will be a dummy handler so plugins can be appended to the route.
inline void rootStorageControllerCollectionHandler(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    [[maybe_unused]] const std::string& storageId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    BMCWEB_LOG_DEBUG << "Failed to setup Redfish Route for StorageController";
    return;
  }
}

inline void requestRoutesStorageControllerCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/<str>/Controllers/")
      .privileges(redfish::privileges::getStorageControllerCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(storageControllerCollectionHandler, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Storage/<str>/Controllers/")
      .privileges(redfish::privileges::getStorageControllerCollection)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          rootStorageControllerCollectionHandler, std::ref(app)));
}

// This will be a dummy handler so plugins can be appended to the route.
inline void rootStorageControllerHandler(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    [[maybe_unused]] const std::string& storageId,
    [[maybe_unused]] const std::string& controllerId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    BMCWEB_LOG_DEBUG << "Failed to setup Redfish Route for StorageController";
    return;
  }
}

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

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

inline void requestRoutesStorageVolumeCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/<str>/Volumes/")
      .privileges(redfish::privileges::getVolumeCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(storageVolumeCollectionHandler, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/<str>/Volumes/")
      .privileges(redfish::privileges::postVolumeCollection)
      .methods(boost::beast::http::verb::post)(
          std::bind_front(storageVolumeCreateHandler, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Volumes/Capabilities")
      .privileges(redfish::privileges::getVolumeCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(storageVolumeCapabilitiesHandler, std::ref(app)));
}

inline void requestRoutesStorageVolume(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/<str>/Volumes/<str>")
      .privileges(redfish::privileges::getVolume)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(storageVolumeHandler, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/<str>/Volumes/<str>")
      .privileges(redfish::privileges::deleteVolume)
      .methods(boost::beast::http::verb::delete_)(
          std::bind_front(storageVolumeDeleteHandler, std::ref(app)));
}

inline void requestRoutesStorageControllerMetric(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Controllers/<str>/Oem/"
               "Google/Metrics/<str>")
      .privileges(redfish::privileges::privilegeSetLogin)
      .methods(boost::beast::http::verb::get)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& system, const std::string& storage,
                 const std::string& cntrl, const std::string& metric) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            asyncResp->res.jsonValue["@odata.id"] =
                crow::utility::urlFromPieces(
                    "redfish", "v1", "Systems", system, "Storage", storage,
                    "Controllers", cntrl, "Oem", "Google", "Metrics", metric);

            asyncResp->res.jsonValue["Name"] = metric;

            asyncResp->res
                .jsonValue["Actions"]["#GoogleNvmeMetric.RefreshMetric"]
                          ["target"] = crow::utility::urlFromPieces(
                "redfish", "v1", "Systems", system, "Storage", storage,
                "Controllers", cntrl, "Oem", "Google", "Metrics", metric,
                "Actions", "GoogleNvmeMetric.RefreshMetric");

            // TODO: verify system and storage relation

            nvmeControllerMetricFetcher(asyncResp, storage, cntrl, metric);
          });

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Controllers/<str>/Oem/"
               "Google/Metrics/<str>/Actions/GoogleNvmeMetric.RefreshMetric")
      .privileges(redfish::privileges::postStorageController)
      .methods(boost::beast::http::verb::post)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& system, const std::string& storage,
                 const std::string& cntrl, const std::string& metric) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            asyncResp->res.jsonValue["@odata.id"] =
                crow::utility::urlFromPieces(
                    "redfish", "v1", "Systems", system, "Storage", storage,
                    "Controllers", cntrl, "Oem", "Google", "Metrics", metric);

            asyncResp->res.jsonValue["Name"] = metric;

            nvmeControllerMetricRefresher(asyncResp, storage, cntrl, metric);
          });
}

inline void handleStorageVolumeMetricGet(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& system, const std::string& storage,
    const std::string& volume, const std::string& metric) {
  asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
      "redfish", "v1", "Systems", system, "Storage", storage, "Volumes", volume,
      "Oem", "Google", "Metrics", metric);

  asyncResp->res.jsonValue["Name"] = metric;

  checkSystemAndStorage(asyncResp, system, storage);

  findStorageVolume(
      asyncResp, storage, volume,
      [asyncResp, metric](const std::string& /* sPath */,
                          const std::string& vPath,
                          const std::string& /* connectionName */,
                          const dbus::utility::MapperServiceMap& ifaces) {
        nvmeMetricFetcher(asyncResp, vPath, ifaces, metric, {});
      });
}

inline void requestRoutesStorageVolumeMetric(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Storage/<str>/Volumes/<str>/Oem/"
               "Google/Metrics/<str>")
      .privileges(redfish::privileges::privilegeSetLogin)
      .methods(boost::beast::http::verb::get)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& system, const std::string& storage,
                 const std::string& volume, const std::string& metric) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            handleStorageVolumeMetricGet(asyncResp, system, storage, volume,
                                         metric);
          });
}

}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_STORAGE_H_
