#ifndef THIRD_PARTY_GBMCWEB_HTTP_ROUTING_H_
#define THIRD_PARTY_GBMCWEB_HTTP_ROUTING_H_

#ifdef BMCWEB_ENABLE_GRPC
#include "absl/log/log.h"
#include "authorizer_enums.h"
#include "bmcweb_authorizer_singleton.h"
#include "uri_to_entity.h"
#endif

#include <algorithm>
#include <array>
#include <cstdint>
#include <cstdlib>
#include <functional>
#include <initializer_list>
#include <limits>
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

#include "boost/beast/ssl/ssl_stream.hpp"  // NOLINT
#include "boost/container/flat_map.hpp"  // NOLINT
#include "common.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "verb.hpp"
#include "websocket.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "privileges.hpp"
// TODO(haoooamazing): Remove dbus_utils.h include once indirect include is
// fixed for redfish-core/lib/ethernet.hpp
#include "dbus_utils.hpp"  // NOLINT(misc-include-cleaner)
#include "managed_store.hpp"

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

namespace crow {

class BaseRule {
 public:
  explicit BaseRule(std::string_view thisRule) : rule(thisRule) {}

  virtual ~BaseRule() = default;

  BaseRule(const BaseRule&) = delete;
  BaseRule(BaseRule&&) = delete;
  BaseRule& operator=(const BaseRule&) = delete;
  BaseRule& operator=(const BaseRule&&) = delete;

  virtual void validate() = 0;
  std::unique_ptr<BaseRule> upgrade() {
    if (ruleToUpgrade) {
      return std::move(ruleToUpgrade);
    }
    return {};
  }

  virtual void handle(const Request& /*req*/,
                      const std::shared_ptr<bmcweb::AsyncResp>&,
                      const RoutingParams&) = 0;
#ifndef BMCWEB_ENABLE_SSL
  virtual void handleUpgrade(
      const Request& /*req*/,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      boost::asio::ip::tcp::socket&& /*adaptor*/) {
    asyncResp->res.result(boost::beast::http::status::not_found);
  }
#else
  virtual void handleUpgrade(
      const Request& /*req*/,
      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      boost::beast::ssl_stream<boost::asio::ip::tcp::socket>&& /*adaptor*/) {
    asyncResp->res.result(boost::beast::http::status::not_found);
  }
#endif

  size_t getMethods() const { return methodsBitfield; }

  bool checkPrivileges(const redfish::Privileges& userPrivileges) {
    // If there are no privileges assigned, assume no privileges
    // required
    if (privilegesSet.empty()) {
      return true;
    }

    // NOLINTNEXTLINE(readability-use_anyofallof)
    for (const redfish::Privileges& requiredPrivileges : privilegesSet) {
      if (userPrivileges.isSupersetOf(requiredPrivileges)) {
        return true;
      }
    }
    return false;
  }

  size_t methodsBitfield{1 << static_cast<size_t>(HttpVerb::Get)};  // NOLINT
  static_assert(std::numeric_limits<decltype(methodsBitfield)>::digits >
                    methodNotAllowedIndex,
                "Not enough bits to store bitfield");

  std::vector<redfish::Privileges> privilegesSet;  // NOLINT

  std::string rule;     // NOLINT
  std::string nameStr;  // NOLINT

  std::unique_ptr<BaseRule> ruleToUpgrade;  // NOLINT

