#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_REDFISH_AGGREGATOR_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_REDFISH_AGGREGATOR_H_

#include <algorithm>
#include <array>
#include <chrono>  // NOLINT
#include <cstddef>
#include <cstdint>
#include <functional>
#include <limits>
#include <memory>
#include <random>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <unordered_map>
#include <utility>
#include <variant>

#include "boost/algorithm/string/predicate.hpp"  // NOLINT
#include "boost/url/parse.hpp"  // NOLINT
#include "boost/url/url.hpp"  // NOLINT
#include "bmcweb_config.h"
#include "http_client.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "request_stats.hpp"
#include "aggregation_utils.hpp"
#include "error_messages.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"

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

namespace redfish {

constexpr unsigned int aggregatorReadBodyLimit = 50 * 1024 * 1024;  // 50MB

enum class Result : std::uint8_t { LocalHandle, NoLocalHandle };

enum class SearchType : std::uint8_t {
  Collection,
  CollOrCon,
  ContainsSubordinate,
  Resource
};

struct RdeSatelliteConfig {
  std::string name;
  std::string vid;
  std::string udevid;
  std::string usbport;
  std::string objectpath;
  bool skipChassisCollectionAggregation = false;
};

// clang-format off
// These are all of the properties as of version 2022.2 of the Redfish Resource
// and Schema Guide whose Type is "string (URI)" and the name does not end in a
// case-insensitive form of "uri".  That version of the schema is associated
// with version 1.16.0 of the Redfish Specification.  Going forward, new URI
// properties should end in URI so this list should not need to be maintained as
// the spec is updated.  NOTE: These have been pre-sorted in order to be
// compatible with binary search
constexpr std::array nonUriProperties{
    "@Redfish.ActionInfo",
    // "@odata.context", // We can't fix /redfish/v1/$metadata URIs
    "@odata.id",
    // "Destination", // Only used by EventService and won't be a Redfish URI
    // "HostName", // Isn't actually a Redfish URI
    "Image",
    "MetricProperty",
    // "OriginOfCondition", // Is URI when in request, but is object in response
    "TaskMonitor",
    "target",  // normal string, but target URI for POST to invoke an action
};
// clang-format on

// Search the top collection array to determine if the passed URI is of a
// desired type
inline bool searchCollectionsArray(std::string_view uri,
                                   const SearchType searchType) {
  boost::system::result<boost::urls::url> parsedUrl =
      boost::urls::parse_relative_ref(uri);

  if (!parsedUrl) {
    BMCWEB_LOG_ERROR << "Failed to get target URI from " << uri;
    return false;
  }

  parsedUrl->normalize();
  boost::urls::segments_ref segments = parsedUrl->segments();
  if (!segments.is_absolute()) {
    return false;
  }

  // The passed URI must begin with "/redfish/v1", but we have to strip it
  // from the URI since topCollections does not include it in its URIs.
  if (segments.size() < 2) {
    return false;
  }
  if (segments.front() != "redfish") {
    return false;
  }
  segments.erase(segments.begin());
  if (segments.front() != "v1") {
    return false;
  }
  segments.erase(segments.begin());

  // Exclude the trailing "/" if it exists such as in "/redfish/v1/".
  if (!segments.empty() && segments.back().empty()) {
    segments.pop_back();
  }

  // If no segments then the passed URI was either "/redfish/v1" or
  // "/redfish/v1/".
  if (segments.empty()) {
    return (searchType == SearchType::ContainsSubordinate) ||
           (searchType == SearchType::CollOrCon);
  }
  std::string_view url = segments.buffer();
  const auto* it = std::ranges::lower_bound(topCollections, url);  // NOLINT
  if (it == topCollections.end()) {
    // parsedUrl is alphabetically after the last entry in the array so it
    // can't be a top collection or up tree from a top collection
    return false;
  }

  boost::urls::url collectionUrl(*it);
  boost::urls::segments_view collectionSegments = collectionUrl.segments();
  boost::urls::segments_view::iterator itCollection =
      collectionSegments.begin();
  const boost::urls::segments_view::const_iterator endCollection =
      collectionSegments.end();

  // Each segment in the passed URI should match the found collection
  for (const auto& segment : segments) {
    if (itCollection == endCollection) {
      // Leftover segments means the target is for an aggregation
      // supported resource
      return searchType == SearchType::Resource;
    }

    if (segment != (*itCollection)) {
      return false;
    }
    itCollection++;
  }

  // No remaining segments means the passed URI was a top level collection
  if (searchType == SearchType::Collection) {
    return itCollection == endCollection;
  }
  if (searchType == SearchType::ContainsSubordinate) {
    return itCollection != endCollection;
  }

  // Return this check instead of "true" in case other SearchTypes get added
  return searchType == SearchType::CollOrCon;
}

// Strip query params which are incompatible with aggregation.
// Note, this still doesn't work for collections that might return less than the
// complete collection by default, but hopefully those are rare/nonexistent in
// top collections.  bmcweb doesn't implement any of these.
inline void parameterRemove(crow::Request& localReq) {
  boost::urls::url& urlNew = localReq.mutableUrl();
  auto paramsIt = urlNew.params().begin();
  bool foundSkip = false;
  while (paramsIt != urlNew.params().end()) {
    const boost::urls::param& param = *paramsIt;

    // Plugins will not apply correctly to resources pulled in by offloading
    // $expand to a satellite BMC.  Don't forward $expand in that case.
    if constexpr (enablePlatform22) {
      if (param.key == "$expand") {
        BMCWEB_LOG_DEBUG << "Erasing $expand from forwarded request";
        paramsIt = urlNew.params().erase(paramsIt);
        continue;
      }
    }

    // By the spec, no other params should be provided with only. Don't
    // forward any params and let the aggregating BMC handle them.
    if (param.key == "only") {
      BMCWEB_LOG_DEBUG
          << "Erasing all params from request to top level collection";
      urlNew.params().clear();
      foundSkip = false;
      break;
    }

    if (param.key == "$skip") {
      foundSkip = true;
    }
    paramsIt++;
  }

  if (foundSkip) {
    // Remove $skip and any other param that is supposed to processed after
    // it.  Applying $skip twice would produce different results.
    // Forwarding just the non-$skip params would result in partially
    // processing the params in the wrong order.
    paramsIt = urlNew.params().begin();
    while (paramsIt != urlNew.params().end()) {
      const boost::urls::param& param = *paramsIt;
      // According to the Redfish spec, $filter is the only param that is
      // processed before $skip and is thus safe to be forwarded. All
      // others need to be removed
      if (param.key != "$filter") {
        BMCWEB_LOG_DEBUG << "Erasing \"" << param.key
                         << "\" param from request to top level collection";
        paramsIt = urlNew.params().erase(paramsIt);
        continue;
      }
      // Pass $filter parameter
      paramsIt++;
    }
  }
  localReq.target(urlNew.buffer());
}

// Determines if the passed property contains a URI.  Those property names
// either end with a case-insensitive version of "uri" or are specifically
// defined in the above array.
inline bool isPropertyUri(std::string_view propertyName) {
  return boost::iends_with(propertyName, "uri") ||
         std::binary_search(nonUriProperties.begin(), nonUriProperties.end(),
                            propertyName);
}

static inline void addPrefixToStringItem(std::string& strValue,
                                         std::string_view prefix) {
  // Make sure the value is a properly formatted URI
  auto parsed = boost::urls::parse_relative_ref(strValue);
  if (!parsed) {
    BMCWEB_LOG_CRITICAL << "Couldn't parse URI from resource " << strValue;
    return;
  }

  boost::urls::url_view thisUrl = *parsed;

  // We don't need to aggregate JsonSchemas due to potential issues such as
  // version mismatches between aggregator and satellite BMCs.  For now
  // assume that the aggregator has all the schemas and versions that the
  // aggregated server has.
  if (crow::utility::readUrlSegments(thisUrl, "redfish", "v1", "JsonSchemas",
                                     crow::utility::OrMorePaths())) {
    BMCWEB_LOG_DEBUG << "Skipping JsonSchemas URI prefix fixing";
    return;
  }

  // The first two segments should be "/redfish/v1".  We need to check that
  // before we can search topCollections
  if (!crow::utility::readUrlSegments(thisUrl, "redfish", "v1",
                                      crow::utility::OrMorePaths())) {
    return;
  }

  // Check array adding a segment each time until collection is identified
  // Add prefix to segment after the collection
  const boost::urls::segments_view urlSegments = thisUrl.segments();
  bool addedPrefix = false;
  boost::urls::url url("/");
  boost::urls::segments_view::iterator it = urlSegments.begin();
  const boost::urls::segments_view::const_iterator end = urlSegments.end();

  // Skip past the leading "/redfish/v1"
  it++;
  it++;
  for (; it != end; it++) {
    // Trailing "/" will result in an empty segment.  In that case we need
    // to return so we don't apply a prefix to top level collections such
    // as "/redfish/v1/Chassis/"
    if ((*it).empty()) {
      return;
    }

    if (std::binary_search(topCollections.begin(), topCollections.end(),
                           url.buffer())) {
      std::string collectionItem(prefix);
      collectionItem += "_" + (*it);
      url.segments().push_back(collectionItem);
      it++;
      addedPrefix = true;
      break;
    }

    url.segments().push_back(*it);
  }

  // Finish constructing the URL here (if needed) to avoid additional checks
  for (; it != end; it++) {
    url.segments().push_back(*it);
  }

  if (addedPrefix) {
    url.segments().insert(url.segments().begin(), {"redfish", "v1"});
    // Preserve the fragment from the original URL
    if (thisUrl.has_fragment()) {
      url.set_fragment(thisUrl.fragment());
    }
    strValue = url.buffer();
  }
}

static inline void addPrefixToItem(nlohmann::json& item,
                                   std::string_view prefix) {
  std::string* strValue = item.get_ptr<std::string*>();
  if (strValue == nullptr) {
    BMCWEB_LOG_CRITICAL << "Field wasn't a string????";
    return;
  }
  addPrefixToStringItem(*strValue, prefix);
  item = *strValue;
}

static inline int generateRandomInt() {
  std::random_device randomDevice;  // NOLINT
  std::mt19937 generator(randomDevice());
  std::uniform_int_distribution<> distribution(1, 9999);
  int randomNumber = distribution(generator);
  return randomNumber;
}

static inline void addAggregatedHeaders(crow::Response& asyncResp,
                                        const crow::Response& resp,
                                        std::string_view prefix) {
  if (!resp.getHeaderValue("Content-Type").empty()) {
    asyncResp.addHeader(boost::beast::http::field::content_type,
                        resp.getHeaderValue("Content-Type"));
  }
  if (!resp.getHeaderValue("Allow").empty()) {
    asyncResp.addHeader(boost::beast::http::field::allow,
                        resp.getHeaderValue("Allow"));
  }
  std::string_view header = resp.getHeaderValue("Location");
  if (!header.empty()) {
    std::string location(header);
    addPrefixToStringItem(location, prefix);
    asyncResp.addHeader(boost::beast::http::field::location, location);
  }
  if (!resp.getHeaderValue("Retry-After").empty()) {
    asyncResp.addHeader(boost::beast::http::field::retry_after,
                        resp.getHeaderValue("Retry-After"));
  }
  // TODO: we need special handling for Link Header Value
}

// Fix HTTP headers which appear in responses from Task resources among others
static inline void addPrefixToHeadersInResp(nlohmann::json& json,
                                            std::string_view prefix) {
  // The passed in "HttpHeaders" should be an array of headers
  nlohmann::json::array_t* array = json.get_ptr<nlohmann::json::array_t*>();
  if (array == nullptr) {
    BMCWEB_LOG_ERROR << "Field wasn't an array_t????";
    return;
  }

  for (nlohmann::json& item : *array) {
    // Each header is a single string with the form "<Field>: <Value>"
    std::string* strHeader = item.get_ptr<std::string*>();
    if (strHeader == nullptr) {
      BMCWEB_LOG_CRITICAL << "Field wasn't a string????";
      continue;
    }

    constexpr std::string_view location = "Location: ";
    if (strHeader->starts_with(location)) {
      std::string header = strHeader->substr(location.size());
      addPrefixToStringItem(header, prefix);
      *strHeader = std::string(location) + header;
    }
  }
}

// Search the json for all URIs and add the supplied prefix if the URI is for
// an aggregated resource.
static inline void addPrefixes(nlohmann::json& json, std::string_view prefix) {
  nlohmann::json::object_t* object = json.get_ptr<nlohmann::json::object_t*>();
  if (object != nullptr) {
    for (std::pair<const std::string, nlohmann::json>& item : *object) {
      if (isPropertyUri(item.first)) {
        addPrefixToItem(item.second, prefix);
        continue;
      }

      // "HttpHeaders" contains HTTP headers.  Among those we need to
      // attempt to fix the "Location" header
      if (item.first == "HttpHeaders") {
        addPrefixToHeadersInResp(item.second, prefix);
        continue;
      }

      // Recursively parse the rest of the json
      addPrefixes(item.second, prefix);
    }
    return;
  }
  nlohmann::json::array_t* array = json.get_ptr<nlohmann::json::array_t*>();
  if (array != nullptr) {
    for (nlohmann::json& item : *array) {
      addPrefixes(item, prefix);
    }
  }
}

// This struct is used to encode the settings that will be used for
// RdeAggregation. We want to be able to configure different parameters of the
// aggregation so we can store the settings in this struct and expand easily.
struct RdeAggregationSettings {
  std::string prefix;
  std::string serviceLabel;
  bool skipChassisCollectionAggregation = false;
};

inline std::unordered_map<std::string, RdeAggregationSettings>
    rdeAggregationSettingsMap(
        {{"/xyz/openbmc_project/rde_devices/1_1_1_1",
          {.prefix = "BCX5VT", .serviceLabel = "DOWNLINK"}},  // NOLINT
         {"/xyz/openbmc_project/rde_devices/1_1_2_1",
          {.prefix = "A61MJ0", .serviceLabel = "DOWNLINK"}},
         {"/xyz/openbmc_project/rde_devices/1_1_3_1",
          {.prefix = "K298LC", .serviceLabel = "DOWNLINK"}},
         {"/xyz/openbmc_project/rde_devices/1_1_4_1",
          {.prefix = "2HMMCS", .serviceLabel = "PCIE0"}},
         {"/xyz/openbmc_project/rde_devices/1_1_5_1_1",
          {.prefix = "SB_86",
           .serviceLabel = "DOWNLINK",
           .skipChassisCollectionAggregation = true}},
         {"/xyz/openbmc_project/rde_devices/1_1_5_3_1",
          {.prefix = "SB_88",
           .serviceLabel = "DOWNLINK",
           .skipChassisCollectionAggregation = true}},
         {"/xyz/openbmc_project/rde_devices/1_1_6_1_1",
          {.prefix = "SB_96",
           .serviceLabel = "DOWNLINK",
           .skipChassisCollectionAggregation = true}}});

inline static bool generatePrefix(const std::string& objPath,
                                  std::string& prefix) {
  const auto& it = rdeAggregationSettingsMap.find(objPath);
  if (it == rdeAggregationSettingsMap.end()) {
    BMCWEB_LOG_DEBUG << "objPath does not exist in prefix map " << objPath
                     << "\n";
    return false;
  }
  prefix = it->second.prefix;
  return true;
}

static inline bool isMemberStartsWithKnownPrefix(
    const std::string& memberName) {
  BMCWEB_LOG_DEBUG << "isMemberStartsWithKnownPrefix";
  for (auto const& [path, settings] : rdeAggregationSettingsMap) {
    BMCWEB_LOG_DEBUG << "path " << path << " " << settings.prefix;
    if (memberName.starts_with(settings.prefix)) {
      BMCWEB_LOG_DEBUG << " Known prefix " << memberName;
      return true;
    }
  }
  return false;
}

inline static std::string getServiceLabel(std::string_view prefix) {
  for (auto const& [path, settings] : rdeAggregationSettingsMap) {
    if (settings.prefix == prefix) {
      return settings.serviceLabel;
    }
  }
  return "";
}

inline boost::system::error_code aggregationRetryHandler(
    unsigned int respCode) {
  // Allow all response codes because we want to surface any satellite
  // issue to the client
  BMCWEB_LOG_DEBUG << "Received " << respCode << " response from satellite";
  return boost::system::errc::make_error_code(boost::system::errc::success);
}

inline crow::ConnectionPolicy getAggregationPolicy() {
  return {.maxRetryAttempts = 1,
          .requestByteLimit = aggregatorReadBodyLimit,
          .maxConnections = 20,
          .retryPolicyAction = "TerminateAfterRetries",
          .retryIntervalSecs = std::chrono::seconds(0),
          .invalidResp = aggregationRetryHandler};
}

inline bool shouldSkipRequestAggregation(const RdeSatelliteConfig& rdeConfig,
                                         std::string_view url) {
  // Remove the trailing slash if it exists
  if (url.ends_with('/')) {
    url.remove_suffix(1);
  }

  // I know that the if statement isn't necessary as we can return the condition
  // directly, but I want to setup this pattern for future expansion if we need
  // to skip other collection resources.
  if (rdeConfig.skipChassisCollectionAggregation &&
      url == "/redfish/v1/Chassis") {
    return true;
  }
  return false;
}

class RedfishAggregator {
 private:
  crow::HttpClient client;

