/*
// 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.
*/
#pragma once

#include "app.hpp"
#include "dbus_utility.hpp"
#include "health.hpp"
#include "human_sort.hpp"
#include "managed_store_types.hpp"
#include "openbmc_dbus_rest.hpp"
#include "query.hpp"
#include "redfish_util.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/storage_utils.hpp"

#include <boost/system/error_code.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/unpack_properties.hpp>
#include <utils/location_utils.hpp>

#include <array>
#include <string_view>
#include <unordered_set>

namespace redfish
{
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;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        asyncResp->res.jsonValue["@odata.type"] =
            "#StorageCollection.StorageCollection";
        asyncResp->res.jsonValue["@odata.id"] =
            "/redfish/v1/Systems/system/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", "Systems", "system",
                                         "Storage"),
            interface);
        });

    BMCWEB_ROUTE(app, "/redfish/v1/Storage/")
        .privileges(redfish::privileges::getStorageCollection)
        .methods(boost::beast::http::verb::get)(
            [&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 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::managedObjectStore->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.push_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);
    managedStore::managedObjectStore->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* pwrseqPgood = 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, "PwrseqPgood", pwrseqPgood,
            "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::object_t customSSDJsonObj;
        customSSDJsonObj["@odata.type"] = customSSDOdataType;
        // Write Only and will always read as false.
        customSSDJsonObj["CpldReset"] = false;

        if (manufacturingMode != nullptr)
        {
            customSSDJsonObj["ManufacturingMode"] = *manufacturingMode;
        }
        if (pwrseqPgood != nullptr)
        {
            customSSDJsonObj["PwrseqPgood"] = *pwrseqPgood;
        }
        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";
        asyncResp->res
            .jsonValue["Links"]["Oem"]["Google"][std::string(customSSD)] =
            std::move(customSSDJsonObj);

        managedStore::managedObjectStore->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::managedObjectStore->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;
        }

        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 requestRoutesStorage(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/<str>/")
        .privileges(redfish::privileges::getStorage)
        .methods(boost::beast::http::verb::get)(
            [&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;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        constexpr std::array<std::string_view, 1> interfaces = {
            "xyz.openbmc_project.Inventory.Item.Storage"};
        managedStore::ManagedObjectStoreContext requestContext(asyncResp);
        managedStore::managedObjectStore->getSubTree(
            "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
            [asyncResp, storageId](
                const boost::system::error_code ec,
                const dbus::utility::MapperGetSubTreeResponse& 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::pair<std::string,
                                    dbus::utility::MapperServiceMap>& object) {
                return sdbusplus::message::object_path(object.first)
                           .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", "Systems",
                                             "system", "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->first);
            asyncResp->res.jsonValue["Controllers"]["@odata.id"] =
                crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                             "system", "Storage", storageId,
                                             "Controllers");
        });
        });

    BMCWEB_ROUTE(app, "/redfish/v1/Storage/<str>/")
        .privileges(redfish::privileges::getStorage)
        .methods(boost::beast::http::verb::get)(
            [&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::managedObjectStore->getSubTree(
            "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
            [asyncResp, storageId](
                const boost::system::error_code ec,
                const dbus::utility::MapperGetSubTreeResponse& 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::pair<std::string,
                                    dbus::utility::MapperServiceMap>& object) {
                return sdbusplus::message::object_path(object.first)
                           .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.
            nlohmann::json::array_t storageServices;
            nlohmann::json::object_t storageService;
            storageService["@odata.id"] = crow::utility::urlFromPieces(
                "redfish", "v1", "Systems", "system", "Storage", storageId);
            storageServices.emplace_back(storageService);
            asyncResp->res.jsonValue["Links"]["StorageServices"] =
                std::move(storageServices);
            asyncResp->res.jsonValue["Links"]["StorageServices@odata.count"] =
                1;
        });
        });
}