  friend class Router;
  template <typename T>
  friend struct RuleParameterTraits;
};

namespace detail {
namespace routing_handler_call_helper {
template <typename T, int Pos>
struct CallPair {
  using type = T;
  static const int pos = Pos;
};

template <typename H1>
struct CallParams {
  H1& handler;
  const RoutingParams& params;
  const Request& req;
  const std::shared_ptr<bmcweb::AsyncResp>& asyncResp;  // NOLINT
};

template <typename F, int NInt, int NUint, int NDouble, int NString,
          typename S1, typename S2>
struct Call {};

template <typename F, int NInt, int NUint, int NDouble, int NString,
          typename... Args1, typename... Args2>
struct Call<F, NInt, NUint, NDouble, NString, black_magic::S<int64_t, Args1...>,
            black_magic::S<Args2...>> {
  void operator()(F cparams) {
    using pushed = typename black_magic::S<Args2...>::template push_back<
        CallPair<int64_t, NInt>>;
    Call<F, NInt + 1, NUint, NDouble, NString, black_magic::S<Args1...>,
         pushed>()(cparams);
  }
};

template <typename F, int NInt, int NUint, int NDouble, int NString,
          typename... Args1, typename... Args2>
struct Call<F, NInt, NUint, NDouble, NString,
            black_magic::S<uint64_t, Args1...>, black_magic::S<Args2...>> {
  void operator()(F cparams) {
    using pushed = typename black_magic::S<Args2...>::template push_back<
        CallPair<uint64_t, NUint>>;
    Call<F, NInt, NUint + 1, NDouble, NString, black_magic::S<Args1...>,
         pushed>()(cparams);
  }
};

template <typename F, int NInt, int NUint, int NDouble, int NString,
          typename... Args1, typename... Args2>
struct Call<F, NInt, NUint, NDouble, NString, black_magic::S<double, Args1...>,
            black_magic::S<Args2...>> {
  void operator()(F cparams) {
    using pushed = typename black_magic::S<Args2...>::template push_back<
        CallPair<double, NDouble>>;
    Call<F, NInt, NUint, NDouble + 1, NString, black_magic::S<Args1...>,
         pushed>()(cparams);
  }
};

template <typename F, int NInt, int NUint, int NDouble, int NString,
          typename... Args1, typename... Args2>
struct Call<F, NInt, NUint, NDouble, NString,
            black_magic::S<std::string, Args1...>, black_magic::S<Args2...>> {
  void operator()(F cparams) {
    using pushed = typename black_magic::S<Args2...>::template push_back<
        CallPair<std::string, NString>>;
    Call<F, NInt, NUint, NDouble, NString + 1, black_magic::S<Args1...>,
         pushed>()(cparams);
  }
};

template <typename F, int NInt, int NUint, int NDouble, int NString,
          typename... Args1>
struct Call<F, NInt, NUint, NDouble, NString, black_magic::S<>,
            black_magic::S<Args1...>> {
  void operator()(F cparams) {
    cparams.handler(
        cparams.req, cparams.asyncResp,
        cparams.params.template get<typename Args1::type>(Args1::pos)...);
  }
};

template <typename Func, typename... ArgsWrapped>
struct Wrapped {
  template <typename... Args>
  void set(
      Func f,
      typename std::enable_if<
          !std::is_same<
              typename std::tuple_element<0, std::tuple<Args..., void>>::type,
              const Request&>::value,
          int>::type /*enable*/
      = 0) {
    handler = [f = std::forward<Func>(f)](
                  const Request&,
                  const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                  Args... args) { asyncResp->res.result(f(args...)); };
  }

  template <typename Req, typename... Args>
  struct ReqHandlerWrapper {
    explicit ReqHandlerWrapper(Func fIn) : f(std::move(fIn)) {}

    void operator()(const Request& req,
                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                    Args... args) {
      asyncResp->res.result(f(req, args...));
    }

    Func f;
  };

  template <typename... Args>
  void set(
      Func f,
      typename std::enable_if<
          std::is_same<
              typename std::tuple_element<0, std::tuple<Args..., void>>::type,
              const Request&>::value &&
              !std::is_same<typename std::tuple_element<
                                1, std::tuple<Args..., void, void>>::type,
                            const std::shared_ptr<bmcweb::AsyncResp>&>::value,
          int>::type /*enable*/
      = 0) {
    handler = ReqHandlerWrapper<Args...>(std::move(f));
    /*handler = (
        [f = std::move(f)]
        (const Request& req, Response& res, Args... args){
             res.result(f(req, args...));
             res.end();
        });*/
  }

  template <typename... Args>
  void set(
      Func f,
      typename std::enable_if<
          std::is_same<
              typename std::tuple_element<0, std::tuple<Args..., void>>::type,
              const Request&>::value &&
              std::is_same<typename std::tuple_element<
                               1, std::tuple<Args..., void, void>>::type,
                           const std::shared_ptr<bmcweb::AsyncResp>&>::value,
          int>::type /*enable*/
      = 0) {
    handler = std::move(f);
  }