  RedfishAggregator()
      : client(
            std::make_shared<crow::ConnectionPolicy>(getAggregationPolicy())) {
    getSatelliteConfigs(constructorCallback);
  }

  // Dummy callback used by the Constructor so that it can report the number
  // of satellite configs when the class is first created
  static void constructorCallback(
      const boost::system::error_code& ec,
      const std::unordered_map<std::string, boost::urls::url>& satelliteInfo,
      const std::unordered_map<std::string, RdeSatelliteConfig>&
          rdeSatelliteInfo) {
    if (ec) {
      BMCWEB_LOG_ERROR << "Something went wrong while querying dbus!";
      return;
    }

    BMCWEB_LOG_DEBUG << "There were " << std::to_string(satelliteInfo.size())
                     << " satellite configs found at startup";
    BMCWEB_LOG_DEBUG << "There were " << std::to_string(rdeSatelliteInfo.size())
                     << " RDE Device configs found at startup";
  }

  // Search D-Bus objects for satellite config objects and add their
  // information if valid
  static void findSatelliteConfigs(
      const dbus::utility::ManagedObjectType& objects,
      std::unordered_map<std::string, boost::urls::url>& satelliteInfo,
      std::unordered_map<std::string, RdeSatelliteConfig>& rdeSatelliteInfo) {
    for (const auto& objectPath : objects) {
      for (const auto& interface : objectPath.second) {
        if (interface.first ==
            "xyz.openbmc_project.Configuration.SatelliteController") {
          BMCWEB_LOG_DEBUG << "Found Satellite Controller at "
                           << objectPath.first.str;

          if (!satelliteInfo.empty()) {
            BMCWEB_LOG_ERROR
                << "Redfish Aggregation only supports one satellite!";
            BMCWEB_LOG_DEBUG << "Clearing all satellite data";
            satelliteInfo.clear();
            return;
          }

          // For now assume there will only be one satellite config.
          // Assign it the name/prefix "5B247A"
          addSatelliteConfig("5B247A", interface.second, satelliteInfo);
        } else if (interface.first ==
                   "xyz.openbmc_project.Configuration.RdeSatelliteController") {
          BMCWEB_LOG_DEBUG << "Found RDE Satellite Controller at "
                           << objectPath.first.str;
          addRdeSatelliteConfig(interface.second, rdeSatelliteInfo);
        }
      }
    }
  }

