#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_TRUSTED_COMPONENT_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_TRUSTED_COMPONENT_H_

/*
// Copyright (c) 2023 Google
/
// 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.
*/

#include <algorithm>
#include <array>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>

#include "boost/container/flat_map.hpp"  // NOLINT
#include "boost/system/error_code.hpp"  // NOLINT
#include "boost/url/format.hpp"  // NOLINT
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "chassis_utils.hpp"
#include "collection.hpp"
#include "dbus_utils.hpp"
#include "system_utils.hpp"
#include "component_integrity.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message/native_types.hpp"
#include "sdbusplus/unpack_properties.hpp"

#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp"  // NOLINT
#endif

namespace redfish {
// Interfaces which imply a D-Bus object represents a TrustedComponent
constexpr std::array<std::string_view, 1> trustedComponentInterfaces = {
    "xyz.openbmc_project.Inventory.Item.TrustedComponent"};
constexpr char const* discreteAttachType =
    "xyz.openbmc_project.Inventory.Item.TrustedComponent.ComponentAttachType."
    "Discrete";
constexpr char const* integratedAttachType =
    "xyz.openbmc_project.Inventory.Item.TrustedComponent.ComponentAttachType."
    "Integrated";
constexpr char const* decoratorAssetIntf =
    "xyz.openbmc_project.Inventory.Decorator.Asset";
constexpr char const* uuidIntf = "xyz.openbmc_project.Common.UUID";
constexpr char const* trustedComponentIntf =
    "xyz.openbmc_project.Inventory.Item.TrustedComponent";

/**
 * Map a given vector of D-Bus object path to an array of Redfish
 * URI.
 *
 * @param[in]       property1       Redfish property name.
 * @param[in]       property2       Optional second Redfish property name.
 * @param[in]       nodeList        vector of path string.
 *
 * @return          entities        Array of Redfish URI in json.
 */
inline std::optional<nlohmann::json> mapObjectPathVector(
    const std::string& property1, const std::string& property2,
    const std::vector<std::string>& pathList) {
  nlohmann::json entities = nlohmann::json::array();

  for (const std::string& node : pathList) {
    sdbusplus::message::object_path path(node);
    std::string entityId = path.filename();
    if (entityId.empty()) {
      BMCWEB_LOG_ERROR << "Invalid object path:" << property1 << " "
                       << property2 << ":" << path.str;
      return std::nullopt;
    }

    nlohmann::json::object_t entity;
    if (property2.empty()) {
      entity["@odata.id"] =
          crow::utility::urlFromPieces("redfish", "v1", property1, entityId);
    } else {
      entity["@odata.id"] = crow::utility::urlFromPieces(
          "redfish", "v1", property1, property2, entityId);
    }
    entities.push_back(std::move(entity));
  }

  return {std::move(entities)};
}

/**
 * Find the D-Bus object representing the requested TrustedComponent, and call
 * the handler with the results. If matching object is not found, add 404 error
 * to response and don't call the handler.
 *
 * @param[in,out]   resp            Async HTTP response.
 * @param[in]       chassisId       Redfish Chassis Id.
 * @param[in]       componentId     Redfish TrustedComponent Id.
 * @param[in]       handler         Callback to continue processing request upon
 *                                  successfully finding object.
 */
template <typename Handler>
inline void getTrustedComponentObject(
    const std::shared_ptr<bmcweb::AsyncResp>& resp,
    const std::string& chassisId, const std::string& componentId,
    Handler&& handler) {
  BMCWEB_LOG_DEBUG << "Get available chassis trusted_component resources.";

  // GetSubTree on all interfaces which provide info about TrustedComponent
  constexpr std::array<std::string_view, 1> interfaces = {trustedComponentIntf};
  std::string trustedComponentsPath =
      sdbusplus::message::object_path("/xyz/openbmc_project/Chassis") /
      chassisId / "TrustedComponents";
  managedStore::ManagedObjectStoreContext context(resp);
  managedStore::GetManagedObjectStore()->getSubTree(
      trustedComponentsPath, 0, interfaces, context,
      [resp, chassisId, componentId, handler](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
          messages::internalError(resp->res);
          return;
        }

        for (const auto& [objectPath, serviceMap] : subtree) {
          // Ignore any objects which don't end with our desired component
          // name
          if (!objectPath.ends_with(componentId)) {
            continue;
          }

          bool found = false;
          for (const auto& [serviceName, interfaceList] : serviceMap) {
            if (std::find_first_of(interfaceList.begin(), interfaceList.end(),
                                   trustedComponentInterfaces.begin(),
                                   trustedComponentInterfaces.end()) !=
                interfaceList.end()) {
              found = true;
              break;
            }
          }

          if (!found) {
            continue;
          }

          // Found something, populate Name and Id before get Interface info
          resp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
              "redfish", "v1", "Chassis", chassisId, "TrustedComponents",
              componentId);
          resp->res.jsonValue["Name"] = componentId;
          resp->res.jsonValue["Id"] = componentId;

          handler(objectPath, serviceMap);
          return;
        }
        messages::resourceNotFound(resp->res, "TrustedComponent", componentId);
      });
}