  template <typename... Args>
  struct HandlerTypeHelper {
    using type =
        std::function<void(const crow::Request& /*req*/,
                           const std::shared_ptr<bmcweb::AsyncResp>&, Args...)>;
    using args_type = black_magic::S<typename black_magic::PromoteT<Args>...>;
  };

  template <typename... Args>
  struct HandlerTypeHelper<const Request&, Args...> {
    using type =
        std::function<void(const crow::Request& /*req*/,
                           const std::shared_ptr<bmcweb::AsyncResp>&, Args...)>;
    using args_type = black_magic::S<typename black_magic::PromoteT<Args>...>;
  };

  template <typename... Args>
  struct HandlerTypeHelper<const Request&,
                           const std::shared_ptr<bmcweb::AsyncResp>&, Args...> {
    using type =
        std::function<void(const crow::Request& /*req*/,
                           const std::shared_ptr<bmcweb::AsyncResp>&, Args...)>;
    using args_type = black_magic::S<typename black_magic::PromoteT<Args>...>;
  };

  typename HandlerTypeHelper<ArgsWrapped...>::type handler;

  void operator()(const Request& req,
                  const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                  const RoutingParams& params) {
    detail::routing_handler_call_helper::Call<
        detail::routing_handler_call_helper::CallParams<decltype(handler)>, 0,
        0, 0, 0, typename HandlerTypeHelper<ArgsWrapped...>::args_type,
        black_magic::S<>>()(
        detail::routing_handler_call_helper::CallParams<decltype(handler)>{
            handler, params, req, asyncResp});
  }
};
}  // namespace routing_handler_call_helper
}  // namespace detail

class WebSocketRule : public BaseRule {
  using self_t = WebSocketRule;

 public:
  explicit WebSocketRule(const std::string& ruleIn) : BaseRule(ruleIn) {}

  void validate() override {}

  void handle(const Request& /*req*/,
              const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
              const RoutingParams& /*params*/) override {
    asyncResp->res.result(boost::beast::http::status::not_found);
  }

#ifndef BMCWEB_ENABLE_SSL
  void handleUpgrade(const Request& req,
                     const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
                     boost::asio::ip::tcp::socket&& adaptor) override {
    BMCWEB_LOG_DEBUG << "Websocket handles upgrade";
    std::shared_ptr<
        crow::websocket::ConnectionImpl<boost::asio::ip::tcp::socket>>
        myConnection = std::make_shared<
            crow::websocket::ConnectionImpl<boost::asio::ip::tcp::socket>>(
            req, std::move(adaptor), openHandler, messageHandler,
            messageExHandler, closeHandler, errorHandler);
    myConnection->start();
  }
#else
  void handleUpgrade(const Request& req,
                     const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
                     boost::beast::ssl_stream<boost::asio::ip::tcp::socket>&&
                         adaptor) override {
    BMCWEB_LOG_DEBUG << "Websocket handles upgrade";
    std::shared_ptr<crow::websocket::ConnectionImpl<
        boost::beast::ssl_stream<boost::asio::ip::tcp::socket>>>
        myConnection = std::make_shared<crow::websocket::ConnectionImpl<
            boost::beast::ssl_stream<boost::asio::ip::tcp::socket>>>(
            req, std::move(adaptor), openHandler, messageHandler,
            messageExHandler, closeHandler, errorHandler);
    myConnection->start();
  }
#endif

  template <typename Func>
  self_t& onopen(Func f) {
    openHandler = f;
    return *this;
  }

  template <typename Func>
  self_t& onmessage(Func f) {
    messageHandler = f;
    return *this;
  }

  template <typename Func>
  self_t& onmessageex(Func f) {
    messageExHandler = f;
    return *this;
  }

  template <typename Func>
  self_t& onclose(Func f) {
    closeHandler = f;
    return *this;
  }

  template <typename Func>
  self_t& onerror(Func f) {
    errorHandler = f;
    return *this;
  }

