#pragma once

#include "bmcweb_config.h"

#include "aggregation_utils.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "http_client.hpp"
#include "http_connection.hpp"
#include "managed_store.hpp"
#include "request_stats.hpp"

#include <boost/algorithm/string/predicate.hpp>

#include <array>
#include <cstdint>
#include <random>

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

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

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

inline std::unordered_map<std::string, std::string>
    rdePrefixMap({{"/xyz/openbmc_project/rde_devices/1_1_1_1", "BCX5VT"}, // NOLINT
                  {"/xyz/openbmc_project/rde_devices/1_1_2_1", "A61MJ0"},
                  {"/xyz/openbmc_project/rde_devices/1_1_3_1", "K298LC"},
                  {"/xyz/openbmc_project/rde_devices/1_1_4_1", "2HMMCS"}});

inline std::unordered_map<std::string, std::string>
    rdeServiceLabelMap({{"BCX5VT", "DOWNLINK"}, // NOLINT
                        {"A61MJ0", "DOWNLINK"},
                        {"K298LC", "DOWNLINK"},
                        {"2HMMCS", "PCIE0"}});

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

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

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

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;
        }
        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;
            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);
            }
            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)
                {
                    BMCWEB_LOG_DEBUG << "Setting up service label "
                                     << rdeServiceLabelMap[std::string{prefix}]
                                     << " for prefix " << prefix;
                    jsonVal["Location"]["PartLocation"]["ServiceLabel"] =
                        rdeServiceLabelMap[std::string{prefix}];
                }
            }
            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);
                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