  // Parse the properties of a satellite config object and add the
  // configuration if the properties are valid
  static void addSatelliteConfig(
      const std::string& name,
      const dbus::utility::DBusPropertiesMap& properties,
      std::unordered_map<std::string, boost::urls::url>& satelliteInfo) {
    boost::urls::url url;

    for (const auto& prop : properties) {
      if (prop.first == "Hostname") {
        const std::string* propVal = std::get_if<std::string>(&prop.second);
        if (propVal == nullptr) {
          BMCWEB_LOG_ERROR << "Invalid Hostname value";
          return;
        }
        url.set_host(*propVal);
      } else if (prop.first == "Port") {
        const uint64_t* propVal = std::get_if<uint64_t>(&prop.second);
        if (propVal == nullptr) {
          BMCWEB_LOG_ERROR << "Invalid Port value";
          return;
        }

        if (*propVal > std::numeric_limits<uint16_t>::max()) {
          BMCWEB_LOG_ERROR << "Port value out of range";
          return;
        }
        url.set_port(std::to_string(static_cast<uint16_t>(*propVal)));
      } else if (prop.first == "AuthType") {
        const std::string* propVal = std::get_if<std::string>(&prop.second);
        if (propVal == nullptr) {
          BMCWEB_LOG_ERROR << "Invalid AuthType value";
          return;
        }

        // For now assume authentication not required to communicate
        // with the satellite BMC
        if (*propVal != "None") {
          BMCWEB_LOG_ERROR << "Unsupported AuthType value: " << *propVal
                           << ", only \"none\" is supported";
          return;
        }
        url.set_scheme("http");
      }
    }  // Finished reading properties

    // Make sure all required config information was made available
    if (url.host().empty()) {
      BMCWEB_LOG_ERROR << "Satellite config " << name << " missing Host";
      return;
    }

    if (!url.has_port()) {
      BMCWEB_LOG_ERROR << "Satellite config " << name << " missing Port";
      return;
    }

    if (!url.has_scheme()) {
      BMCWEB_LOG_ERROR << "Satellite config " << name << " missing AuthType";
      return;
    }

    std::string resultString;
    auto result = satelliteInfo.insert_or_assign(name, std::move(url));
    if (result.second) {
      resultString = "Added new satellite config ";
    } else {
      resultString = "Updated existing satellite config ";
    }

    BMCWEB_LOG_DEBUG << resultString << name << " at "
                     << result.first->second.scheme() << "://"
                     << result.first->second.encoded_host_and_port();
  }

  // Parse the properties of a RDE Device config object and add the
  // configuration if the properties are valid
  static void addRdeSatelliteConfig(
      const dbus::utility::DBusPropertiesMap& properties,
      std::unordered_map<std::string, RdeSatelliteConfig>& rdeSatelliteInfo) {
    RdeSatelliteConfig rdeConfig;
    std::string name;
    for (const auto& prop : properties) {
      if (prop.first == "Name") {
        const std::string* propVal = std::get_if<std::string>(&prop.second);
        if (propVal == nullptr) {
          BMCWEB_LOG_ERROR << "Invalid Name value";
          return;
        }
        rdeConfig.name = *propVal;
      } else if (prop.first == "VID") {
        const std::string* propVal = std::get_if<std::string>(&prop.second);
        if (propVal == nullptr) {
          BMCWEB_LOG_ERROR << "Invalid VID value";
          return;
        }
        rdeConfig.vid = *propVal;
      } else if (prop.first == "UDEVID") {
        const std::string* propVal = std::get_if<std::string>(&prop.second);
        if (propVal == nullptr) {
          BMCWEB_LOG_ERROR << "Invalid UDEVID value";
          return;
        }
        rdeConfig.udevid = *propVal;
      } else if (prop.first == "USBPORT") {
        const std::string* propVal = std::get_if<std::string>(&prop.second);
        if (propVal == nullptr) {
          BMCWEB_LOG_ERROR << "Invalid USBPORT value";
          return;
        }
        rdeConfig.usbport = *propVal;
      }
    }  // Finished reading properties

    if (rdeConfig.udevid.empty()) {
      BMCWEB_LOG_ERROR << "Empty udevid";
      return;
    }
    rdeConfig.objectpath =
        "/xyz/openbmc_project/rde_devices/" + rdeConfig.udevid;

    // Set the prefix to a random string 'E0SB8D'
    // (TODO) Generate a unique random prefix for each RDE Device
    if constexpr (bmcwebEnableRdeDevice) {
      if (!generatePrefix(rdeConfig.objectpath, name)) {
        BMCWEB_LOG_ERROR << " Failed to get a prefix for "
                         << rdeConfig.objectpath;
        return;
      }
      BMCWEB_LOG_DEBUG << " Got prefix " << name;
    }

    rdeConfig.skipChassisCollectionAggregation =
        rdeAggregationSettingsMap[rdeConfig.objectpath]
            .skipChassisCollectionAggregation;

    std::string resultString;
    auto result = rdeSatelliteInfo.emplace(name, std::move(rdeConfig));
    if (result.second) {
      resultString = "Added new RDE Device config ";
    } else {
      resultString = "Updated existing RDE Device config ";
    }
  }