 protected:
  std::function<void(crow::websocket::Connection&)> openHandler;  // NOLINT
  std::function<void(crow::websocket::Connection&, const std::string&, bool)>
      messageHandler;  // NOLINT
  std::function<void(crow::websocket::Connection&, std::string_view,
                     crow::websocket::MessageType type,
                     std::function<void()>&& whenComplete)>
      messageExHandler;  // NOLINT
  std::function<void(crow::websocket::Connection&, const std::string&)>
      closeHandler;                                                // NOLINT
  std::function<void(crow::websocket::Connection&)> errorHandler;  // NOLINT
};

template <typename T>
struct RuleParameterTraits {
  using self_t = T;
  WebSocketRule& websocket() {
    self_t* self = static_cast<self_t*>(this);
    WebSocketRule* p = new WebSocketRule(self->rule);
    self->ruleToUpgrade.reset(p);
    return *p;
  }

  self_t& name(std::string_view name) noexcept {
    self_t* self = static_cast<self_t*>(this);
    self->nameStr = name;
    return *self;
  }

  self_t& methods(boost::beast::http::verb method) {
    self_t* self = static_cast<self_t*>(this);
    std::optional<HttpVerb> verb = httpVerbFromBoost(method);
    if (verb) {
      self->methodsBitfield = 1U << static_cast<size_t>(*verb);
    }
    return *self;
  }

  template <typename... MethodArgs>
  self_t& methods(boost::beast::http::verb method, MethodArgs... argsMethod) {
    self_t* self = static_cast<self_t*>(this);
    methods(argsMethod...);
    std::optional<HttpVerb> verb = httpVerbFromBoost(method);
    if (verb) {
      self->methodsBitfield |= 1U << static_cast<size_t>(*verb);
    }
    return *self;
  }

  self_t& notFound() {
    self_t* self = static_cast<self_t*>(this);
    self->methodsBitfield = 1U << notFoundIndex;
    return *self;
  }

  self_t& methodNotAllowed() {
    self_t* self = static_cast<self_t*>(this);
    self->methodsBitfield = 1U << methodNotAllowedIndex;
    return *self;
  }

  self_t& privileges(
      const std::initializer_list<std::initializer_list<const char*>>& p) {
    self_t* self = static_cast<self_t*>(this);
    for (const std::initializer_list<const char*>& privilege : p) {
      self->privilegesSet.emplace_back(privilege);
    }
    return *self;
  }

  template <size_t N, typename... MethodArgs>
  self_t& privileges(const std::array<redfish::Privileges, N>& p) {
    self_t* self = static_cast<self_t*>(this);
    for (const redfish::Privileges& privilege : p) {
      self->privilegesSet.emplace_back(privilege);
    }
    return *self;
  }
};

class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule> {
 public:
  explicit DynamicRule(const std::string& ruleIn) : BaseRule(ruleIn) {}

  void validate() override {
    if (!erasedHandler) {
      throw std::runtime_error(nameStr + (!nameStr.empty() ? ": " : "") +
                               "no handler for url " + rule);
    }
  }

  void handle(const Request& req,
              const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
              const RoutingParams& params) override {
    erasedHandler(req, asyncResp, params);
  }

  template <typename Func>
  void operator()(Func f) {
    using boost::callable_traits::args_t;
    constexpr size_t arity = std::tuple_size<args_t<Func>>::value;
    constexpr auto is = std::make_integer_sequence<unsigned, arity>{};
    erasedHandler = wrap(std::move(f), is);
  }

  // enable_if Arg1 == request && Arg2 == Response
  // enable_if Arg1 == request && Arg2 != response
  // enable_if Arg1 != request

  template <typename Func, unsigned... Indices>
  std::function<void(const Request&, const std::shared_ptr<bmcweb::AsyncResp>&,
                     const RoutingParams&)>
  wrap(Func f, std::integer_sequence<unsigned, Indices...> /*is*/) {
    using function_t = crow::utility::FunctionTraits<Func>;

    if (!black_magic::isParameterTagCompatible(
            black_magic::getParameterTag(rule),
            black_magic::computeParameterTagFromArgsList<
                typename function_t::template arg<Indices>...>::value)) {
      throw std::runtime_error(
          "routeDynamic: Handler type is mismatched "
          "with URL parameters: " +
          rule);
    }
    auto ret = detail::routing_handler_call_helper::Wrapped<
        Func, typename function_t::template arg<Indices>...>();
    ret.template set<typename function_t::template arg<Indices>...>(
        std::move(f));
    return ret;
  }