inline void getTrustedComponentIntegratedIntoInfo(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& trustedComponentObjPath,
    const boost::system::error_code& ec,
    const dbus::utility::MapperEndPoints& integratedIntoObjPaths) {
  if (ec) {
    if (ec.value() != EBADR) {
      BMCWEB_LOG_ERROR << "DBUS response error " << ec;
      messages::internalError(asyncResp->res);
    }
    return;
  }

  if (integratedIntoObjPaths.empty()) {
    return;
  }

  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  for (const auto& objpath : integratedIntoObjPaths) {
    sdbusplus::message::object_path integratedIntoObjPath(objpath);
    const std::string objName = integratedIntoObjPath.filename();
    if (objName.empty()) {
      BMCWEB_LOG_WARNING << "Malformed integratedInto object path "
                         << integratedIntoObjPath.str << " for "
                         << trustedComponentObjPath;
      continue;
    }
    managedStore::GetManagedObjectStore()->getDbusObject(
        objpath, {}, requestContext,
        [asyncResp, integratedIntoObjPath, trustedComponentObjPath,
         requestContext,
         objName](const boost::system::error_code& ec2,
                  const dbus::utility::MapperGetObject& object) {
          if (ec2) {
            BMCWEB_LOG_ERROR << "DBUS response error";
            messages::internalError(asyncResp->res);
            return;
          }

          nlohmann::json::object_t integratedPath;

          // Link can be Chassis or Board, Processor, and NetworkAdapters
          // handle Chassis or Board case
          if (redfish::dbus_utils::findInterfacesInServiceMap(
                  object, redfish::chassis_utils::chassisInterfaces)) {
            integratedPath["@odata.id"] = crow::utility::urlFromPieces(
                "redfish", "v1", "Chassis", objName);
            asyncResp->res.jsonValue["Links"]["IntegratedInto"] =
                std::move(integratedPath);
            return;
          }

          // handle NetworkAdaptors: parent resource can only be Chassis.
          if (redfish::dbus_utils::findInterfacesInServiceMap(
                  object, networkAdapterInterfaces)) {
            const std::string parentObj =
                integratedIntoObjPath.parent_path().filename();
            if (parentObj.empty()) {
              BMCWEB_LOG_WARNING << "Malformed integratedInto object path "
                                 << integratedIntoObjPath.str << " for "
                                 << trustedComponentObjPath;
              return;
            }

            integratedPath["@odata.id"] = crow::utility::urlFromPieces(
                "redfish", "v1", "Chassis", parentObj, "NetworkAdapters",
                objName);
            asyncResp->res.jsonValue["Links"]["IntegratedInto"] =
                std::move(integratedPath);
            return;
          }

          if (redfish::dbus_utils::findInterfacesInServiceMap(
                  object, processorsInterfaces)) {
            std::string parentPath = integratedIntoObjPath.parent_path().str;
            std::string parentObj =
                integratedIntoObjPath.parent_path().filename();
            // e.g.,
            // /xyz/openbmc_project/inventory/system/board/BoardName/system1/chassis/motherboard/cpu0
            // filter out chassis|motherboard in object path.
            while (parentObj == "motherboard" || parentObj == "chassis") {
              sdbusplus::message::object_path tempObjPath(parentPath);
              parentPath = tempObjPath.parent_path().str;
              parentObj = tempObjPath.parent_path().filename();
            }
            if (parentObj.empty()) {
              BMCWEB_LOG_WARNING << "Malformed integratedInto object path "
                                 << integratedIntoObjPath.str << " for "
                                 << trustedComponentObjPath;
              return;
            }
            managedStore::GetManagedObjectStore()->getDbusObject(
                parentPath, {}, requestContext,
                [asyncResp, objName, parentObj](
                    const boost::system::error_code& ec2,
                    const dbus::utility::MapperGetObject& object) {
                  if (ec2) {
                    BMCWEB_LOG_ERROR << "DBUS response error";
                    messages::internalError(asyncResp->res);
                    return;
                  }

                  // handle Processor: parent resource has to be Systems as
                  // OpenBMC only search for Processor under Systems though
                  // Redfish SPEC allows Processors to be modeled under Chassis
                  // starting from DSP2046_2022.3.pdf.
                  nlohmann::json::object_t integratedProcessorPath;
                  std::string parentResourceType;
                  std::string parentResourceName;
                  if (redfish::dbus_utils::findInterfacesInServiceMap(
                          object, redfish::chassis_utils::chassisInterfaces)) {
                    parentResourceType = "Systems";
                    parentResourceName = "system";
                  } else if (redfish::dbus_utils::findInterfacesInServiceMap(
                                 object,
                                 redfish::system_utils::systemInterfaces)) {
                    parentResourceType = "Systems";
                    parentResourceName = parentObj;
                  } else {
                    BMCWEB_LOG_ERROR << "Parent resource type not "
                                        "supported for Processor resource";
                    messages::internalError(asyncResp->res);
                    return;
                  }

                  integratedProcessorPath["@odata.id"] =
                      crow::utility::urlFromPieces(
                          "redfish", "v1", parentResourceType,
                          parentResourceName, "Processors", objName);
                  asyncResp->res.jsonValue["Links"]["IntegratedInto"] =
                      std::move(integratedProcessorPath);
                  return;
                });

            return;
          }  // end of Processor interfaces handling

          // Unsupported resource type
          BMCWEB_LOG_ERROR << "Unsupported IntegratedInto resource for "
                           << integratedIntoObjPath.str;
          messages::internalError(asyncResp->res);
          return;
        });
  }
}

