#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_ = MethodFieldsFromSingleHttpVerb(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_ = MethodFieldsFromSingleHttpVerb(*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();

  // Returns a vector of pairs of registered routes (url, methods_bit_field)
  std::vector<std::pair<std::string_view, size_t>> 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_ &
           MethodFieldsFromSingleHttpVerb(*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_
