#include "query.hpp"

#include "absl/synchronization/mutex.h"
#include "bmcweb_config.h"

#include "app.hpp"
#include "async_resp.hpp"
#include "error_messages.hpp"
#include "logging.hpp"
#include "managed_store.hpp"
#include "redfish_aggregator.hpp"
#include "str_utility.hpp"

#include <boost/beast/http/verb.hpp>
#include <boost/system/error_code.hpp>
#include <boost/url/params_view.hpp>
#include <boost/url/url_view.hpp>

#include <cstdint>
#include <functional>
#include <memory>
#include <new>
#include <optional>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>

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

namespace redfish
{

namespace query_param
{

// Validates the property in the $select parameter. Every character is among
// [a-zA-Z0-9#@_.] (taken from Redfish spec, section 9.6 Properties)
bool isSelectedPropertyAllowed(std::string_view property)
{
    // These a magic number, but with it it's less likely that this code
    // introduces CVE; e.g., too large properties crash the service.
    constexpr int maxPropertyLength = 60;
    if (property.empty() || property.size() > maxPropertyLength)
    {
        return false;
    }
    for (char ch : property)
    {
        if (std::isalnum(static_cast<unsigned char>(ch)) == 0 && ch != '#' &&
            ch != '@' && ch != '.')
        {
            return false;
        }
    }
    return true;
}

bool SelectTrie::insertNode(std::string_view nestedProperty)
{
    if (nestedProperty.empty())
    {
        return false;
    }
    SelectTrieNode* currNode = &root;
    size_t index = nestedProperty.find_first_of('/');
    while (!nestedProperty.empty())
    {
        std::string_view property = nestedProperty.substr(0, index);
        if (!isSelectedPropertyAllowed(property))
        {
            return false;
        }
        currNode = currNode->emplace(property);
        if (index == std::string::npos)
        {
            break;
        }
        nestedProperty.remove_prefix(index + 1);
        index = nestedProperty.find_first_of('/');
    }
    currNode->setToSelected();
    return true;
}

// Delegates query parameters according to the given |queryCapabilities|
// This function doesn't check query parameter conflicts since the parse
// function will take care of it.
// Returns a delegated query object which can be used by individual resource
// handlers so that handlers don't need to query again.
Query delegate(const QueryCapabilities& queryCapabilities, Query& query,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    Query delegated;
    // delegate only
    if (query.isOnly && queryCapabilities.canDelegateOnly)
    {
        delegated.isOnly = true;
        query.isOnly = false;
    }
    // delegate expand as much as we can
    if (query.expandType != ExpandType::None)
    {
        delegated.expandType = query.expandType;
        if (query.expandLevel <= queryCapabilities.canDelegateExpandLevel)
        {
            query.expandType = ExpandType::None;
            delegated.expandLevel = query.expandLevel;
            query.expandLevel = 0;
        }
        else
        {
            // We actually dont need to subtract query.expandType here because
            // When we expand navigation references, we actually start from
            // the root of the entire response instead of the delegated level
            delegated.expandLevel = queryCapabilities.canDelegateExpandLevel;
        }
        asyncResp->delegatedExpandLevel = delegated.expandLevel;
    }

    // delegate top
    if (query.top && queryCapabilities.canDelegateTop)
    {
        delegated.top = query.top;
        query.top = std::nullopt;
    }

    // delegate skip
    if (query.skip && queryCapabilities.canDelegateSkip)
    {
        delegated.skip = query.skip;
        query.skip = 0;
    }

    // delegate select
    if (!query.selectTrie.root.empty() && queryCapabilities.canDelegateSelect)
    {
        delegated.selectTrie = std::move(query.selectTrie);
        query.selectTrie.root.clear();
    }

    // delegate filter
    if (!query.filter.empty() && queryCapabilities.canDelegateFilter)
    {
        delegated.filter = query.filter;
        query.filter = "";
    }
    return delegated;
}

bool getExpandType(std::string_view value, Query& query)
{
    if (value.empty())
    {
        return false;
    }
    switch (value[0])
    {
        case '*':
            query.expandType = ExpandType::Both;
            break;
        case '.':
            query.expandType = ExpandType::NotLinks;
            break;
        case '~':
            query.expandType = ExpandType::Links;
            break;
        default:
            return false;

            break;
    }
    value.remove_prefix(1);
    if (value.empty())
    {
        query.expandLevel = 1;
        return true;
    }
    constexpr std::string_view levels = "($levels=";
    if (!value.starts_with(levels))
    {
        return false;
    }
    value.remove_prefix(levels.size());

    auto it = std::from_chars(value.data(), value.data() + value.size(),
                              query.expandLevel);
    if (it.ec != std::errc())
    {
        return false;
    }
    value.remove_prefix(static_cast<size_t>(it.ptr - value.data()));
    return value == ")";
}

enum class QueryError : std::uint8_t
{
    Ok,
    OutOfRange,
    ValueFormat,
};

QueryError getNumericParam(std::string_view value, size_t& param)
{
    std::from_chars_result r =
        std::from_chars(value.data(), value.data() + value.size(), param);

    // If the number wasn't representable in the type, it's out of range
    if (r.ec == std::errc::result_out_of_range)
    {
        return QueryError::OutOfRange;
    }
    // All other errors are value format
    if (r.ec != std::errc())
    {
        return QueryError::ValueFormat;
    }
    return QueryError::Ok;
}

QueryError getSkipParam(std::string_view value, Query& query)
{
    return getNumericParam(value, query.skip.emplace());
}

QueryError getTopParam(std::string_view value, Query& query)
{
    QueryError ret = getNumericParam(value, query.top.emplace());
    if (ret != QueryError::Ok)
    {
        return ret;
    }

    // Range check for sanity.
    if (query.top > Query::maxTop)
    {
        return QueryError::OutOfRange;
    }

    return QueryError::Ok;
}

// Parses and validates the $select parameter.
// As per OData URL Conventions and Redfish Spec, the $select values shall be
// comma separated Resource Path
// Ref:
// 1. https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
// 2.
// https://docs.oasis-open.org/odata/odata/v4.01/os/abnf/odata-abnf-construction-rules.txt
bool getSelectParam(std::string_view value, Query& query)
{
    std::vector<std::string> properties;
    bmcweb::split(properties, value, ',');
    if (properties.empty())
    {
        return false;
    }
    // These a magic number, but with it it's less likely that this code
    // introduces CVE; e.g., too large properties crash the service.
    constexpr int maxNumProperties = 10;
    if (properties.size() > maxNumProperties)
    {
        return false;
    }
    for (const auto& property : properties)
    {
        if (!query.selectTrie.insertNode(property))
        {
            return false;
        }
    }
    return true;
}

bool getFilterParam(std::string_view value, Query& query)
{
    if (value.empty())
    {
        return false;
    }

    query.filter = std::string(value);
    return true;
}

std::optional<Query> parseParameters(boost::urls::params_view urlParams,
                                     crow::Response& res)
{
    Query ret;
    for (const boost::urls::params_view::value_type& it : urlParams)
    {
        if (it.key == "only")
        {
            if (!it.value.empty())
            {
                messages::queryParameterValueFormatError(res, it.value, it.key);
                return std::nullopt;
            }
            ret.isOnly = true;
        }
        else if (it.key == "$expand" && bmcwebInsecureEnableQueryParams)
        {
            if (!getExpandType(it.value, ret))
            {
                messages::queryParameterValueFormatError(res, it.value, it.key);
                return std::nullopt;
            }
        }
        else if (it.key == "$top")
        {
            QueryError topRet = getTopParam(it.value, ret);
            if (topRet == QueryError::ValueFormat)
            {
                messages::queryParameterValueFormatError(res, it.value, it.key);
                return std::nullopt;
            }
            if (topRet == QueryError::OutOfRange)
            {
                messages::queryParameterOutOfRange(
                    res, it.value, "$top",
                    "0-" + std::to_string(Query::maxTop));
                return std::nullopt;
            }
        }
        else if (it.key == "$skip")
        {
            QueryError topRet = getSkipParam(it.value, ret);
            if (topRet == QueryError::ValueFormat)
            {
                messages::queryParameterValueFormatError(res, it.value, it.key);
                return std::nullopt;
            }
            if (topRet == QueryError::OutOfRange)
            {
                messages::queryParameterOutOfRange(
                    res, it.value, it.key,
                    "0-" + std::to_string(std::numeric_limits<size_t>::max()));
                return std::nullopt;
            }
        }
        else if (it.key == "$select")
        {
            if (!getSelectParam(it.value, ret))
            {
                messages::queryParameterValueFormatError(res, it.value, it.key);
                return std::nullopt;
            }
        }
        else if (it.key == "$filter")
        {
            if (!getFilterParam(it.value, ret))
            {
                messages::queryParameterValueFormatError(res, it.value, it.key);
                return std::nullopt;
            }
        }
        else
        {
            // Intentionally ignore other errors Redfish spec, 7.3.1
            if (it.key.starts_with("$"))
            {
                // Services shall return... The HTTP 501 Not Implemented
                // status code for any unsupported query parameters that
                // start with $ .
                messages::queryParameterValueFormatError(res, it.value, it.key);
                res.result(boost::beast::http::status::not_implemented);
                return std::nullopt;
            }
            // "Shall ignore unknown or unsupported query parameters that do
            // not begin with $ ."
        }
    }

    if (ret.expandType != ExpandType::None && !ret.selectTrie.root.empty())
    {
        messages::queryCombinationInvalid(res);
        return std::nullopt;
    }

    return ret;
}

bool processOnly(crow::App& app, crow::Response& res,
                 std::function<void(crow::Response&)>& completionHandler,
                 const std::shared_ptr<boost::asio::io_context::strand>& strand)
{
    BMCWEB_LOG_DEBUG << "Processing only query param";
    auto itMembers = res.jsonValue.find("Members");
    if (itMembers == res.jsonValue.end())
    {
        messages::queryNotSupportedOnResource(res);
        completionHandler(res);
        return false;
    }
    auto itMemBegin = itMembers->begin();
    if (itMemBegin == itMembers->end() || itMembers->size() != 1)
    {
        BMCWEB_LOG_DEBUG << "Members contains " << itMembers->size()
                         << " element, returning full collection.";
        completionHandler(res);
        return false;
    }

    auto itUrl = itMemBegin->find("@odata.id");
    if (itUrl == itMemBegin->end())
    {
        BMCWEB_LOG_DEBUG << "No found odata.id";
        messages::internalError(res);
        completionHandler(res);
        return false;
    }
    const std::string* url = itUrl->get_ptr<const std::string*>();
    if (url == nullptr)
    {
        BMCWEB_LOG_DEBUG << "@odata.id wasn't a string????";
        messages::internalError(res);
        completionHandler(res);
        return false;
    }
    // TODO(Ed) copy request headers?
    // newReq.session = req.session;
    std::error_code ec;
    crow::Request newReq({boost::beast::http::verb::get, *url, 11}, ec);
    if (ec)
    {
        messages::internalError(res);
        completionHandler(res);
        return false;
    }

    auto asyncResp = std::make_shared<bmcweb::AsyncResp>(strand);
    BMCWEB_LOG_DEBUG << "setting completion handler on " << &asyncResp->res;
    asyncResp->res.setCompleteRequestHandler(std::move(completionHandler));
    asyncResp->res.setIsAliveHelper(res.releaseIsAliveHelper());
    app.handle(newReq, asyncResp);
    return true;
}

// Walks a json object looking for Redfish NavigationReference entries that
// might need resolved.  It recursively walks the jsonResponse object, looking
// for links at every level, and returns a list (out) of locations within the
// tree that need to be expanded.  The current json pointer location p is passed
// in to reference the current node that's being expanded, so it can be combined
// with the keys from the jsonResponse object
void findNavigationReferencesRecursive(ExpandType eType,
                                       nlohmann::json& jsonResponse,
                                       const nlohmann::json::json_pointer& p,
                                       int depth, bool inLinks,
                                       std::vector<ExpandNode>& out)
{
    // If no expand is needed, return early
    if (eType == ExpandType::None)
    {
        return;
    }

    nlohmann::json::array_t* array =
        jsonResponse.get_ptr<nlohmann::json::array_t*>();
    if (array != nullptr)
    {
        size_t index = 0;
        // For arrays, walk every element in the array
        for (auto& element : *array)
        {
            nlohmann::json::json_pointer newPtr = p / index;
            BMCWEB_LOG_DEBUG << "Traversing response at " << newPtr.to_string();
            findNavigationReferencesRecursive(eType, element, newPtr, depth,
                                              inLinks, out);
            index++;
        }
    }
    nlohmann::json::object_t* obj =
        jsonResponse.get_ptr<nlohmann::json::object_t*>();
    if (obj == nullptr)
    {
        return;
    }
    // Navigation References only ever have a single element
    if (obj->size() == 1)
    {
        if (obj->begin()->first == "@odata.id")
        {
            const std::string* uri =
                obj->begin()->second.get_ptr<const std::string*>();
            if (uri != nullptr)
            {
                BMCWEB_LOG_DEBUG << "Found " << *uri << " at " << p.to_string();
                out.push_back({p, *uri});
                return;
            }
        }
    }

    int newDepth = depth;
    auto odataId = obj->find("@odata.id");
    if (odataId != obj->end())
    {
        // The Redfish spec requires all resources to include the resource
        // identifier.  If the object has multiple elements and one of them is
        // "@odata.id" then that means we have entered a new level / expanded
        // resource.  We need to stop traversing if we're already at the desired
        // depth
        if ((obj->size() > 1) && (depth == 0))
        {
            return;
        }
        newDepth--;
    }

    // Loop the object and look for links
    for (auto& element : *obj)
    {
        bool localInLinks = inLinks;
        if (!localInLinks)
        {
            // Check if this is a links node
            localInLinks = element.first == "Links";
        }
        // Only traverse the parts of the tree the user asked for
        // Per section 7.3 of the redfish specification
        if (localInLinks && eType == ExpandType::NotLinks)
        {
            continue;
        }
        if (!localInLinks && eType == ExpandType::Links)
        {
            continue;
        }
        nlohmann::json::json_pointer newPtr = p / element.first;
        BMCWEB_LOG_DEBUG << "Traversing response at " << newPtr;

        findNavigationReferencesRecursive(eType, element.second, newPtr,
                                          newDepth, localInLinks, out);
    }
}

// TODO: When aggregation is enabled and we receive a partially expanded
// response we may need need additional handling when the original URI was
// up tree from a top level collection.
// Isn't a concern until https://gerrit.openbmc.org/c/openbmc/bmcweb/+/60556
// lands.  May want to avoid forwarding query params when request is uptree from
// a top level collection.
std::vector<ExpandNode> findNavigationReferences(ExpandType eType, int depth,
                                                 nlohmann::json& jsonResponse)
{
    std::vector<ExpandNode> ret;
    const nlohmann::json::json_pointer root = nlohmann::json::json_pointer("");
    findNavigationReferencesRecursive(eType, jsonResponse, root, depth, false,
                                      ret);
    return ret;
}

// Formats a query parameter string for the sub-query.
// Returns std::nullopt on failures.
// This function shall handle $select when it is added.
// There is no need to handle parameters that's not campatible with $expand,
// e.g., $only, since this function will only be called in side $expand handlers
std::optional<std::string> formatQueryForExpand(const Query& query)
{
    // query.expandLevel<=1: no need to do subqueries
    if (query.expandLevel <= 1)
    {
        return "";
    }
    std::string str = "?$expand=";
    bool queryTypeExpected = false;
    switch (query.expandType)
    {
        case ExpandType::None:
            return "";
        case ExpandType::Links:
            queryTypeExpected = true;
            str += '~';
            break;
        case ExpandType::NotLinks:
            queryTypeExpected = true;
            str += '.';
            break;
        case ExpandType::Both:
            queryTypeExpected = true;
            str += '*';
            break;
    }
    if (!queryTypeExpected)
    {
        return std::nullopt;
    }
    str += "($levels=";
    str += std::to_string(query.expandLevel - 1);
    str += ')';
    return str;
}

// Propogates the worst error code to the final response.
// The order of error code is (from high to low)
// 500 Internal Server Error
// 511 Network Authentication Required
// 510 Not Extended
// 508 Loop Detected
// 507 Insufficient Storage
// 506 Variant Also Negotiates
// 505 HTTP Version Not Supported
// 504 Gateway Timeout
// 503 Service Unavailable
// 502 Bad Gateway
// 501 Not Implemented
// 401 Unauthorized
// 451 - 409 Error codes (not listed explictly)
// 408 Request Timeout
// 407 Proxy Authentication Required
// 406 Not Acceptable
// 405 Method Not Allowed
// 404 Not Found
// 403 Forbidden
// 402 Payment Required
// 400 Bad Request
unsigned propogateErrorCode(unsigned finalCode, unsigned subResponseCode)
{
    // We keep a explicit list for error codes that this project often uses
    // Higer priority codes are in lower indexes
    constexpr std::array<unsigned, 13> orderedCodes = {
        500, 507, 503, 502, 501, 401, 412, 409, 406, 405, 404, 403, 400};
    size_t finalCodeIndex = std::numeric_limits<size_t>::max();
    size_t subResponseCodeIndex = std::numeric_limits<size_t>::max();
    for (size_t i = 0; i < orderedCodes.size(); ++i)
    {
        if (orderedCodes[i] == finalCode)
        {
            finalCodeIndex = i;
        }
        if (orderedCodes[i] == subResponseCode)
        {
            subResponseCodeIndex = i;
        }
    }
    if (finalCodeIndex != std::numeric_limits<size_t>::max() &&
        subResponseCodeIndex != std::numeric_limits<size_t>::max())
    {
        return finalCodeIndex <= subResponseCodeIndex ? finalCode
                                                      : subResponseCode;
    }
    if (subResponseCode == 500 || finalCode == 500)
    {
        return 500;
    }
    if (subResponseCode > 500 || finalCode > 500)
    {
        return std::max(finalCode, subResponseCode);
    }
    if (subResponseCode == 401)
    {
        return subResponseCode;
    }
    return std::max(finalCode, subResponseCode);
}

// Propogates all error messages into |finalResponse|
void propogateError(crow::Response& finalResponse, crow::Response& subResponse)
{
    // no errors
    if (subResponse.resultInt() >= 200 && subResponse.resultInt() < 400)
    {
        return;
    }
    messages::moveErrorsToErrorJson(finalResponse.jsonValue,
                                    subResponse.jsonValue);
    finalResponse.result(
        propogateErrorCode(finalResponse.resultInt(), subResponse.resultInt()));
}

class MultiAsyncResp : public std::enable_shared_from_this<MultiAsyncResp>
{
  public:
    // This object takes a single asyncResp object as the "final" one, then
    // allows callers to attach sub-responses within the json tree that need
    // to be executed and filled into their appropriate locations.  This
    // class manages the final "merge" of the json resources.
    MultiAsyncResp(crow::App& appIn,
                   std::shared_ptr<bmcweb::AsyncResp> finalResIn,
                   const crow::Request& request) :
        app(appIn), finalRes(std::move(finalResIn)), fromGrpc(request.fromGrpc),
        with_trust_bundle(request.with_trust_bundle),
        peer_authenticated(request.peer_authenticated),
        peer_privileges(request.peer_privileges)
    {}

