#ifndef THIRD_PARTY_MILOTIC_INTERNAL_CC_BMCWEB_SMART_ROUTER_H_
#define THIRD_PARTY_MILOTIC_INTERNAL_CC_BMCWEB_SMART_ROUTER_H_

#include <array>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>

#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "boost/asio/io_context.hpp"  // NOLINT
#include "boost/beast/http/message.hpp"  //NOLINT
#include "boost/beast/http/string_body.hpp"  //NOLINT
#include "boost/beast/http/verb.hpp"  // NOLINT
#include "boost/system/error_code.hpp"  // NOLINT
#include "boost/url/parse.hpp"  // NOLINT
#include "boost/url/url.hpp"  // NOLINT
#include "http_request.hpp"
#include "async_resp.hpp"
#include "utility.hpp"
#include "app_interface.h"
#include "router_interface.h"
#include "routing.hpp"

// DO NOT MODIFY THIS FILE IN GERRIT. THIS FILE SHOULD ONLY BE MODIFIED IN G3

namespace crow {

namespace internal {

struct Node {
  absl::flat_hash_map<std::string, Node> children;
  bool is_leaf = false;
};

// The class is thread compatible.
class SimpleTrie {
 public:
  explicit SimpleTrie(const absl::flat_hash_set<std::string>& subtrees);
  ~SimpleTrie() = default;

  // This SimpleTrie is not going to validate the URL is actually a valid URL.
  // As the input of this function in our use case comes from a valid Redfish
  // request, the url is guaranteed to be a valid URL.
  bool IsUrlInSubtrees(std::string_view url) const;

  void DebugPrint() const;

 protected:
  void AddSubtree(std::string_view subtree);

 private:
  Node root_;
  const absl::flat_hash_set<std::string> subtrees_;
};

}  // namespace internal

// This router will automatically route the requests to the appropriate
// router based on the request path.
class SmartRouter : public RouterInterface {
 public:
  // Clang thinks that the following constructor is deleted, but on gcc, it is
  // not.
  SmartRouter() : tlbmc_owned_subtrees_({}) {};  // NOLINT
  ~SmartRouter() override = default;

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

  SmartRouter(bool allow_session_empty, AppInterface* tlbmc_app);

  void Validate();

  void Handle(crow::Request& req,
              const std::shared_ptr<bmcweb::AsyncResp>& async_resp) override;

  // This is a wrapper around the gbmcweb router's handleUpgrade function.
  template <typename Adaptor>
  void HandleUpgrade(Request& req,
                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                     Adaptor&& adaptor) {
    gbmcweb_router_.handleUpgrade(req, asyncResp,
                                  std::forward<Adaptor>(adaptor));
  }

  DynamicRule& NewRuleDynamic(std::string&& rule);

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

  void DebugPrint();

  template <uint64_t N>
  typename black_magic::Arguments<
      N>::type::template rebind<TaggedRule>&
  NewRuleTagged(std::string_view rule) {
    return gbmcweb_router_.newRuleTagged<N>(rule);
  }

  // Plugin Routes
  template <uint64_t Tag, typename Func, size_t N>
  void AddHandler(absl::string_view url, boost::beast::http::verb verb,
                  const std::array<redfish::Privileges, N>& p, Func&& func) {
    gbmcweb_router_.newRuleTagged<Tag>(url).methods(verb).privileges(p)(func);
    // TODO(b/396518102): Add support for plugins in tlbmc.
    // tlbmc_app_->AddRoute<Tag>(url).methods(verb)(func);
  }

  template <uint64_t Tag, typename Func>
  void ReplaceHandler(std::string_view url, boost::beast::http::verb verb,
                      Func&& func) {
    gbmcweb_router_.replaceHandler<Tag>(url, verb, func);
    // TODO(b/396518102): Add support for plugins in tlbmc.
    // tlbmc_app_->ReplaceHandler<Tag>(url, verb, func);
  }

  template <uint64_t Tag>
  void RemoveHandler(std::string_view url, boost::beast::http::verb verb) {
    gbmcweb_router_.removeRuleTagged<Tag>(url, verb);
    // TODO(b/396518102): Add support for plugins in tlbmc.
    // tlbmc_app_->RemoveHandler<Tag>(url, verb);
  }
  template <uint64_t Tag, typename Func>
  void AppendHandler(std::string_view url, boost::beast::http::verb verb,
                     Func&& func) {
    gbmcweb_router_.appendHandler<Tag>(url, verb, func);
    // TODO(b/396518102): Add support for plugins in tlbmc.
    // tlbmc_app_->AppendHandler<Tag>(url, verb, func);
  }

  bool IsTlbmcOwnedUrl(std::string_view url, boost::beast::http::verb verb);

  Router& GetGbmcwebRouter() { return gbmcweb_router_; }

  void UpdateTlbmcOwnedUrls() override;

 protected:
  // Store both the gbmcweb and tlbmc routers.
  Router gbmcweb_router_ = Router(true);
  AppInterface* const tlbmc_app_ = nullptr;
  absl::Mutex tlbmc_owned_urls_mutex_;
  absl::flat_hash_map<std::string, size_t> tlbmc_owned_urls_
      ABSL_GUARDED_BY(tlbmc_owned_urls_mutex_);

 private:
  absl::flat_hash_map<std::string, size_t> GetTlbmcOwnedUrls();
  absl::flat_hash_set<std::string> GetTlbmcOwnedSubtrees();
  const internal::SimpleTrie tlbmc_owned_subtrees_;
};

}  // namespace crow

#endif  // THIRD_PARTY_MILOTIC_INTERNAL_CC_BMCWEB_SMART_ROUTER_H_
