#include "query.hpp"

#include <algorithm>
#include <array>
#include <cctype>
#include <charconv>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iterator>
#include <limits>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <unordered_set>
#include <utility>
#include <vector>

#include "absl/strings/str_cat.h"
#include "absl/synchronization/mutex.h"
#include "boost/beast/http/verb.hpp"  // NOLINT
#include "boost/system/error_code.hpp"  // NOLINT
#include "boost/url/params_view.hpp"  // NOLINT
#include "boost/url/url_view.hpp"  // NOLINT
#include "bmcweb_config.h"
#include "app.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "logging.hpp"
#include "async_resp.hpp"
#include "str_utility.hpp"
#include "error_messages.hpp"
#include "redfish_aggregator.hpp"  // NOLINT
#include <nlohmann/json.hpp>

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

QueryError getExpandType(std::string_view value, Query& query) {
  if (value.empty()) {
    return QueryError::ValueFormat;
  }
  switch (value[0]) {
    case '*':
      query.expandType = ExpandType::Both;
      break;
    case '.':
      query.expandType = ExpandType::NotLinks;
      break;
    case '~':
      query.expandType = ExpandType::Links;
      break;
    default:
      return QueryError::ValueFormat;
  }
  value.remove_prefix(1);
  if (value.empty()) {
    query.expandLevel = 1;
    return QueryError::Ok;
  }
  constexpr std::string_view levels = "($levels=";
  if (!value.starts_with(levels)) {
    return QueryError::ValueFormat;
  }
  value.remove_prefix(levels.size());

  if (value.back() != ')') {
    return QueryError::ValueFormat;
  }

  std::string_view numberStr = value.substr(0, value.size() - 1);

  int8_t expandLevel = 0;
  auto it = std::from_chars(numberStr.data(),
                            numberStr.data() + numberStr.size(), expandLevel);

  if (it.ec == std::errc::result_out_of_range) {
    return QueryError::OutOfRange;
  }

  if (it.ec != std::errc() || it.ptr != numberStr.data() + numberStr.size()) {
    return QueryError::ValueFormat;
  }

  if (expandLevel < Query::kMinExpandLevel ||
      expandLevel > Query::kMaxExpandLevel) {
    return QueryError::OutOfRange;
  }

  query.expandLevel = static_cast<uint8_t>(expandLevel);
  return QueryError::Ok;
}

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) {
      QueryError expandRet = getExpandType(it.value, ret);
      if (expandRet == QueryError::ValueFormat) {
        messages::queryParameterValueFormatError(res, it.value, it.key);
        return std::nullopt;
      }
      if (expandRet == QueryError::OutOfRange) {
        messages::queryParameterOutOfRange(
            res, it.value, "$expand",
            absl::StrCat(Query::kMinExpandLevel, "-", Query::kMaxExpandLevel));
        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;
  if (req.url().has_query() && !req.url().query().empty()) {
    queryOpt = query_param::parseParameters(req.url().params(), asyncResp->res);
  } else {
    queryOpt.emplace();
  }

  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