  enum AggregationType : std::uint8_t {
    Collection,
    ContainsSubordinate,
    Resource,
  };

  static void startAggregation(
      AggregationType aggType, const crow::Request& thisReq,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
    if (thisReq.method() != boost::beast::http::verb::get) {
      if (aggType == AggregationType::Collection) {
        BMCWEB_LOG_DEBUG
            << "Only aggregate GET requests to top level collections";
        return;
      }

      if (aggType == AggregationType::ContainsSubordinate) {
        BMCWEB_LOG_DEBUG << "Only aggregate GET requests when uptree of"
                         << " a top level collection";
        return;
      }
    }

    // Create a copy of thisReq so we we can still locally process the req
    std::error_code ec;
    auto localReq = std::make_shared<crow::Request>(thisReq.req, ec);
    if (ec) {
      BMCWEB_LOG_ERROR << "Failed to create copy of request";
      if (aggType == AggregationType::Resource) {
        messages::internalError(asyncResp->res);
      }
      return;
    }

    // Strip query params that don't work correctly if forwarded
    parameterRemove(*localReq);

    getSatelliteConfigs(
        std::bind_front(aggregateAndHandle, aggType, localReq, asyncResp));
  }

  static void findSatellite(
      const crow::Request& req,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      const std::unordered_map<std::string, boost::urls::url>& satelliteInfo,
      const std::unordered_map<std::string, RdeSatelliteConfig>&
          rdeSatelliteInfo,
      std::string_view memberName) {
    bool validPrefix = false;
    // Determine if the resource ID begins with a known prefix
    for (const auto& satellite : satelliteInfo) {
      std::string targetPrefix = satellite.first;
      targetPrefix += "_";
      if (memberName.starts_with(targetPrefix)) {
        BMCWEB_LOG_DEBUG << "\"" << satellite.first << "\" is a known prefix";

        // Remove the known prefix from the request's URI and
        // then forward to the associated satellite BMC
        getInstance().forwardRequest(req, asyncResp, satellite.first,
                                     satelliteInfo);
        validPrefix = true;
      }
    }
    // Determine if the resource ID begins with a known prefix
    for (const auto& rdeSatellite : rdeSatelliteInfo) {
      std::string targetPrefix = rdeSatellite.first;
      targetPrefix += "_";
      if (memberName.starts_with(targetPrefix)) {
        BMCWEB_LOG_DEBUG << "\"" << rdeSatellite.first
                         << "\" is a known prefix";
        // Remove the known prefix from the request's URI and
        // then forward to RDE Daemon
        forwardRdeRequest(req, asyncResp, rdeSatellite.first, rdeSatelliteInfo);
        validPrefix = true;
      }
    }
    if (validPrefix) {
      return;
    }
    // We didn't recognize the prefix and need to return a 404
    std::string nameStr = req.url().segments().back();
    messages::resourceNotFound(asyncResp->res, "", nameStr);
  }

  // Intended to handle an incoming request based on if Redfish Aggregation
  // is enabled.  Forwards request to satellite BMC if it exists.
  static void aggregateAndHandle(
      AggregationType aggType, const std::shared_ptr<crow::Request>& sharedReq,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      const boost::system::error_code& ec,
      const std::unordered_map<std::string, boost::urls::url>& satelliteInfo,
      const std::unordered_map<std::string, RdeSatelliteConfig>&
          rdeSatelliteInfo) {
    if (sharedReq == nullptr) {
      return;
    }
    // Something went wrong while querying dbus
    if (ec) {
      messages::internalError(asyncResp->res);
      return;
    }

    // No satellite or RDE configs means we don't need to keep attempting to
    // aggregate
    if (satelliteInfo.empty() && rdeSatelliteInfo.empty()) {
      // For collections or resources that can contain a subordinate
      // top level collection we'll also handle the request locally so we
      // don't need to write an error code
      if (aggType == AggregationType::Resource) {
        std::string nameStr = sharedReq->url().segments().back();
        messages::resourceNotFound(asyncResp->res, "", nameStr);
      }
      return;
    }

    const crow::Request& thisReq = *sharedReq;
    if constexpr (enablePlatform9) {
      BMCWEB_LOG_DEBUG << "Aggregation is enabled, begin processing of "
                       << thisReq.url();
    } else {
      BMCWEB_LOG_DEBUG << "Aggregation is enabled, begin processing of "
                       << thisReq.target();
    }

    // We previously determined the request is for a collection.  No need to
    // check again
    if (aggType == AggregationType::Collection) {
      BMCWEB_LOG_DEBUG << "Aggregating a collection";
      // We need to use a specific response handler and send the
      // request to all known satellites
      getInstance().forwardCollectionRequests(thisReq, asyncResp, satelliteInfo,
                                              rdeSatelliteInfo);
      return;
    }

    // We previously determined the request may contain a subordinate
    // collection.  No need to check again
    if (aggType == AggregationType::ContainsSubordinate) {
      BMCWEB_LOG_DEBUG << "Aggregating what may have a subordinate collection";
      // We need to use a specific response handler and send the
      // request to all known satellites
      getInstance().forwardContainsSubordinateRequests(thisReq, asyncResp,
                                                       satelliteInfo);
      return;
    }

    const boost::urls::segments_view urlSegments = thisReq.url().segments();
    boost::urls::url currentUrl("/");
    boost::urls::segments_view::iterator it = urlSegments.begin();
    const boost::urls::segments_view::const_iterator end = urlSegments.end();

    // Skip past the leading "/redfish/v1"
    it++;
    it++;
    for (; it != end; it++) {
      if (std::binary_search(topCollections.begin(), topCollections.end(),
                             currentUrl.buffer())) {
        // We've matched a resource collection so this current segment
        // must contain an aggregation prefix
        findSatellite(thisReq, asyncResp, satelliteInfo, rdeSatelliteInfo, *it);
        return;
      }

      currentUrl.segments().push_back(*it);
    }

    // We shouldn't reach this point since we should've hit one of the
    // previous exits
    messages::internalError(asyncResp->res);
  }