/**
 * @brief Fill out TrustedComponent interface related info by
 * requesting data from the given D-Bus object.
 *
 * @param[in,out]   aResp       Async HTTP response.
 * @param[in]       service     D-Bus service to query.
 * @param[in]       objPath     D-Bus object to query.
 */
inline void getTrustedComponentInterfaceData(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& service,
    const std::string& objPath) {
  BMCWEB_LOG_DEBUG << "Get TrustedComponent Interface Data";
  managedStore::ManagedObjectStoreContext context(aResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      service, objPath, trustedComponentIntf, context,
      [objPath, aResp{aResp}, context](
          const boost::system::error_code& ec,
          const std::vector<std::pair<
              std::string, dbus::utility::DbusVariantType>>& properties) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS response error";
          messages::internalError(aResp->res);
          return;
        }

        const std::string* type = nullptr;
        const std::string* firmwareVersion = nullptr;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), properties, "FirmwareVersion",
            firmwareVersion, "TrustedComponentType", type);

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

        if ((firmwareVersion != nullptr) && !firmwareVersion->empty()) {
          aResp->res.jsonValue["FirmwareVersion"] = *firmwareVersion;
        }

        // For Root-of-Trust, it is safe to hardcode it as Embedded.
        aResp->res.jsonValue["Location"]["PartLocation"]["LocationType"] =
            "Embedded";

        // Get active software image info from associations.
        std::string activeSoftwarePath = objPath + "/actively_running";
        dbus_utils::getAssociationEndPoints(
            activeSoftwarePath, context,
            [aResp](
                const boost::system::error_code& e,
                const dbus::utility::MapperEndPoints& nodeActiveSoftwareList) {
              if (e) {
                if (e.value() != EBADR) {
                  messages::internalError(aResp->res);
                  return;
                }
                // No resource found.
                return;
              }

              // One TrustedComponent object should be associated with one
              // activeSoftwareImage object
              if (nodeActiveSoftwareList.size() != 1) {
                BMCWEB_LOG_ERROR
                    << "Unexpected ActiveSoftwareImage #objs (expecting 1): "
                    << nodeActiveSoftwareList.size();
                messages::internalError(aResp->res);
                return;
              }

              const std::string& softwareImageURI =
                  nodeActiveSoftwareList.at(0);
              sdbusplus::message::object_path activeSoftwareImage(
                  softwareImageURI);
              std::string softwareId = activeSoftwareImage.filename();

              nlohmann::json::object_t imagePath;

              if (softwareId.empty()) {
                BMCWEB_LOG_ERROR
                    << "TrustedComponent contains invalid activeSoftwareImage:"
                    << activeSoftwareImage.str;
                messages::internalError(aResp->res);
                return;
              }

              imagePath["@odata.id"] =
                  crow::utility::urlFromPieces("redfish", "v1", "UpdateService",
                                               "FirmwareInventory", softwareId);
              aResp->res.jsonValue["Links"]["ActiveSoftwareImage"] =
                  std::move(imagePath);
            });

        // Get ComponentIntegrity info from associations.
        std::string componentIntegrityPath = objPath + "/reported_by";
        dbus_utils::getAssociationEndPoints(
            componentIntegrityPath, context,
            [aResp](const boost::system::error_code& e,
                    const dbus::utility::MapperEndPoints&
                        nodeComponentIntegrityList) {
              if (e) {
                if (e.value() != EBADR) {
                  messages::internalError(aResp->res);
                  return;
                }
                // No resource found.
                return;
              }

              if (nodeComponentIntegrityList.empty()) {
                BMCWEB_LOG_DEBUG << "No ComponentIntegrity objects found!";
                return;
              }

              std::optional<nlohmann::json> components = mapObjectPathVector(
                  "ComponentIntegrity", "", nodeComponentIntegrityList);
              if (!components) {
                BMCWEB_LOG_ERROR << "ComponentIntegrity is invalid.";
                messages::internalError(aResp->res);
                return;
              }

              aResp->res.jsonValue["Links"]["ComponentIntegrity"] = *components;
            });

        // Get protected components info from associations.
        std::string protectedComponentPath = objPath + "/protecting";
        dbus_utils::getAssociationEndPoints(
            protectedComponentPath, context,
            std::bind_front(getProtectedComponentsInfo, aResp, objPath));

        // Get integratedInto info from associations.
        std::string integratedInto = objPath + "/integrated_into";
        dbus_utils::getAssociationEndPoints(
            integratedInto, context,
            std::bind_front(getTrustedComponentIntegratedIntoInfo, aResp,
                            objPath));

        // Get software images info from associations.
        std::string softwareImagesPath = objPath + "/runs";
        dbus_utils::getAssociationEndPoints(
            softwareImagesPath, context,
            [aResp](
                const boost::system::error_code& e,
                const dbus::utility::MapperEndPoints& nodeSoftwareImagesList) {
              if (e) {
                if (e.value() != EBADR) {
                  messages::internalError(aResp->res);
                  return;
                }
                // No resource found.
                return;
              }

              // One TrustedComponent object may be associated with one
              // or more SoftwareImage objects
              if (nodeSoftwareImagesList.empty()) {
                BMCWEB_LOG_DEBUG << "No software image objects found!";
                return;
              }

              std::optional<nlohmann::json> images = mapObjectPathVector(
                  "UpdateService", "FirmwareInventory", nodeSoftwareImagesList);
              if (!images) {
                BMCWEB_LOG_ERROR << "SoftwareImages is invalid.";
                messages::internalError(aResp->res);
                return;
              }
              aResp->res.jsonValue["Links"]["SoftwareImages"] = *images;
            });

        if ((type != nullptr) && !type->empty()) {
          if (*type == discreteAttachType) {
            aResp->res.jsonValue["TrustedComponentType"] = "Discrete";
          } else if (*type == integratedAttachType) {
            aResp->res.jsonValue["TrustedComponentType"] = "Integrated";
          } else {
            BMCWEB_LOG_ERROR << "Unrecognized ComponentAttachType!";
            messages::internalError(aResp->res);
            return;
          }
        } else {
          BMCWEB_LOG_ERROR << "No ComponentAttachType found!";
          messages::internalError(aResp->res);
          return;
        }
      });
}

