#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_QUERY_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_QUERY_H_

#include <cstddef>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "boost/beast/http/verb.hpp"  // NOLINT
#include "boost/url/params_view.hpp"  // NOLINT
#include "boost/url/url_view.hpp"  // NOLINT
#include "app.hpp"
#include "app_singleton.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "async_resp.hpp"
#include <nlohmann/json.hpp>

// IWYU pragma: no_forward_declare crow::App
// IWYU pragma: no_include <boost/url/impl/params_view.hpp>
// IWYU pragma: no_include <boost/url/impl/url_view.hpp>

namespace redfish {

namespace query_param {
enum class ExpandType : uint8_t {
  None,
  Links,
  NotLinks,
  Both,
};

// A simple implementation of Trie to help |recursiveSelect|.
class SelectTrieNode {
 public:
  SelectTrieNode() = default;

  const SelectTrieNode* find(const std::string& jsonKey) const {
    auto it = children.find(jsonKey);
    if (it == children.end()) {
      return nullptr;
    }
    return &it->second;
  }

  // Creates a new node if the key doesn't exist, returns the reference to the
  // newly created node; otherwise, return the reference to the existing node
  SelectTrieNode* emplace(std::string_view jsonKey) {
    auto [it, _] = children.emplace(jsonKey, SelectTrieNode{});
    return &it->second;
  }

  bool empty() const { return children.empty(); }

  void clear() { children.clear(); }

  void setToSelected() { selected = true; }

  bool isSelected() const { return selected; }

 private:
  std::map<std::string, SelectTrieNode, std::less<>> children;
  bool selected = false;
};

struct SelectTrie {
  SelectTrie() = default;

  // Inserts a $select value; returns false if the nestedProperty is illegal.
  bool insertNode(std::string_view nestedProperty);

  SelectTrieNode root;
};

// The struct stores the parsed query parameters of the default Redfish route.
struct Query {
  // Only
  bool isOnly = false;
  // Expand
  uint8_t expandLevel = 0;
  ExpandType expandType = ExpandType::None;

  // Skip
  std::optional<size_t> skip = std::nullopt;

  // Top
  static constexpr size_t maxTop = 1000;  // Max entries a response contain
  std::optional<size_t> top = std::nullopt;

  // Select
  SelectTrie selectTrie = {};  // NOLINT

  // Filter
  // We only support delegate filter for now.
  // Unless explicitly enable canDelegateFilter capability, common queries
  // won't parse $filter in the query.
  std::string filter = "";  // NOLINT
};

// The struct defines how resource handlers in redfish-core/lib/ can handle
// query parameters themselves, so that the default Redfish route will delegate
// the processing.
struct QueryCapabilities {
  bool canDelegateOnly = false;
  bool canDelegateTop = false;
  bool canDelegateSkip = false;
  uint8_t canDelegateExpandLevel = 0;
  bool canDelegateSelect = false;
  bool canDelegateFilter = false;
  bool canHandleSubscription = false;
};

struct ExpandNode {
  nlohmann::json::json_pointer location;
  std::string uri;

  inline bool operator==(const ExpandNode& other) const {
    return location == other.location && uri == other.uri;
  }
};

Query delegate(const QueryCapabilities& queryCapabilities, Query& query,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp);
std::optional<std::string> formatQueryForExpand(const Query& query);
bool isSelectedPropertyAllowed(std::string_view property);
bool getSelectParam(std::string_view value, Query& query);
void recursiveSelect(nlohmann::json& currRoot, const SelectTrieNode& currNode);
unsigned propogateErrorCode(unsigned finalCode, unsigned subResponseCode);
void propogateError(crow::Response& finalResponse, crow::Response& subResponse);
std::optional<Query> parseParameters(boost::urls::params_view urlParams,
                                     crow::Response& res);
bool getExpandType(std::string_view value, Query& query);
std::vector<ExpandNode> findNavigationReferences(ExpandType eType, int depth,
                                                 nlohmann::json& jsonResponse);
}  // namespace query_param

// Sets up the Redfish Route and delegates some of the query parameter
// processing. |queryCapabilities| stores which query parameters will be
// handled by redfish-core/lib codes, then default query parameter handler won't
// process these parameters.
[[nodiscard]] 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);

// Sets up the Redfish Route. All parameters are handled by the default handler.
[[nodiscard]] inline bool setUpRedfishRoute(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  // This route |delegated| is never used
  query_param::Query delegated;
  return setUpRedfishRouteWithDelegation(app, req, asyncResp, delegated,
                                         query_param::QueryCapabilities{});
}

// See |setUpRedfishRouteWithDelegation| above for documentation.
[[nodiscard]] inline bool setUpRedfishRouteWithDelegationOnGlobalApp(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    query_param::Query& delegated,
    const query_param::QueryCapabilities& queryCapabilities) {
  return setUpRedfishRouteWithDelegation(*crow::globalBmcWebApp, req, asyncResp,
                                         delegated, queryCapabilities);
}

// See |setUpRedfishRoute| above for documentation.
[[nodiscard]] inline bool setUpRedfishRouteOnGlobalApp(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  return setUpRedfishRoute(*crow::globalBmcWebApp, req, asyncResp);
}

}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_QUERY_H_