  template <typename Func>
  void operator()(std::string name, Func&& f) {
    nameStr = std::move(name);
    (*this).template operator()<Func>(std::forward(f));
  }

 private:
  std::function<void(const Request&, const std::shared_ptr<bmcweb::AsyncResp>&,
                     const RoutingParams&)>
      erasedHandler;  // NOLINT
};

template <typename... Args>
class TaggedRule : public BaseRule,
                   public RuleParameterTraits<TaggedRule<Args...>> {
 public:
  using self_t = TaggedRule<Args...>;

  explicit TaggedRule(std::string_view ruleIn) : BaseRule(ruleIn) {}

  void validate() override {
    if (!handler) {
      throw std::runtime_error(nameStr + (!nameStr.empty() ? ": " : "") +
                               "no handler for url " + rule);
    }
  }

  template <typename Func>
  typename std::enable_if<
      black_magic::CallHelper<Func, black_magic::S<Args...>>::value, void>::type
  operator()(Func&& f) {
    static_assert(
        black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
            black_magic::CallHelper<
                Func, black_magic::S<crow::Request, Args...>>::value,
        "Handler type is mismatched with URL parameters");
    static_assert(
        !std::is_same<void, decltype(f(std::declval<Args>()...))>::value,
        "Handler function cannot have void return type; valid return "
        "types: "
        "string, int, crow::response, nlohmann::json");

    handler = [f = std::forward<Func>(f)](
                  const Request&,
                  const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                  Args... args) { asyncResp->res.result(f(args...)); };
  }

  template <typename Func>
  typename std::enable_if<
      !black_magic::CallHelper<Func, black_magic::S<Args...>>::value &&
          black_magic::CallHelper<
              Func, black_magic::S<crow::Request, Args...>>::value,
      void>::type
  operator()(Func&& f) {
    static_assert(
        black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
            black_magic::CallHelper<
                Func, black_magic::S<crow::Request, Args...>>::value,
        "Handler type is mismatched with URL parameters");
    static_assert(
        !std::is_same<void, decltype(f(std::declval<crow::Request>(),
                                       std::declval<Args>()...))>::value,
        "Handler function cannot have void return type; valid return "
        "types: "
        "string, int, crow::response,nlohmann::json");

    handler = [f = std::forward<Func>(f)](
                  const crow::Request& req,
                  const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                  Args... args) { asyncResp->res.result(f(req, args...)); };
  }

  template <typename Func>
  typename std::enable_if<
      !black_magic::CallHelper<Func, black_magic::S<Args...>>::value &&
          !black_magic::CallHelper<
              Func, black_magic::S<crow::Request, Args...>>::value,
      void>::type
  operator()(Func&& f) {
    static_assert(
        black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
            black_magic::CallHelper<
                Func, black_magic::S<crow::Request, Args...>>::value ||
            black_magic::CallHelper<
                Func, black_magic::S<crow::Request,
                                     std::shared_ptr<bmcweb::AsyncResp>&,
                                     Args...>>::value,
        "Handler type is mismatched with URL parameters");
    static_assert(
        std::is_same<void,
                     decltype(f(
                         std::declval<crow::Request>(),
                         std::declval<std::shared_ptr<bmcweb::AsyncResp>&>(),
                         std::declval<Args>()...))>::value,
        "Handler function with response argument should have void "
        "return "
        "type");

    handler = std::forward<Func>(f);
  }

  template <typename Func>
  void operator()(std::string_view name, Func&& f) {
    nameStr = name;
    (*this).template operator()<Func>(std::forward(f));
  }

  template <typename Func>
  void replaceHandler(Func&& f) {
    this->operator()(f);
  }

  template <typename Func>
  void appendHandler(Func&& f) {
    this->operator()([f = std::forward<Func>(f), previousFunc = this->handler](
                         const crow::Request & req,
                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         Args... args) {
      if (previousFunc) {
        previousFunc(req, asyncResp, args...);
      }
      std::function<void(crow::Response&)> previousCompleteFunc =
          asyncResp->res.releaseCompleteRequestHandler();
      auto strand = asyncResp->strand_;

      asyncResp->res.setCompleteRequestHandler(
          [req, previousCompleteFunc(std::move(previousCompleteFunc)), args...,
           f, strand, delegatedExpandLevel(asyncResp->delegatedExpandLevel)](
              crow::Response& resIn) mutable {
            std::shared_ptr<bmcweb::AsyncResp> newAsyncResp =
                std::make_shared<bmcweb::AsyncResp>(std::move(resIn), strand);

            // Pass delegatedExpandLevel so that hanlder in plugin can
            // handler efficient expand appending accordingly
            newAsyncResp->delegatedExpandLevel = delegatedExpandLevel;

            // previousCompleteFunc contains callback functions including
            // Redfish params and writing bytes to socket
            newAsyncResp->res.setCompleteRequestHandler(
                [previousCompleteFunc(std::move(previousCompleteFunc))](
                    crow::Response& resp) {
                  if (previousCompleteFunc) {
                    previousCompleteFunc(resp);
                  }
                });
            f(req, newAsyncResp, args...);
          });
    });
  }

  void handle(const Request& req,
              const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
              const RoutingParams& params) override {
    detail::routing_handler_call_helper::Call<
        detail::routing_handler_call_helper::CallParams<decltype(handler)>, 0,
        0, 0, 0, black_magic::S<Args...>, black_magic::S<>>()(
        detail::routing_handler_call_helper::CallParams<decltype(handler)>{
            handler, params, req, asyncResp});
  }

 private:
  std::function<void(const crow::Request&,
                     const std::shared_ptr<bmcweb::AsyncResp>&, Args...)>
      handler;  // NOLINT
};

class Trie {
 public:
  struct Node {
    unsigned ruleIndex{};  // NOLINT
    std::array<size_t, static_cast<size_t>(ParamType::MAX)>
        paramChildrens{};  // NOLINT
    using ChildMap = boost::container::flat_map<
        std::string, unsigned, std::less<>,
        std::vector<std::pair<std::string, unsigned>>>;
    ChildMap children;