/**
 * @brief Fill out Inventory.Decorator.Asset interface related info by
 * requesting data from the given D-Bus object.
 *
 * @param[in,out]   aResp       Async HTTP response.
 * @param[in]       service     D-Bus service to query.
 * @param[in]       objPath     D-Bus object to query.
 */
inline void getDecoratorAssetInterfaceData(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& service,
    const std::string& objPath) {
  BMCWEB_LOG_DEBUG << "Get Decorator.Asset Interface Data";
  managedStore::ManagedObjectStoreContext context(aResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      service, objPath, decoratorAssetIntf, context,
      [objPath, aResp{aResp}, context](
          const boost::system::error_code& ec,
          const std::vector<std::pair<
              std::string, dbus::utility::DbusVariantType>>& properties) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS response error for DecoratorAssetIntf!";
          messages::internalError(aResp->res);
          return;
        }

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

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), properties, "Manufacturer",
            manufacturer, "SerialNumber", serialNumber, "PartNumber",
            partNumber, "SKU", sku);

        if (!success) {
          BMCWEB_LOG_ERROR << "Unpacking Inventory.Decorator.Asset failed!";
          messages::internalError(aResp->res);
          return;
        }

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

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

        if ((sku != nullptr) && !sku->empty()) {
          aResp->res.jsonValue["SKU"] = *sku;
        }

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

