#pragma once

#include "app.hpp"
#include "app_singleton.hpp"
#include "async_resp.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "logging.hpp"

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

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

// 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