    bool isSimpleNode() const {
      return ruleIndex == 0 &&
             std::all_of(std::begin(paramChildrens), std::end(paramChildrens),
                         [](size_t x) { return x == 0U; });
    }
  };

  Trie() : nodes(1) {}

 private:
  void optimizeNode(Node* node);

  void optimize() { optimizeNode(head()); }

 public:
  void validate() { optimize(); }

  void findRouteIndexes(const std::string& reqUrl,
                        std::vector<unsigned>& routeIndexes,
                        const Node* node = nullptr, unsigned pos = 0) const;

  std::pair<unsigned, RoutingParams> find(
      std::string_view reqUrl, const Node* node = nullptr, size_t pos = 0,
      RoutingParams* params = nullptr) const;

  void add(const std::string& url, unsigned ruleIndex);

 private:
  void debugNodePrint(Node* n, size_t level);

 public:
  void debugPrint() { debugNodePrint(head(), 0U); }

 private:
  const Node* head() const { return &nodes.front(); }

  Node* head() { return &nodes.front(); }

  unsigned newNode() {
    nodes.resize(nodes.size() + 1);
    return static_cast<unsigned>(nodes.size() - 1);
  }

  std::vector<Node> nodes;  // NOLINT
};

class Router {
 public:
  explicit Router(bool allowSessionEmpty)
      : allowSessionEmpty(allowSessionEmpty) {}

  DynamicRule& newRuleDynamic(const std::string& rule) {
    std::unique_ptr<DynamicRule> ruleObject =
        std::make_unique<DynamicRule>(rule);
    DynamicRule* ptr = ruleObject.get();
    allRules.emplace_back(std::move(ruleObject));

    return *ptr;
  }