  // Attempt to forward a request to the satellite BMC associated with the
  // prefix.
  void forwardRequest(
      const crow::Request& thisReq,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      const std::string& prefix,
      const std::unordered_map<std::string, boost::urls::url>& satelliteInfo) {
    const auto& sat = satelliteInfo.find(prefix);
    if (sat == satelliteInfo.end()) {
      // Realistically this shouldn't get called since we perform an
      // earlier check to make sure the prefix exists
      BMCWEB_LOG_ERROR << "Unrecognized satellite prefix \"" << prefix << "\"";
      return;
    }

    // We need to strip the prefix from the request's path
    std::string targetURI;
    if constexpr (enablePlatform9) {
      targetURI = std::string(thisReq.url().path());
    } else {
      targetURI = std::string(thisReq.target());
    }

    size_t pos = targetURI.find(prefix + "_");
    if (pos == std::string::npos) {
      // If this fails then something went wrong
      BMCWEB_LOG_ERROR << "Error removing prefix \"" << prefix
                       << "_\" from request URI";
      messages::internalError(asyncResp->res);
      return;
    }
    targetURI.erase(pos, prefix.size() + 1);

    std::function<void(crow::Response&)> cb =
        std::bind_front(processResponse, prefix, asyncResp);

    std::string data = thisReq.req.body();
    client.sendDataWithCallback(
        data, std::string(sat->second.host()), sat->second.port_number(),
        targetURI, false /*useSSL*/, thisReq.fields(), thisReq.method(), cb);
  }

  // Forward a request for a collection URI to each known satellite BMC
  void forwardCollectionRequests(
      const crow::Request& thisReq,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      const std::unordered_map<std::string, boost::urls::url>& satelliteInfo,
      const std::unordered_map<std::string, RdeSatelliteConfig>&
          rdeSatelliteInfo) {
    for (const auto& sat : satelliteInfo) {
      std::function<void(crow::Response&)> cb =
          std::bind_front(processCollectionResponse, sat.first, asyncResp);

      std::string targetURI;
      if constexpr (enablePlatform9) {
        targetURI = std::string(thisReq.url().path());
      } else {
        targetURI = std::string(thisReq.target());
      }
      std::string data = thisReq.req.body();
      client.sendDataWithCallback(
          data, std::string(sat.second.host()), sat.second.port_number(),
          targetURI, false /*useSSL*/, thisReq.fields(), thisReq.method(), cb);
    }
    for (const auto& rsat : rdeSatelliteInfo) {
      uint8_t operationId = 1;
      std::string requestPayload;
      BMCWEB_LOG_DEBUG << " Collection Request: dbus call to RDE Daemon "
                       << " operationId " << operationId;
      if (shouldSkipRequestAggregation(rsat.second, thisReq.url().path())) {
        continue;
      }
      std::string targetURI(thisReq.target());
      if (managedStore::RequestStatsStore::isRdeRateLimitEnabled() &&
          managedStore::RequestStatsStore::instance()
                  .getCurrentRdeRequestSkips() > 0) {
        BMCWEB_LOG_DEBUG << " Skipping the request " << targetURI;
        asyncResp->requestStatsContext->updateRdeSkips();
        managedStore::RequestStatsStore::instance()
            .updateCurrentRdeRequestSkips();
        return;
      }
      BMCWEB_LOG_DEBUG << "Collections objpath " << rsat.second.objectpath
                       << " targetURI " << targetURI << " udevid "
                       << rsat.second.udevid;
      asyncResp->res.startTimetrace(rsat.first);
      if (managedStore::RequestStatsStore::isRdeRateLimitEnabled()) {
        asyncResp->requestStatsContext->updateRdeReqs();
      }
      managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
          asyncResp->strand_,
          [&operationId, rsat, asyncResp](const boost::system::error_code ec,
                                          const std::string& jsonString) {
            if (ec) {
              BMCWEB_LOG_ERROR << "DBUS response error operationId "
                               << operationId << " , " << ec.value() << ", "
                               << ec.message();
              if (managedStore::RequestStatsStore::isRdeRateLimitEnabled()) {
                asyncResp->requestStatsContext->updateRdeDbusErrors();
                managedStore::RequestStatsStore::instance()
                    .updateCurrentRdeDbusErrors();
                if (managedStore::RequestStatsStore::instance()
                            .getCurrentRdeDbusErrors() >
                        managedStore::RequestStatsStore::rdeErrorThreshold() &&
                    managedStore::RequestStatsStore::instance()
                            .getCurrentRdeRequestSkips() <= 0) {
                  BMCWEB_LOG_ERROR << "RDE Rate Limit enabled";
                  asyncResp->requestStatsContext->updateRdeRateLimitToggles();
                  managedStore::RequestStatsStore::instance()
                      .setCurrentRdeRequestSkips(
                          managedStore::RequestStatsStore::rdeMaxSkips());
                }
              }
              return;
            }
            if (managedStore::RequestStatsStore::isRdeRateLimitEnabled()) {
              managedStore::RequestStatsStore::instance()
                  .setCurrentRdeDbusErrors(0);
              managedStore::RequestStatsStore::instance()
                  .setCurrentRdeRequestSkips(0);
            }
            processRdeCollectionResponse(rsat.first, asyncResp, jsonString);
          },
          "xyz.openbmc_project.rdeoperation", rsat.second.objectpath,
          "xyz.openbmc_project.RdeDevice", "execute_rde", generateRandomInt(),
          operationId, targetURI, rsat.second.udevid, requestPayload);
    }
  }

  // Forward request for a URI that is uptree of a top level collection to
  // each known satellite BMC
  void forwardContainsSubordinateRequests(
      const crow::Request& thisReq,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      const std::unordered_map<std::string, boost::urls::url>& satelliteInfo) {
    for (const auto& sat : satelliteInfo) {
      std::function<void(crow::Response&)> cb = std::bind_front(
          processContainsSubordinateResponse, sat.first, asyncResp);

      std::string targetURI(thisReq.target());
      std::string data = thisReq.req.body();
      client.sendDataWithCallback(
          data, std::string(sat.second.host()), sat.second.port_number(),
          targetURI, false /*useSSL*/, thisReq.fields(), thisReq.method(), cb);
    }
  }