    void addAwaitingResponse(
        const std::shared_ptr<bmcweb::AsyncResp>& res,
        const nlohmann::json::json_pointer& finalExpandLocation)
    {
        res->res.setCompleteRequestHandler(std::bind_front(
            placeResultStatic, shared_from_this(), finalExpandLocation));
    }

    void placeResult(const nlohmann::json::json_pointer& locationToPlace,
                     crow::Response& res)
    {
        propogateError(finalRes->res, res);
        if (!res.jsonValue.is_object() || res.jsonValue.empty())
        {
            return;
        }
        nlohmann::json& finalObj = finalRes->res.jsonValue[locationToPlace];
        finalObj = std::move(res.jsonValue);
        BMCWEB_LOG_DEBUG << "placeResult for " << locationToPlace;
    }

    // Handles the very first level of Expand, and starts a chain of sub-queries
    // for deeper levels.
    void startQuery(const Query& query)
    {
        std::vector<ExpandNode> nodes = findNavigationReferences(
            query.expandType, query.expandLevel, finalRes->res.jsonValue);
        BMCWEB_LOG_DEBUG << nodes.size() << " nodes to traverse";
        const std::optional<std::string> queryStr = formatQueryForExpand(query);
        if (!queryStr)
        {
            messages::internalError(finalRes->res);
            return;
        }
        for (const ExpandNode& node : nodes)
        {
            const std::string subQuery = node.uri + *queryStr;
            BMCWEB_LOG_DEBUG << "URL of subquery:  " << subQuery;
            std::error_code ec;
            crow::Request newReq({boost::beast::http::verb::get, subQuery, 11},
                                 ec);
            if (ec)
            {
                messages::internalError(finalRes->res);
                return;
            }

            newReq.fromGrpc = fromGrpc;
            newReq.with_trust_bundle = with_trust_bundle;
            newReq.peer_authenticated = peer_authenticated;
            newReq.peer_privileges = peer_privileges;

            auto asyncResp = std::make_shared<bmcweb::AsyncResp>(finalRes->strand_);
            BMCWEB_LOG_DEBUG << "setting completion handler on "
                             << &asyncResp->res;

            addAwaitingResponse(asyncResp, node.location);

            BMCWEB_LOG_DEBUG << "Single-threaded expand";
            app.handle(newReq, asyncResp);
        }
    }