  template <uint64_t N>
  typename black_magic::Arguments<N>::type::template rebind<TaggedRule>&
  newRuleTagged(std::string_view rule) {
    using RuleT =
        typename black_magic::Arguments<N>::type::template rebind<TaggedRule>;
    std::unique_ptr<RuleT> ruleObject = std::make_unique<RuleT>(rule);
    RuleT* ptr = ruleObject.get();
    allRules.emplace_back(std::move(ruleObject));

    return *ptr;
  }

  template <uint64_t Tag>
  void removeRuleTagged(std::string_view url,
                        boost::beast::http::verb boostVerb) {
    auto iter = findRuleByUrlAndVerb<Tag>(url, boostVerb);
    if (iter == allRules.end()) {
      throwHandlerNotFound(url, boostVerb);
    }
    allRules.erase(iter);
  }

  void internalAddRuleObject(const std::string& rule, BaseRule* ruleObject);

  void validate();

  struct FindRoute {
    BaseRule* rule = nullptr;
    RoutingParams params;
  };

  struct FindRouteResponse {
    std::string allowHeader;  // NOLINT
    FindRoute route;
  };

  FindRoute findRouteByIndex(std::string_view url, size_t index) const;

  FindRouteResponse findRoute(Request& req) const;

  template <typename CallbackFn>
  void afterGetUserInfo(Request& req,
                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                        BaseRule& rule, CallbackFn&& callback,
                        const boost::system::error_code& ec,
                        const dbus::utility::DBusPropertiesMap& userInfoMap) {
    if (ec) {
      BMCWEB_LOG_ERROR << "GetUserInfo failed...";
      asyncResp->res.result(boost::beast::http::status::internal_server_error);
      return;
    }

    if (!isUserPrivileged(req, asyncResp, rule, userInfoMap)) {
      // User is not privileged
      BMCWEB_LOG_ERROR << "Insufficient Privilege";
      asyncResp->res.result(boost::beast::http::status::forbidden);
      return;
    }
    callback(req);
  }

  template <typename CallbackFn>
  void validatePrivilege(Request& req,
                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         BaseRule& rule, CallbackFn&& callback) {
    if (req.session == nullptr) {
      BMCWEB_LOG_DEBUG << "validatePrivilege: no session to validatePrivilege:";

      if (allowSessionEmpty) {
        callback(req);
      }

      return;
    }

    if (managedStore::GetManagedObjectStore()
                ->GetDeprecatedThreadUnsafeSystemBus() != nullptr &&
        req.session) {
      BMCWEB_LOG_DEBUG << "validatePrivilege: GetUserInfo";
      const std::string username = req.session->username;
      // TODO: WHY ARE WE DOING THIS FOR EVERY REQUEST ?!?! OMG. this is
      // absurd!
      managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
          asyncResp->strand_,
          [this, &req, asyncResp, &rule,
           callback(std::forward<CallbackFn>(callback))](
              const boost::system::error_code& ec,
              const dbus::utility::DBusPropertiesMap& userInfoMap) mutable {
            afterGetUserInfo(req, asyncResp, rule,
                             std::forward<CallbackFn>(callback), ec,
                             userInfoMap);
          },
          "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
          "xyz.openbmc_project.User.Manager", "GetUserInfo", username);
    } else {
      // systemBus = null is most likely unit testing
      callback(req);
    }
  }