  // Attempt to forward a request to the RDE Daemon associated with the
  // prefix.
  static void forwardRdeRequest(
      const crow::Request& thisReq,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      const std::string& prefix,
      const std::unordered_map<std::string, RdeSatelliteConfig>&
          rdeSatelliteInfo) {
    const auto& sat = rdeSatelliteInfo.find(prefix);
    if (sat == rdeSatelliteInfo.end()) {
      // Realistically this shouldn't get called since we perform an
      // earlier check to make sure the prefix exists
      BMCWEB_LOG_ERROR << "Unrecognized RDE Device prefix \"" << prefix << "\"";
      return;
    }

    // We need to strip the prefix from the request's path
    std::string targetURI(thisReq.target());
    if (managedStore::RequestStatsStore::isRdeRateLimitEnabled() &&
        managedStore::RequestStatsStore::instance()
                .getCurrentRdeRequestSkips() > 0) {
      BMCWEB_LOG_DEBUG << " Skipping the request " << targetURI;
      asyncResp->requestStatsContext->updateRdeSkips();
      managedStore::RequestStatsStore::instance()
          .updateCurrentRdeRequestSkips();
      return;
    }
    size_t pos = targetURI.find(prefix + "_");
    if (pos == std::string::npos) {
      // If this fails then something went wrong
      BMCWEB_LOG_ERROR << "Error removing prefix \"" << prefix
                       << "_\" from request URI";
      messages::internalError(asyncResp->res);
      return;
    }
    targetURI.erase(pos, prefix.size() + 1);

    uint8_t operationId = 1;
    std::string requestPayload;
    boost::beast::http::verb method = thisReq.method();
    if (thisReq.method() == boost::beast::http::verb::post) {
      operationId = 8;
      requestPayload = thisReq.body();
    } else if (thisReq.method() == boost::beast::http::verb::patch) {
      operationId = 4;
      requestPayload = thisReq.body();
    }
    BMCWEB_LOG_DEBUG
        << " Resource Request: dbus call to RDE Daemon operationId "
        << operationId;
    BMCWEB_LOG_DEBUG << "objpath " << sat->second.objectpath << " targetURI "
                     << targetURI << " udevid " << sat->second.udevid
                     << " method " << method;
    asyncResp->res.startTimetrace(prefix);
    if (managedStore::RequestStatsStore::isRdeRateLimitEnabled()) {
      asyncResp->requestStatsContext->updateRdeReqs();
    }
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [&operationId, method, prefix, asyncResp](
            const boost::system::error_code ec, const std::string& jsonString) {
          if (ec) {
            BMCWEB_LOG_ERROR << "DBUS response error operationId "
                             << operationId << " , " << ec.value() << ", "
                             << ec.message();
            if (managedStore::RequestStatsStore::isRdeRateLimitEnabled()) {
              asyncResp->requestStatsContext->updateRdeDbusErrors();
              managedStore::RequestStatsStore::instance()
                  .updateCurrentRdeDbusErrors();

              if (managedStore::RequestStatsStore::instance()
                          .getCurrentRdeDbusErrors() >
                      managedStore::RequestStatsStore::rdeErrorThreshold() &&
                  managedStore::RequestStatsStore::instance()
                          .getCurrentRdeRequestSkips() <= 0) {
                BMCWEB_LOG_ERROR << "RDE Rate limiting enabled";
                asyncResp->requestStatsContext->updateRdeRateLimitToggles();
                managedStore::RequestStatsStore::instance()
                    .setCurrentRdeRequestSkips(
                        managedStore::RequestStatsStore::rdeMaxSkips());
              }
            }
            return;
          }
          if (managedStore::RequestStatsStore::isRdeRateLimitEnabled()) {
            managedStore::RequestStatsStore::instance().setCurrentRdeDbusErrors(
                0);
            managedStore::RequestStatsStore::instance()
                .setCurrentRdeRequestSkips(0);
          }
          processRdeResponse(prefix, method, asyncResp, jsonString);
        },
        "xyz.openbmc_project.rdeoperation", sat->second.objectpath,
        "xyz.openbmc_project.RdeDevice", "execute_rde", generateRandomInt(),
        operationId, targetURI, sat->second.udevid, requestPayload);
  }
  // Processes the response returned by a RDE Device and loads its
  // contents into asyncResp
  static void processRdeResponse(
      std::string_view prefix, boost::beast::http::verb method,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      const std::string& respString) {
    nlohmann::json jsonVal = nlohmann::json::parse(respString, nullptr, false);
    if (jsonVal.is_discarded()) {
      BMCWEB_LOG_ERROR << "Error parsing RDE Device response as JSON "
                       << respString;
      messages::operationFailed(asyncResp->res);
      return;
    }

    BMCWEB_LOG_DEBUG << "Successfully parsed RDE Device response";

    if (method == boost::beast::http::verb::post) {
      if (jsonVal["Status"] == "Completed") {
        asyncResp->res.result(200);
        return;
      }
      // If the POST action returns a resource, let it fall through to
      // populate the response body.
      if (jsonVal.contains("@odata.id")) {
        BMCWEB_LOG_DEBUG << "POST response contains resource, falling through "
                            "to process body";
      } else {
        messages::operationFailed(asyncResp->res);
        return;
      }
    }
    // TODO: For collections we  want to add the satellite responses to
    // our response rather than just straight overwriting them if our
    // local handling was successful (i.e. would return a 200).
    addPrefixes(jsonVal, prefix);

    if constexpr (bmcwebEnableRdeDevice) {
      if (jsonVal.contains(
              "/Location/PartLocation/ServiceLabel"_json_pointer)) {
        BMCWEB_LOG_DEBUG << " @odata.type " << jsonVal["@odata.type"];
        if (jsonVal["Model"] == platform6Chassis1 ||
            jsonVal["Model"] == platform6Chassis2) {
          std::string serviceLabel = getServiceLabel(prefix);
          BMCWEB_LOG_DEBUG << "Setting up service label " << serviceLabel
                           << " for prefix " << prefix;
          jsonVal["Location"]["PartLocation"]["ServiceLabel"] = serviceLabel;
        }
      }
      auto it = jsonVal.find("Id");
      if (it != jsonVal.end() && it->is_string()) {
        std::string* id_ptr = it->get_ptr<std::string*>();
        if (id_ptr != nullptr) {
          id_ptr->insert(0, std::string(prefix) + "_");
        }
      }
    }

    asyncResp->res.result(200);
    asyncResp->res.jsonValue = std::move(jsonVal);
    asyncResp->res.endTimetrace(std::string(prefix));

    BMCWEB_LOG_DEBUG << "Finished writing asyncResp";
  }

  // Processes the collection response returned by a RDE Device and merges
  // its "@odata.id" values
  static void processRdeCollectionResponse(
      const std::string& prefix,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      const std::string& respString) {
    nlohmann::json jsonVal = nlohmann::json::parse(respString, nullptr, false);
    if (jsonVal.is_discarded()) {
      BMCWEB_LOG_ERROR << "Error parsing RDEd response as JSON " << respString;

      // Notify the user if doing so won't overwrite a valid response
      if ((asyncResp->res.resultInt() != 200) &&
          (asyncResp->res.resultInt() != 502)) {
        messages::operationFailed(asyncResp->res);
      }
      return;
    }

    BMCWEB_LOG_DEBUG << "Successfully parsed RDEd response";

    // Now we need to add the prefix to the URIs contained in the
    // response.
    addPrefixes(jsonVal, prefix);

    BMCWEB_LOG_DEBUG << "Added prefix to parsed RDE Device response";

    // If this resource collection does not exist on the aggregating bmc
    // and has not already been added from processing the response from
    // a different satellite then we need to completely overwrite
    // asyncResp
    if (asyncResp->res.resultInt() != 200) {
      // We only want to aggregate collections that contain a
      // "Members" array
      if ((!jsonVal.contains("Members")) && (!jsonVal["Members"].is_array())) {
        BMCWEB_LOG_DEBUG << "Skipping aggregating unsupported resource";
        return;
      }

      BMCWEB_LOG_DEBUG << "Collection does not exist, overwriting asyncResp";
      asyncResp->res.jsonValue = std::move(jsonVal);

      BMCWEB_LOG_DEBUG << "Finished overwriting asyncResp";
    } else {
      // We only want to aggregate collections that contain a
      // "Members" array
      if ((!asyncResp->res.jsonValue.contains("Members")) &&
          (!asyncResp->res.jsonValue["Members"].is_array())) {
        BMCWEB_LOG_DEBUG << "Skipping aggregating unsupported resource";
        return;
      }

      BMCWEB_LOG_DEBUG << "Adding aggregated resources from \"" << prefix
                       << "\" to collection";

      // TODO: This is a potential race condition with multiple
      // satellites and the aggregating bmc attempting to write to
      // update this array.  May need to cascade calls to the next
      // satellite at the end of this function.
      auto& members = asyncResp->res.jsonValue["Members"];
      auto& satMembers = jsonVal["Members"];
      for (auto& satMem : satMembers) {
        members.push_back(std::move(satMem));
      }
      asyncResp->res.jsonValue["Members@odata.count"] = members.size();

      // TODO: Do we need to sort() after updating the array?
    }
    asyncResp->res.endTimetrace(prefix);
  }  // End processRdeCollectionResponse()

 public:
  RedfishAggregator(const RedfishAggregator&) = delete;
  RedfishAggregator& operator=(const RedfishAggregator&) = delete;
  RedfishAggregator(RedfishAggregator&&) = delete;
  RedfishAggregator& operator=(RedfishAggregator&&) = delete;
  ~RedfishAggregator() = default;

  static RedfishAggregator& getInstance() {
    static RedfishAggregator handler;
    return handler;
  }

  // Polls D-Bus to get all available satellite config information
  // Expects a handler which interacts with the returned configs
  static void getSatelliteConfigs(
      std::function<
          void(const boost::system::error_code&,
               const std::unordered_map<std::string, boost::urls::url>&,
               const std::unordered_map<std::string, RdeSatelliteConfig>&)>
          handler) {
    BMCWEB_LOG_DEBUG << "Gathering satellite configs";

    managedStore::ManagedObjectStoreContext context(nullptr);
    managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
        "xyz.openbmc_project.EntityManager", {"/xyz/openbmc_project/inventory"},
        context,
        [handler{std::move(handler)}](
            const boost::system::error_code& ec,
            const dbus::utility::ManagedObjectType& objects) {
          std::unordered_map<std::string, boost::urls::url> satelliteInfo;
          std::unordered_map<std::string, RdeSatelliteConfig> rdeSatelliteInfo;
          if (ec) {
            BMCWEB_LOG_ERROR << "DBUS response error " << ec.value() << ", "
                             << ec.message();
            handler(ec, satelliteInfo, rdeSatelliteInfo);
            return;
          }

          // Maps a chosen alias representing a satellite BMC to a url
          // containing the information required to create a http
          // connection to the satellite
          findSatelliteConfigs(objects, satelliteInfo, rdeSatelliteInfo);

          if (!satelliteInfo.empty()) {
            BMCWEB_LOG_DEBUG << "Redfish Aggregation enabled with "
                             << std::to_string(satelliteInfo.size())
                             << " satellite BMCs";
          } else if (!rdeSatelliteInfo.empty()) {
            BMCWEB_LOG_DEBUG << "Redfish Aggregation enabled with "
                             << std::to_string(rdeSatelliteInfo.size())
                             << " RDE Device";
          } else {
            BMCWEB_LOG_DEBUG << "No satellite BMCs detected.  Redfish "
                                "Aggregation not enabled";
          }
          handler(ec, satelliteInfo, rdeSatelliteInfo);
        });
  }

  // Processes the response returned by a satellite BMC and loads its
  // contents into asyncResp
  static void processResponse(
      std::string_view prefix,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      crow::Response& resp) {
    // 429 and 502 mean we didn't actually send the request so don't
    // overwrite the response headers in that case
    if ((resp.result() == boost::beast::http::status::too_many_requests) ||
        (resp.result() == boost::beast::http::status::bad_gateway)) {
      asyncResp->res.result(resp.result());
      return;
    }

    // We want to attempt prefix fixing regardless of response code
    // The resp will not have a json component
    // We need to create a json from resp's stringResponse
    std::string_view contentType = resp.getHeaderValue("Content-Type");
    if (boost::iequals(contentType, "application/json") ||
        boost::iequals(contentType, "application/json; charset=utf-8")) {
      nlohmann::json jsonVal =
          nlohmann::json::parse(resp.body(), nullptr, false);
      if (jsonVal.is_discarded()) {
        BMCWEB_LOG_ERROR << "Error parsing satellite response as JSON";
        messages::operationFailed(asyncResp->res);
        return;
      }

      BMCWEB_LOG_DEBUG << "Successfully parsed satellite response";

      addPrefixes(jsonVal, prefix);

      if constexpr (enablePlatform9) {
        // Hardcode relation to aggregating BMC
        if ((jsonVal.contains("@odata.id")) &&
            (jsonVal["@odata.id"].is_string())) {
          std::string targetURI(jsonVal["@odata.id"]);
          std::string aggRootURI(prefix);
          aggRootURI = "/redfish/v1/Chassis/" + aggRootURI + "_" +
                       std::string(platform9Chassis5);
          if (targetURI == aggRootURI) {
            jsonVal["Links"]["ContainedBy"] = {
                {"@odata.id",
                 "/redfish/v1/Chassis/" + std::string(platform9Chassis4)}};
          }
        }
        // End hardcoded workaround
      }

      BMCWEB_LOG_DEBUG << "Added prefix to parsed satellite response";

      asyncResp->res.result(resp.result());
      asyncResp->res.jsonValue = std::move(jsonVal);

      BMCWEB_LOG_DEBUG << "Finished writing asyncResp";
    } else {
      // We allow any Content-Type that is not "application/json" now
      asyncResp->res.result(resp.result());
      asyncResp->res.write(resp.body());
    }
    addAggregatedHeaders(asyncResp->res, resp, prefix);
  }

  // Processes the collection response returned by a satellite BMC and merges
  // its "@odata.id" values
  static void processCollectionResponse(
      const std::string& prefix,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      crow::Response& resp) {
    // 429 and 502 mean we didn't actually send the request so don't
    // overwrite the response headers in that case
    if ((resp.result() == boost::beast::http::status::too_many_requests) ||
        (resp.result() == boost::beast::http::status::bad_gateway)) {
      return;
    }

    if (resp.resultInt() != 200) {
      BMCWEB_LOG_DEBUG
          << "Collection resource does not exist in satellite BMC \"" << prefix
          << "\"";
      // Return the error if we haven't had any successes
      if (asyncResp->res.resultInt() != 200) {
        asyncResp->res.result(resp.result());
        asyncResp->res.write(resp.body());
      }
      return;
    }

    // The resp will not have a json component
    // We need to create a json from resp's stringResponse
    std::string_view contentType = resp.getHeaderValue("Content-Type");
    if (boost::iequals(contentType, "application/json") ||
        boost::iequals(contentType, "application/json; charset=utf-8")) {
      nlohmann::json jsonVal =
          nlohmann::json::parse(resp.body(), nullptr, false);
      if (jsonVal.is_discarded()) {
        BMCWEB_LOG_ERROR << "Error parsing satellite response as JSON";

        // Notify the user if doing so won't overwrite a valid response
        if (asyncResp->res.resultInt() != 200) {
          messages::operationFailed(asyncResp->res);
        }
        return;
      }

      BMCWEB_LOG_DEBUG << "Successfully parsed satellite response";

      // Now we need to add the prefix to the URIs contained in the
      // response.
      addPrefixes(jsonVal, prefix);

      BMCWEB_LOG_DEBUG << "Added prefix to parsed satellite response";

      // If this resource collection does not exist on the aggregating bmc
      // and has not already been added from processing the response from
      // a different satellite then we need to completely overwrite
      // asyncResp
      if (asyncResp->res.resultInt() != 200) {
        BMCWEB_LOG_DEBUG << "Collection does not exist, overwriting asyncResp";
        asyncResp->res.result(resp.result());
        asyncResp->res.jsonValue = std::move(jsonVal);
        auto& members = asyncResp->res.jsonValue["Members"];
        if (members.is_array()) {
          asyncResp->res.jsonValue["Members@odata.count"] = members.size();
        }
        asyncResp->res.addHeader("Content-Type", "application/json");

        BMCWEB_LOG_DEBUG << "Finished overwriting asyncResp";
      } else {
        BMCWEB_LOG_DEBUG << "Adding aggregated resources from \"" << prefix
                         << "\" to collection";

        // TODO: This is a potential race condition with multiple
        // satellites and the aggregating bmc attempting to write to
        // update this array.  May need to cascade calls to the next
        // satellite at the end of this function.
        // This is presumably not a concern when there is only a single
        // satellite since the aggregating bmc should have completed
        // before the response is received from the satellite.

        auto& members = asyncResp->res.jsonValue["Members"];
        if (!members.is_array()) {
          // Satellite response is being processed before top level
          // collection request has been locally handled so we need
          // to create Members array
          BMCWEB_LOG_DEBUG << "Created new Members array";
          members = nlohmann::json::array();
        }
        auto& satMembers = jsonVal["Members"];
        for (auto& satMem : satMembers) {
          members.push_back(std::move(satMem));
        }
        asyncResp->res.jsonValue["Members@odata.count"] = members.size();

        // TODO: Do we need to sort() after updating the array?
      }
    } else {
      BMCWEB_LOG_ERROR << "Received unparsable response from \"" << prefix
                       << "\"";
      // We received a response that was not a json.
      // Notify the user only if we did not receive any valid responses
      // and if the resource collection does not already exist on the
      // aggregating BMC
      if (asyncResp->res.resultInt() != 200) {
        messages::operationFailed(asyncResp->res);
      }
    }
  }  // End processCollectionResponse()

  // Processes the response returned by a satellite BMC and merges any
  // properties whose "@odata.id" value is the URI or either a top level
  // collection or is uptree from a top level collection
  static void processContainsSubordinateResponse(
      const std::string& prefix,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      crow::Response& resp) {
    // 429 and 502 mean we didn't actually send the request so don't
    // overwrite the response headers in that case
    if ((resp.result() == boost::beast::http::status::too_many_requests) ||
        (resp.result() == boost::beast::http::status::bad_gateway)) {
      return;
    }

    if (resp.resultInt() != 200) {
      BMCWEB_LOG_DEBUG << "Resource uptree from Collection does not exist in "
                       << "satellite BMC \"" << prefix << "\"";
      // Return the error if we haven't had any successes
      if (asyncResp->res.resultInt() != 200) {
        asyncResp->res.result(resp.result());
        asyncResp->res.write(resp.body());
      }
      return;
    }

    // The resp will not have a json component
    // We need to create a json from resp's stringResponse
    std::string_view contentType = resp.getHeaderValue("Content-Type");
    if (boost::iequals(contentType, "application/json") ||
        boost::iequals(contentType, "application/json; charset=utf-8")) {
      bool addedLinks = false;
      nlohmann::json jsonVal =
          nlohmann::json::parse(resp.body(), nullptr, false);
      if (jsonVal.is_discarded()) {
        BMCWEB_LOG_ERROR << "Error parsing satellite response as JSON";

        // Notify the user if doing so won't overwrite a valid response
        if (asyncResp->res.resultInt() != 200) {
          messages::operationFailed(asyncResp->res);
        }
        return;
      }

      BMCWEB_LOG_DEBUG << "Successfully parsed satellite response";

      // Parse response and add properties missing from the AsyncResp
      // Valid properties will be of the form <property>.@odata.id and
      // @odata.id is a <URI>.  In other words, the json should contain
      // multiple properties such that
      // {"<property>":{"@odata.id": "<URI>"}}
      nlohmann::json::object_t* object =
          jsonVal.get_ptr<nlohmann::json::object_t*>();
      if (object == nullptr) {
        BMCWEB_LOG_ERROR << "Parsed JSON was not an object?";
        return;
      }

      for (std::pair<const std::string, nlohmann::json>& prop : *object) {
        if (!prop.second.contains("@odata.id")) {
          continue;
        }

        std::string* strValue =
            prop.second["@odata.id"].get_ptr<std::string*>();
        if (strValue == nullptr) {
          BMCWEB_LOG_CRITICAL << "Field wasn't a string????";
          continue;
        }
        if (!searchCollectionsArray(*strValue, SearchType::CollOrCon)) {
          continue;
        }

        addedLinks = true;
        if (!asyncResp->res.jsonValue.contains(prop.first)) {
          // Only add the property if it did not already exist
          BMCWEB_LOG_DEBUG << "Adding link for " << *strValue << " from BMC "
                           << prefix;
          asyncResp->res.jsonValue[prop.first]["@odata.id"] = *strValue;
          continue;
        }
      }

      // If we added links to a previously unsuccessful (non-200) response
      // then we need to make sure the response contains the bare minimum
      // amount of additional information that we'd expect to have been
      // populated.
      if (addedLinks && (asyncResp->res.resultInt() != 200)) {
        // This resource didn't locally exist or an error
        // occurred while generating the response.  Remove any
        // error messages and update the error code.
        asyncResp->res.jsonValue.erase(asyncResp->res.jsonValue.find("error"));
        asyncResp->res.result(resp.result());

        const auto& it1 = object->find("@odata.id");
        if (it1 != object->end()) {
          asyncResp->res.jsonValue["@odata.id"] = (it1->second);
        }
        const auto& it2 = object->find("@odata.type");
        if (it2 != object->end()) {
          asyncResp->res.jsonValue["@odata.type"] = (it2->second);
        }
        const auto& it3 = object->find("Id");
        if (it3 != object->end()) {
          asyncResp->res.jsonValue["Id"] = (it3->second);
        }
        const auto& it4 = object->find("Name");
        if (it4 != object->end()) {
          asyncResp->res.jsonValue["Name"] = (it4->second);
        }
      }
    } else {
      BMCWEB_LOG_ERROR << "Received unparsable response from \"" << prefix
                       << "\"";
      // We received as response that was not a json
      // Notify the user only if we did not receive any valid responses,
      // and if the resource does not already exist on the aggregating BMC
      if (asyncResp->res.resultInt() != 200) {
        messages::operationFailed(asyncResp->res);
      }
    }
  }

  // Entry point to Redfish Aggregation
  // Returns Result stating whether or not we still need to locally handle the
  // request
  static Result beginAggregation(
      const crow::Request& thisReq,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
    using crow::utility::OrMorePaths;
    using crow::utility::readUrlSegments;
    const boost::urls::url_view url = thisReq.url();

    // We don't need to aggregate JsonSchemas due to potential issues such
    // as version mismatches between aggregator and satellite BMCs.  For
    // now assume that the aggregator has all the schemas and versions that
    // the aggregated server has.
    if (crow::utility::readUrlSegments(url, "redfish", "v1", "JsonSchemas",
                                       crow::utility::OrMorePaths())) {
      return Result::LocalHandle;
    }

    // The first two segments should be "/redfish/v1".  We need to check
    // that before we can search topCollections
    if (!crow::utility::readUrlSegments(url, "redfish", "v1",
                                        crow::utility::OrMorePaths())) {
      return Result::LocalHandle;
    }

    // Parse the URI to see if it begins with a known top level collection
    // such as:
    // /redfish/v1/Chassis
    // /redfish/v1/UpdateService/FirmwareInventory
    const boost::urls::segments_view urlSegments = url.segments();
    boost::urls::url currentUrl("/");
    boost::urls::segments_view::iterator it = urlSegments.begin();
    const boost::urls::segments_view::const_iterator end = urlSegments.end();

    // Skip past the leading "/redfish/v1"
    it++;
    it++;
    for (; it != end; it++) {
      const std::string& collectionItem = *it;
      if (std::binary_search(topCollections.begin(), topCollections.end(),
                             currentUrl.buffer())) {
        // We've matched a resource collection so this current segment
        // might contain an aggregation prefix
        // TODO: This needs to be rethought when we can support multiple
        // satellites due to
        // /redfish/v1/AggregationService/AggregationSources/5B247A
        // being a local resource describing the satellite
        if (collectionItem.starts_with("5B247A_") ||
            isMemberStartsWithKnownPrefix(collectionItem)) {
          BMCWEB_LOG_DEBUG << "Need to forward a request";

          // Extract the prefix from the request's URI, retrieve the
          // associated satellite config information, and then forward
          // the request to that satellite.
          startAggregation(AggregationType::Resource, thisReq, asyncResp);
          return Result::NoLocalHandle;
        }

        // Handle collection URI with a trailing backslash
        // e.g. /redfish/v1/Chassis/
        it++;
        if ((it == end) && collectionItem.empty()) {
          startAggregation(AggregationType::Collection, thisReq, asyncResp);
        }

        // We didn't recognize the prefix or it's a collection with a
        // trailing "/".  In both cases we still want to locally handle
        // the request
        return Result::LocalHandle;
      }

      currentUrl.segments().push_back(collectionItem);
    }

    // If we made it here then currentUrl could contain a top level
    // collection URI without a trailing "/", e.g. /redfish/v1/Chassis
    if (std::binary_search(topCollections.begin(), topCollections.end(),
                           currentUrl.buffer())) {
      startAggregation(AggregationType::Collection, thisReq, asyncResp);
      return Result::LocalHandle;
    }

    // If nothing else then the request could be for a resource which has a
    // top level collection as a subordinate
    if (searchCollectionsArray(url.buffer(), SearchType::ContainsSubordinate)) {
      startAggregation(AggregationType::ContainsSubordinate, thisReq,
                       asyncResp);
      return Result::LocalHandle;
    }

    BMCWEB_LOG_DEBUG << "Aggregation not required";
    return Result::LocalHandle;
  }
};

}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_REDFISH_AGGREGATOR_H_
