#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_REDFISH_ROUTING_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_REDFISH_ROUTING_H_

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

#include "absl/log/log.h"
#include "boost/container/flat_map.hpp"  // NOLINT
#include "tlbmc/redfish/black_magic.h"
#include "tlbmc/redfish/common.h"
#include "tlbmc/redfish/request.h"
#include "tlbmc/redfish/response.h"
#include "tlbmc/redfish/verb.h"
#include "router_interface.h"

namespace milotic_tlbmc {
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;
  virtual void Handle(const milotic_tlbmc::RedfishRequest& request,
                      milotic_tlbmc::RedfishResponse& response,
                      const RoutingParams& params) = 0;
  size_t methods_bit_field_{
      1 << static_cast<size_t>(milotic_tlbmc::HttpVerb::kGet)};

  static_assert(std::numeric_limits<decltype(methods_bit_field_)>::digits >
                    milotic_tlbmc::kMethodNotAllowedIndex,
                "Not enough bits to store bitfield");

  std::string rule_;
  friend class Router;
  template <typename T>
  friend struct RuleParameterTraits;
};

template <typename T>
struct RuleParameterTraits {
  using self_t = T;
  self_t& methods(boost::beast::http::verb method) {
    self_t* self = static_cast<self_t*>(this);
    std::optional<milotic_tlbmc::HttpVerb> verb =
        milotic_tlbmc::HttpVerbFromBoost(method);
    if (verb) {
      self->methods_bit_field_ = 1U << static_cast<size_t>(*verb);
    }
    return *self;
  }
};

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 milotic_tlbmc::RedfishRequest& req;
  milotic_tlbmc::RedfishResponse& resp;
};

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<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.resp,
        cparams.params.template Get<typename Args1::type>(Args1::pos)...);
  }
};

}  // namespace routing_handler_call_helper
}  // namespace detail

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("no handler for url " + rule_);
    }
  }

  template <typename Func>
  typename std::enable_if<
      !black_magic::CallHelper<Func, black_magic::S<Args...>>::value &&
          !black_magic::CallHelper<
              Func,
              black_magic::S<milotic_tlbmc::RedfishRequest, 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<milotic_tlbmc::RedfishRequest,
                                     Args...>>::value ||
            black_magic::CallHelper<
                Func, black_magic::S<milotic_tlbmc::RedfishRequest,
                                     milotic_tlbmc::RedfishResponse&,
                                     Args...>>::value,
        "Handler type is mismatched with URL parameters");
    static_assert(
        std::is_same<void,
                     decltype(f(std::declval<milotic_tlbmc::RedfishRequest>(),
                                std::declval<milotic_tlbmc::RedfishResponse&>(),
                                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) {
    (*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), previous_func = this->handler_](
            const milotic_tlbmc::RedfishRequest & req,
            milotic_tlbmc::RedfishResponse & resp, Args... args) {
          previous_func(req, resp, args...);
          f(req, resp, args...);
        });
  }

  void Handle(const milotic_tlbmc::RedfishRequest& req,
              milotic_tlbmc::RedfishResponse& resp,
              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, resp});
  }

 private:
  std::function<void(const milotic_tlbmc::RedfishRequest&,
                     milotic_tlbmc::RedfishResponse& resp, Args...)>
      handler_;
};

// Trie is thread-compatible.
// A trie is used to store the rules and efficiently find the rule for a given
// URL and a method.
class Trie {
 public:
  struct Node {
    unsigned rule_index{};
    std::array<size_t, static_cast<size_t>(ParamType::kMax)> param_children{};
    using ChildMap = boost::container::flat_map<
        std::string, unsigned, std::less<>,
        std::vector<std::pair<std::string, unsigned>>>;
    ChildMap children;

    bool IsSimpleNode() const {
      return rule_index == 0 &&
             std::all_of(std::begin(param_children), std::end(param_children),
                         [](size_t x) { return x == 0U; });
    }
  };

  Trie() : nodes_(1) {}

  // Builds the trie and optimizes it.
  void Validate() { Optimize(); }

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

  void Add(const std::string& url, unsigned index);