  template <typename Adaptor>
  void handleUpgrade(Request& req,
                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                     Adaptor&& adaptor) {
    std::optional<HttpVerb> verb = httpVerbFromBoost(req.method());
    if (!verb || static_cast<size_t>(*verb) >= perMethods.size()) {
      asyncResp->res.result(boost::beast::http::status::not_found);
      return;
    }
    PerMethod& perMethod = perMethods[static_cast<size_t>(*verb)];
    Trie& trie = perMethod.trie;
    std::vector<BaseRule*>& rules = perMethod.rules;

    const std::pair<unsigned, RoutingParams>& found =  // NOLINT
        trie.find(req.url().encoded_path());
    unsigned ruleIndex = found.first;
    if (ruleIndex == 0U) {
      BMCWEB_LOG_DEBUG << "Cannot match rules " << req.url().encoded_path();
      asyncResp->res.result(boost::beast::http::status::not_found);
      return;
    }

    if (ruleIndex >= rules.size()) {
      throw std::runtime_error("Trie internal structure corrupted!");
    }

    BaseRule& rule = *rules[ruleIndex];
    size_t methods = rule.getMethods();
    if ((methods & (1U << static_cast<size_t>(*verb))) == 0) {
      BMCWEB_LOG_DEBUG << "Rule found but method mismatch: "
                       << req.url().encoded_path() << " with "
                       << req.methodString() << "("
                       << static_cast<uint32_t>(*verb) << ") / " << methods;
      asyncResp->res.result(boost::beast::http::status::not_found);
      return;
    }

    BMCWEB_LOG_DEBUG << "Matched rule (upgrade) '" << rule.rule << "' "
                     << static_cast<uint32_t>(*verb) << " / " << methods;

    // TODO(ed) This should be able to use std::bind_front, but it doesn't
    // appear to work with the std::move on adaptor.
    validatePrivilege(
        req, asyncResp, rule,
        [&rule, asyncResp,
         adaptor(std::forward<Adaptor>(adaptor))](Request& thisReq) mutable {
          rule.handleUpgrade(thisReq, asyncResp, std::move(adaptor));
        });
  }

  template <uint64_t Tag>
  std::vector<std::unique_ptr<BaseRule>>::iterator findRuleByUrlAndVerb(
      std::string_view url, boost::beast::http::verb boostVerb) {
    std::optional<HttpVerb> verb = httpVerbFromBoost(boostVerb);
    if (!verb) {
      return allRules.end();
    }

    for (auto iter = allRules.begin(); iter != allRules.end(); ++iter) {
      if ((*iter)->rule == url &&
          ((*iter)->methodsBitfield & (1 << static_cast<size_t>(*verb))) > 0) {
        return iter;
      }
    }
    return allRules.end();
  }

  void handle(Request& req,
              const std::shared_ptr<bmcweb::AsyncResp>& asyncResp);

  void debugPrint();

  std::vector<const std::string*> getRoutes(const std::string& parent);

  static void throwHandlerNotFound(std::string_view url,
                                   boost::beast::http::verb boostVerb);

  template <uint64_t Tag, typename Func>
  void replaceHandler(std::string_view url, boost::beast::http::verb boostVerb,
                      Func&& func) {
    auto iter = findRuleByUrlAndVerb<Tag>(url, boostVerb);
    if (iter == allRules.end()) {
      throwHandlerNotFound(url, boostVerb);
    }
    using RuleT =
        black_magic::Arguments<Tag>::type::template rebind<TaggedRule>;
    RuleT* rule = dynamic_cast<RuleT*>(iter->get());
    rule->replaceHandler(func);
  }

  template <uint64_t Tag, typename Func>
  void appendHandler(std::string_view url, boost::beast::http::verb boostVerb,
                     Func&& func) {
    auto iter = findRuleByUrlAndVerb<Tag>(url, boostVerb);
    if (iter == allRules.end()) {
      throwHandlerNotFound(url, boostVerb);
    }
    using RuleT =
        typename black_magic::Arguments<Tag>::type::template rebind<TaggedRule>;
    RuleT* rule = dynamic_cast<RuleT*>(iter->get());

    rule->appendHandler(func);
  }

 private:
  static bool isUserPrivileged(
      Request& req, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
      BaseRule& rule, const dbus::utility::DBusPropertiesMap& userInfoMap);

  struct PerMethod {
    std::vector<BaseRule*> rules;
    Trie trie;
    // rule index 0 has special meaning; preallocate it to avoid
    // duplication.
    PerMethod() : rules(1) {}
  };

  std::array<PerMethod, methodNotAllowedIndex + 1> perMethods;  // NOLINT
  std::vector<std::unique_ptr<BaseRule>> allRules;              // NOLINT

  bool allowSessionEmpty = false;  // NOLINT
};
}  // namespace crow

#endif  // THIRD_PARTY_GBMCWEB_HTTP_ROUTING_H_