/**
 * @brief Fill out Common.UUID interface related info by
 * requesting data from the given D-Bus object.
 *
 * @param[in,out]   aResp       Async HTTP response.
 * @param[in]       service     D-Bus service to query.
 * @param[in]       objPath     D-Bus object to query.
 */
inline void getCommonUUIDInterfaceData(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& service,
    const std::string& objPath) {
  BMCWEB_LOG_DEBUG << "Get Common.UUID Interface Data";
  managedStore::ManagedObjectStoreContext context(aResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      service, objPath, uuidIntf, context,
      [objPath, aResp{aResp}, context](
          const boost::system::error_code& ec,
          const std::vector<std::pair<
              std::string, dbus::utility::DbusVariantType>>& properties) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error";
          messages::internalError(aResp->res);
          return;
        }

        const std::string* uuid = nullptr;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), properties, "UUID", uuid);

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

        if ((uuid != nullptr) && !uuid->empty()) {
          aResp->res.jsonValue["UUID"] = *uuid;
        }
      });
}

inline void getTrustedComponentData(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& objectPath,
    const dbus::utility::MapperServiceMap& serviceMap) {
  for (const auto& [serviceName, interfaceList] : serviceMap) {
    for (const auto& interface : interfaceList) {
      if (interface == trustedComponentIntf) {
        getTrustedComponentInterfaceData(aResp, serviceName, objectPath);
      } else if (interface == decoratorAssetIntf) {
        getDecoratorAssetInterfaceData(aResp, serviceName, objectPath);
      } else if (interface == uuidIntf) {
        getCommonUUIDInterfaceData(aResp, serviceName, objectPath);
      }
    }
  }
}

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

  asyncResp->res.addHeader(boost::beast::http::field::link,
                           "</redfish/v1/JsonSchemas/TrustedComponent/"
                           "TrustedComponent.json>; rel=describedby");
  asyncResp->res.jsonValue["@odata.type"] =
      "#TrustedComponent.v1_0_0.TrustedComponent";

  getTrustedComponentObject(
      asyncResp, chassisId, componentId,
      std::bind_front(getTrustedComponentData, asyncResp));
}

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

  boost::urls::url url = crow::utility::urlFromPieces(
      "redfish", "v1", "Chassis", chassisId, "TrustedComponents");

  asyncResp->res.jsonValue["@odata.type"] =
      "#TrustedComponentCollection.TrustedComponentCollection";
  asyncResp->res.jsonValue["@odata.id"] = url.buffer();
  asyncResp->res.jsonValue["Name"] = "Trusted Component Collection";
  asyncResp->res.jsonValue["Description"] = "Collection of Trusted Components";

  std::string trustedComponentsPath =
      sdbusplus::message::object_path("/xyz/openbmc_project/Chassis") /
      chassisId / "TrustedComponents";

  collection_util::getCollectionMembers(asyncResp, url,
                                        trustedComponentInterfaces,
                                        trustedComponentsPath.c_str());
}

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

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

}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_TRUSTED_COMPONENT_H_