  private:
    static void
        placeResultStatic(const std::shared_ptr<MultiAsyncResp>& multi,
                          const nlohmann::json::json_pointer& locationToPlace,
                          crow::Response& res)
    {
        multi->placeResult(locationToPlace, res);
    }

    crow::App& app;
    std::shared_ptr<bmcweb::AsyncResp> finalRes;

    bool fromGrpc;
    bool with_trust_bundle;
    bool peer_authenticated;
    std::unordered_set<std::string> peer_privileges;
    absl::Mutex mutex_;
};

void processTopAndSkip(const Query& query, crow::Response& res)
{
    if (!query.skip && !query.top)
    {
        // No work to do.
        return;
    }
    nlohmann::json::object_t* obj =
        res.jsonValue.get_ptr<nlohmann::json::object_t*>();
    if (obj == nullptr)
    {
        // Shouldn't be possible.  All responses should be objects.
        messages::internalError(res);
        return;
    }

    BMCWEB_LOG_DEBUG << "Handling top/skip";
    nlohmann::json::object_t::iterator members = obj->find("Members");
    if (members == obj->end())
    {
        // From the Redfish specification 7.3.1
        // ... the HTTP 400 Bad Request status code with the
        // QueryNotSupportedOnResource message from the Base Message Registry
        // for any supported query parameters that apply only to resource
        // collections but are used on singular resources.
        messages::queryNotSupportedOnResource(res);
        return;
    }

    nlohmann::json::array_t* arr =
        members->second.get_ptr<nlohmann::json::array_t*>();
    if (arr == nullptr)
    {
        messages::internalError(res);
        return;
    }

    if (query.skip)
    {
        // Per section 7.3.1 of the Redfish specification, $skip is run before
        // $top Can only skip as many values as we have
        size_t skip = std::min(arr->size(), *query.skip);
        arr->erase(arr->begin(), arr->begin() + static_cast<ssize_t>(skip));
    }
    if (query.top)
    {
        size_t top = std::min(arr->size(), *query.top);
        arr->erase(arr->begin() + static_cast<ssize_t>(top), arr->end());
    }
}

// Given a JSON subtree |currRoot|, this function erases leaves whose keys are
// not in the |currNode| Trie node.
void recursiveSelect(nlohmann::json& currRoot, const SelectTrieNode& currNode)
{
    nlohmann::json::object_t* object =
        currRoot.get_ptr<nlohmann::json::object_t*>();
    if (object != nullptr)
    {
        BMCWEB_LOG_DEBUG << "Current JSON is an object";
        auto it = currRoot.begin();
        while (it != currRoot.end())
        {
            auto nextIt = std::next(it);
            BMCWEB_LOG_DEBUG << "key=" << it.key();
            const SelectTrieNode* nextNode = currNode.find(it.key());
            // Per the Redfish spec section 7.3.3, the service shall select
            // certain properties as if $select was omitted. This applies to
            // every TrieNode that contains leaves and the root.
            constexpr std::array<std::string_view, 5> reservedProperties = {
                "@odata.id", "@odata.type", "@odata.context", "@odata.etag",
                "error"};
            bool reserved =
                std::find(reservedProperties.begin(), reservedProperties.end(),
                          it.key()) != reservedProperties.end();
            if (reserved || (nextNode != nullptr && nextNode->isSelected()))
            {
                it = nextIt;
                continue;
            }
            if (nextNode != nullptr)
            {
                BMCWEB_LOG_DEBUG << "Recursively select: " << it.key();
                recursiveSelect(*it, *nextNode);
                it = nextIt;
                continue;
            }
            BMCWEB_LOG_DEBUG << it.key() << " is getting removed!";
            it = currRoot.erase(it);
        }
    }
    nlohmann::json::array_t* array =
        currRoot.get_ptr<nlohmann::json::array_t*>();
    if (array != nullptr)
    {
        BMCWEB_LOG_DEBUG << "Current JSON is an array";
        // Array index is omitted, so reuse the same Trie node
        for (nlohmann::json& nextRoot : *array)
        {
            recursiveSelect(nextRoot, currNode);
        }
    }
}

// The current implementation of $select still has the following TODOs due to
//  ambiguity and/or complexity.
// 1. combined with $expand; https://github.com/DMTF/Redfish/issues/5058 was
// created for clarification.
// 2. respect the full odata spec; e.g., deduplication, namespace, star (*),
// etc.
void processSelect(crow::Response& intermediateResponse,
                   const SelectTrieNode& trieRoot)
{
    BMCWEB_LOG_DEBUG << "Process $select quary parameter";
    recursiveSelect(intermediateResponse.jsonValue, trieRoot);
}

void processAllParams(crow::App& app, const Query& query,
                      const crow::Request& request,
                      std::function<void(crow::Response&)>& completionHandler,
                      crow::Response& intermediateResponse,
                      const std::shared_ptr<boost::asio::io_context::strand>& strand)
{
    if (!completionHandler)
    {
        BMCWEB_LOG_DEBUG << "Function was invalid?";
        return;
    }

    BMCWEB_LOG_DEBUG << "Processing query params";
    // If the request failed, there's no reason to even try to run query
    // params.
    if (intermediateResponse.resultInt() < 200 ||
        intermediateResponse.resultInt() >= 400)
    {
        completionHandler(intermediateResponse);
        return;
    }
    if (query.isOnly)
    {
        processOnly(app, intermediateResponse, completionHandler, strand);
        return;
    }

    if (query.top || query.skip)
    {
        processTopAndSkip(query, intermediateResponse);
    }

    if (query.expandType != ExpandType::None)
    {
        BMCWEB_LOG_DEBUG << "Executing expand query";
        auto asyncResp = std::make_shared<bmcweb::AsyncResp>(
            std::move(intermediateResponse), strand);

        asyncResp->res.setCompleteRequestHandler(std::move(completionHandler));
        auto multi = std::make_shared<MultiAsyncResp>(app, asyncResp, request);

        multi->startQuery(query);
        return;
    }

    // According to Redfish Spec Section 7.3.1, $select is the last parameter to
    // to process
    if (!query.selectTrie.root.empty())
    {
        processSelect(intermediateResponse, query.selectTrie.root);
    }

    completionHandler(intermediateResponse);
}

} // namespace query_param

namespace
{

void afterIfMatchRequest(crow::App& app,
                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         crow::Request& req, const std::string& ifMatchHeader,
                         const crow::Response& resIn)
{
    std::string computedEtag = resIn.computeEtag();
    BMCWEB_LOG_DEBUG << "User provided if-match etag " << ifMatchHeader
                     << " computed etag " << computedEtag;
    if (computedEtag != ifMatchHeader)
    {
        messages::preconditionFailed(asyncResp->res);
        return;
    }
    // Restart the request without if-match
    req.req.erase(boost::beast::http::field::if_match);
    BMCWEB_LOG_DEBUG << "Restarting request";
    app.handle(req, asyncResp);
}

bool handleIfMatch(crow::App& app, const crow::Request& req,
                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (req.session == nullptr)
    {
        // If the user isn't authenticated, don't even attempt to parse match
        // parameters
        return true;
    }

    std::string ifMatch{
        req.getHeaderValue(boost::beast::http::field::if_match)};
    if (ifMatch.empty())
    {
        // No If-Match header.  Nothing to do
        return true;
    }
    if (req.req.method() != boost::beast::http::verb::patch &&
        req.req.method() != boost::beast::http::verb::post &&
        req.req.method() != boost::beast::http::verb::delete_)
    {
        messages::preconditionFailed(asyncResp->res);
        return false;
    }
    boost::system::error_code ec;

    // Try to GET the same resource
    crow::Request newReq(
        {boost::beast::http::verb::get, req.url().encoded_path(), 11}, ec);

    if (ec)
    {
        messages::internalError(asyncResp->res);
        return false;
    }

    // New request has the same credentials as the old request
    newReq.session = req.session;

    // Construct a new response object to fill in, and check the hash of before
    // we modify the Resource.
    std::shared_ptr<bmcweb::AsyncResp> getReqAsyncResp =
        std::make_shared<bmcweb::AsyncResp>(asyncResp->strand_);

    getReqAsyncResp->res.setCompleteRequestHandler(std::bind_front(
        afterIfMatchRequest, std::ref(app), asyncResp, req, ifMatch));

    app.handle(newReq, getReqAsyncResp);
    return false;
}

} // namespace

bool setUpRedfishRouteWithDelegation(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    query_param::Query& delegated,
    const query_param::QueryCapabilities& queryCapabilities)
{
    BMCWEB_LOG_DEBUG << "setup redfish route";

    if (asyncResp->response_type ==
            bmcweb::AsyncResp::ResponseType::kSubscription &&
        !queryCapabilities.canHandleSubscription)
    {
        BMCWEB_LOG_ALWAYS << "Cannot delegate subscription for route: "
                          << req.url();
        return false;
    }

    // Section 7.4 of the redfish spec "Redfish Services shall process the
    // [OData-Version header] in the following table as defined by the HTTP 1.1
    // specification..."
    // Required to pass redfish-protocol-validator REQ_HEADERS_ODATA_VERSION
    std::string_view odataHeader = req.getHeaderValue("OData-Version");
    if (!odataHeader.empty() && odataHeader != "4.0")
    {
        messages::preconditionFailed(asyncResp->res);
        return false;
    }

    asyncResp->res.addHeader("OData-Version", "4.0");

    std::optional<query_param::Query> queryOpt =
        query_param::parseParameters(req.url().params(), asyncResp->res);
    if (queryOpt == std::nullopt)
    {
        return false;
    }

    if (!handleIfMatch(app, req, asyncResp))
    {
        return false;
    }

    bool needToCallHandlers = true;

#ifdef BMCWEB_ENABLE_REDFISH_AGGREGATION
    needToCallHandlers = RedfishAggregator::getInstance().beginAggregation(
                             req, asyncResp) == Result::LocalHandle;

    // If the request should be forwarded to a satellite BMC then we don't want
    // to write anything to the asyncResp since it will get overwritten later.
#endif

    // If this isn't a get, no need to do anything with parameters
    if (req.method() != boost::beast::http::verb::get)
    {
        return needToCallHandlers;
    }

    delegated = query_param::delegate(queryCapabilities, *queryOpt, asyncResp);
    std::function<void(crow::Response&)> handler =
        asyncResp->res.releaseCompleteRequestHandler();
    auto strand = asyncResp->strand_;

    asyncResp->res.setCompleteRequestHandler(
        [&app, handler(std::move(handler)), query{std::move(*queryOpt)},
         request(req), strand](crow::Response& resIn) mutable {
        query_param::processAllParams(app, query, request, handler, resIn, strand);
    });

    return needToCallHandlers;
}

} // namespace redfish