 private:
  void OptimizeNode(Node* node);

  // Optimizes the trie by merging nodes that do not have rules.
  void Optimize() { OptimizeNode(&nodes_.front()); }

  const Node* Head() const { return &nodes_.front(); }

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

  std::vector<Node> nodes_;
};

// Router is thread-compatible.
// Router provides a way to register rules and find the rule for a given URL and
// a method.
// After creation, `Handle` is safe to call from multiple threads
// simultaneously.
class Router {
 public:
  struct FindRoute {
    BaseRule* rule = nullptr;
    RoutingParams params;
  };

  struct FindRouteResponse {
    FindRoute route;
  };

  Router() = default;

  // Creates a new rule with the given tag and rule string.
  // The rule string must end with '/'.
  // Returns a reference to the created rule.
  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>;
    if (!rule.empty() && rule.back() != '/') {
      throw std::runtime_error("rule must end with '/'");
    }
    std::unique_ptr<RuleT> rule_object = std::make_unique<RuleT>(rule);
    RuleT* ptr = rule_object.get();
    all_rules_.emplace_back(std::move(rule_object));

    return *ptr;
  }

  template <uint64_t Tag>
  void RemoveRuleTagged(std::string_view url, boost::beast::http::verb method) {
    auto it = FindRule<Tag>(url, method);
    // Incorrect plugin configuration should kill the program.
    if (it == all_rules_.end()) {
      LOG(FATAL) << "Cannot Remove Rule: Rule not found: " << url << " "
                 << method;
    }
    all_rules_.erase(it);
  }

  template <uint64_t Tag, typename Func>
  void ReplaceHandler(std::string_view url, boost::beast::http::verb method,
                      Func&& func) {
    auto iter = FindRule<Tag>(url, method);
    if (iter == all_rules_.end()) {
      LOG(FATAL) << "Cannot Replace Handler: Rule not found: " << url << " "
                 << method;
    }
    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 method,
                     Func&& func) {
    auto iter = FindRule<Tag>(url, method);
    if (iter == all_rules_.end()) {
      LOG(FATAL) << "Cannot append Handler: Rule not found: " << url << " "
                 << method;
    }
    using RuleT =
        typename black_magic::Arguments<Tag>::type::template rebind<TaggedRule>;
    RuleT* rule = dynamic_cast<RuleT*>(iter->get());
    rule->AppendHandler(func);
  }

  // Optimizes the trie so it can be used for fast lookup.
  void Validate();

  std::vector<std::string_view> GetRegisteredRoutes() const;

  // Handles the request by finding the rule for the request and calling the
  // handler inside the rule.
  void Handle(const milotic_tlbmc::RedfishRequest& req,
              milotic_tlbmc::RedfishResponse& asyncResp) const;

  void SetSmartRouter(::crow::RouterInterface* smart_router) {
    smart_router_ = smart_router;
  }

 protected:
  template <uint64_t Tag>
  std::vector<std::unique_ptr<BaseRule>>::iterator FindRule(
      std::string_view url, boost::beast::http::verb method) {
    std::optional<HttpVerb> verb = HttpVerbFromBoost(method);
    if (!verb) {
      return all_rules_.end();
    }
    for (auto iter = all_rules_.begin(); iter != all_rules_.end(); ++iter) {
      if ((*iter)->rule_ == url && ((*iter)->methods_bit_field_ &
                                    (1 << static_cast<size_t>(*verb))) > 0) {
        return iter;
      }
    }
    return all_rules_.end();
  }

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

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

  FindRouteResponse FindRouteByRequest(
      const milotic_tlbmc::RedfishRequest& req) const;

  void InternalAddRuleObject(const std::string& rule, BaseRule* rule_object);

  std::array<PerMethod, milotic_tlbmc::kMethodNotAllowedIndex + 1> per_methods_;
  std::vector<std::unique_ptr<BaseRule>> all_rules_;
  ::crow::RouterInterface* smart_router_ = nullptr;
};

}  // namespace crow
}  // namespace milotic_tlbmc

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_REDFISH_ROUTING_H_