inline void getDriveAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& connectionName,
                          const std::string& path)
{
    managedStore::ManagedObjectStoreContext context(asyncResp);
    managedStore::managedObjectStore->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");
    return;
}

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

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

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::optional<std::string> chassisId = std::nullopt)
{
    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;
            location_util::getPartLocationContext(
                asyncResp, "/PhysicalLocation"_json_pointer, path + "/chassis");
        }
        else if (interface ==
                 "xyz.openbmc_project.Inventory.Decorator.LocationCode")
        {
            location_util::getLocationCode(asyncResp, connectionName, path,
                                           "/PhysicalLocation"_json_pointer);
        }
        else
        {
            std::optional<std::string> locationType =
                location_util::getLocationType(interface);
            if (!locationType)
            {
                BMCWEB_LOG_DEBUG << "getLocationType for Drive failed for "
                                 << interface;
                continue;
            }
            asyncResp->res
                .jsonValue["PhysicalLocation"]["PartLocation"]["LocationType"] =
                *locationType;
        }
    }

    if (driveInterface)
    {
        getDriveItemProperties(asyncResp, driveId, chassisId, connectionName,
                               path, driveStateInterface);
    }
}

/**
 * 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::managedObjectStore->getSubTree(
        "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
        [asyncResp,
         chassisId](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::utility::getAssociationEndPoints(
                path + "/drive",
                [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.push_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.push_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 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;

        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::managedObjectStore->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::internalError(asyncResp->res);
}

// Find Chassis with chassisId and the Drives associated to it.
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::managedObjectStore->getSubTree(
        "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
        [asyncResp, chassisId,
         cb](const boost::system::error_code& ec,
             const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (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() != chassisId)
            {
                continue;
            }

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

            dbus::utility::getAssociationEndPoints(path + "/drive", cb);
            break;
        }
    });
}

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

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

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

    sdbusplus::asio::setProperty<std::string>(
        *crow::connections::systemBus, connectionNames[0].first, path,
        "xyz.openbmc_project.State.Drive", "RequestedDriveTransition",
        action.c_str(),
        [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::managedObjectStore->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,
                            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::managedObjectStore->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);
        });
    });
}

/**
 * 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)(
            [&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);
        });
        });
}

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

/**
 * 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)(
            [](const crow::Request&,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
               const std::string& chassisId, const std::string& driveId) {
        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);
        });
        });
}

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 getStorageControllerLocation(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& service, const std::string& path,
    const std::vector<std::string>& interfaces)
{
    nlohmann::json::json_pointer locationPtr = "/Location"_json_pointer;
    for (const std::string& interface : interfaces)
    {
        if (interface == "xyz.openbmc_project.Inventory.Decorator.LocationCode")
        {
            location_util::getLocationCode(asyncResp, service, path,
                                           locationPtr);
        }
        if (location_util::isConnector(interface))
        {
            std::optional<std::string> locationType =
                location_util::getLocationType(interface);
            if (!locationType)
            {
                BMCWEB_LOG_DEBUG
                    << "getLocationType for StorageController failed for "
                    << interface;
                continue;
            }
            asyncResp->res
                .jsonValue[locationPtr]["PartLocation"]["LocationType"] =
                *locationType;
        }
    }
}

// TODO(matt): could move to dbus_utility.hpp
inline std::optional<std::string>
    matchServiceName(const dbus::utility::MapperServiceMap& allServices,
                     const std::string& matchIface)
{
    // TODO(matt): assumes only a single service matches
    for (const auto& [service, interfaces] : allServices)
    {
        for (const auto& interface : interfaces)
        {
            if (interface == matchIface)
            {
                return service;
            }
        }
    }
    return {};
}

inline void tryPopulateControllerNvme(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& path, const dbus::utility::MapperServiceMap& ifaces)
{
    if (!matchServiceName(ifaces, "xyz.openbmc_project.NVMe.NVMeAdmin"))
    {
        return;
    }

    auto& nvprop = asyncResp->res.jsonValue["NVMeControllerProperties"];
    // TODO(matt) fetch other properties, don't use hardcoded values
    nvprop["ControllerType"] = "IO";
    nvprop["NVMeVersion"] = "1.4";
    (void)path;
}

inline void tryPopulateControllerSecurity(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const boost::urls::url& controllerUrl,
    const dbus::utility::MapperServiceMap& ifaces)
{
    if (!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 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
    std::span<const uint8_t> data(
        reinterpret_cast<const uint8_t*>(dataString.data()), dataString.size());

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

    crow::connections::systemBus->async_method_call(
        [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)
        {
            messages::generalError(asyncResp->res);
            BMCWEB_LOG_DEBUG << "SecuritySend NVMe error";
            if (sd_err->message)
            {
                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
        },
        *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 = matchServiceName(
        ifaces, "xyz.openbmc_project.Inventory.Item.StorageControllerSecurity");
    if (!service)
    {
        BMCWEB_LOG_DEBUG << "No servicename";
        messages::internalError(asyncResp->res);
        return;
    }

    crow::connections::systemBus->async_method_call(
        [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)
        {
            messages::generalError(asyncResp->res);
            BMCWEB_LOG_DEBUG << "SecurityReceive NVMe error";
            if (sd_err->message)
            {
                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()));
        },
        *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));
    sdbusplus::asio::setProperty(
        *crow::connections::systemBus, "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,
                         std::string value)
{
    std::string customSSDDbusInterface =
        "com.google.gbmc.ssd." +
        boost::algorithm::to_lower_copy(std::string(customSSD));
    sdbusplus::asio::setProperty(
        *crow::connections::systemBus, "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 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)(
            [&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;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        uint8_t proto;
        uint16_t protoSpecific;
        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);
            });
        });

    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Systems/<str>/Storage/<str>/Controllers/<str>/Actions/StorageController.SecurityReceive")
        .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& systemName, const std::string& storageId,
                   const std::string& controllerId) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        uint8_t proto;
        uint16_t protoSpecific;
        uint32_t transferLength;

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

    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) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        if (!enableCustomSSD)
            return;

        nlohmann::json customSSDOem;
        if (!json_util::readJsonPatch(
                req, asyncResp->res,
                "Links/Oem/Google/" + std::string(customSSD), customSSDOem))
        {
            BMCWEB_LOG_DEBUG
                << std::string(customSSD) + " OEM is not in the patch input";
            return;
        }

        storage_utils::findStorageAndController(
            asyncResp, storageId, controllerId,
            [asyncResp,
             customSSDOem](const sdbusplus::message::object_path& path,
                           const dbus::utility::MapperServiceMap&) {
            std::string otpWriteEnableProperty =
                customSSDController + std::string("OtpWriteEnable");
            if (customSSDOem.contains("MorristownOtpWriteEnable"))
            {
                setCustomSSDOemGpio(asyncResp, path, otpWriteEnableProperty,
                                    customSSDOem[otpWriteEnableProperty]);
            }
            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"]);
            }
            });
        });
}

inline void populateStorageController(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    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;
    }

    asyncResp->res.jsonValue["@odata.type"] =
        "#StorageController.v1_7_0.StorageController";
    auto url = crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                            "system", "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";

    const std::string& connectionName = ifaces.front().first;
    getStorageControllerLocation(asyncResp, connectionName, path,
                                 ifaces.front().second);
    tryPopulateControllerNvme(asyncResp, path, ifaces);
    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::managedObjectStore->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 populateStorageControllerCollection(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    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, 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", "system", "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;
    }
    if (systemName != "system")
    {
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
        BMCWEB_LOG_DEBUG << "Failed to find ComputerSystem of " << systemName;
        return;
    }

    storage_utils::findStorage(
        asyncResp, storageId,
        [asyncResp,
         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", "system",
                                         "Storage", storageId, "Controllers");
        asyncResp->res.jsonValue["Name"] = "Storage Controller Collection";

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

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;
    }
    if (systemName != "system")
    {
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
        BMCWEB_LOG_DEBUG << "Failed to find ComputerSystem of " << systemName;
        return;
    }

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

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

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

} // namespace redfish
