#include "smart_router.h"

#include <cstddef>
#include <iostream>
#include <memory>
#include <string>
#include <string_view>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/str_split.h"
#include "absl/synchronization/mutex.h"
#include "http_request.hpp"
#include "async_resp.hpp"
#include "tlbmc/hal/shared_mem/server_interface.h"
#include "tlbmc/hal/shared_mem/static_server_impl.h"
#include "tlbmc/redfish/verb.h"
#include "app_interface.h"
#include "routing.hpp"

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

namespace crow {

using ::milotic_tlbmc::StaticSharedMemoryServer;

namespace internal {

void SimpleTrie::AddSubtree(std::string_view subtree) {
  std::vector<std::string_view> parts =
      absl::StrSplit(subtree, '/', absl::SkipEmpty());
  Node* node = &root_;
  for (const auto& part : parts) {
    node = &node->children[part];
  }
  node->is_leaf = true;
}

SimpleTrie::SimpleTrie(const absl::flat_hash_set<std::string>& subtrees)
    : subtrees_(subtrees) {
  for (const auto& subtree : subtrees) {
    AddSubtree(subtree);
  }
}

void SimpleTrie::DebugPrint() const {
  std::cerr << "tlBMC owned subtrees: \n";
  for (const auto& subtree : subtrees_) {
    std::cerr << subtree << "\n";
  }
}

bool SimpleTrie::IsUrlInSubtrees(std::string_view url) const {
  const Node* node = &root_;
  std::vector<std::string_view> parts =
      absl::StrSplit(url, '/', absl::SkipEmpty());
  for (const auto& part : parts) {
    if (node->is_leaf) {
      return true;
    }
    auto it = node->children.find(part);
    if (it == node->children.end()) {
      return false;
    }
    node = &it->second;
  }
  return node->is_leaf;
}

}  // namespace internal

SmartRouter::SmartRouter(bool allow_session_empty, AppInterface* tlbmc_app)
    : gbmcweb_router_(allow_session_empty),
      tlbmc_app_(tlbmc_app),
      tlbmc_owned_urls_(GetTlbmcOwnedUrls()),
      tlbmc_owned_subtrees_(GetTlbmcOwnedSubtrees()) {
  // We still need this logic to set the smart router for the tlbmc router.
  if (tlbmc_app_ != nullptr) {
    tlbmc_app_->SetSmartRouter(this);
    std::cerr << "SmartRouter created! Owned URLs: \n";
    for (const auto& [url, methods] : tlbmc_owned_urls_) {
      std::cerr << "url: " << url
                << " methods: " << milotic_tlbmc::MethodFieldsToString(methods)
                << "\n";
    }
  }
}

void SmartRouter::Handle(crow::Request& req,
                         const std::shared_ptr<bmcweb::AsyncResp>& async_resp) {
  boost::urls::url url(req.target());

  // If the request is not owned by TLBMC, then we will forward it to gBMCWeb.
  if (tlbmc_app_ == nullptr ||
      !IsTlbmcOwnedUrl(url.encoded_path(), req.method())) {
    gbmcweb_router_.handle(req, async_resp);
    if (tlbmc_app_ != nullptr) {
      milotic_tlbmc::StaticSharedMemoryServer::GetInstance()
          .UpdateMetricsRequestCount(false);
    }
    return;
  }

  // Otherwise we prepare for tlbmc to handle it.
  milotic_tlbmc::StaticSharedMemoryServer::GetInstance()
      .UpdateMetricsRequestCount(true);
  tlbmc_app_->HandleFromCrowRequest(req, async_resp);
}

std::vector<const std::string*> SmartRouter::GetRoutes(
    const std::string& parent) {
  return gbmcweb_router_.getRoutes(parent);
}

DynamicRule& SmartRouter::NewRuleDynamic(std::string&& rule) {
  return gbmcweb_router_.newRuleDynamic(rule);
}

void SmartRouter::DebugPrint() {
  gbmcweb_router_.debugPrint();
  if (tlbmc_app_ != nullptr) {
    tlbmc_app_->DebugPrint();
  }
}

void SmartRouter::Validate() { gbmcweb_router_.validate(); }

absl::flat_hash_map<std::string, size_t> SmartRouter::GetTlbmcOwnedUrls() {
  if (tlbmc_app_ == nullptr) {
    return {};
  }
  return tlbmc_app_->GetOwnedUrls();
}

absl::flat_hash_set<std::string> SmartRouter::GetTlbmcOwnedSubtrees() {
  if (tlbmc_app_ == nullptr) {
    return {};
  }
  return tlbmc_app_->GetOwnedSubtrees();
}

bool SmartRouter::IsTlbmcOwnedUrl(std::string_view url,
                                  boost::beast::http::verb verb) {
  // Our `tlbmc_owned_urls_` do not have a trailing slash
  if (url.ends_with('/')) {
    url.remove_suffix(1);
  }
  // NOLINTNEXTLINE: Yocto's Abseil is old and only supports pointer type
  absl::MutexLock lock(tlbmc_owned_urls_subtrees_mutex_);
  if (tlbmc_owned_subtrees_.IsUrlInSubtrees(url)) {
    return true;
  }
  auto it = tlbmc_owned_urls_.find(url);
  if (it == tlbmc_owned_urls_.end()) {
    return false;
  }
  return milotic_tlbmc::MethodFieldsContainBoostVerb(it->second, verb);
}

void SmartRouter::UpdateTlbmcOwnedUrls() {
  // NOLINTNEXTLINE: Yocto's Abseil is old and only supports pointer type
  absl::MutexLock lock(tlbmc_owned_urls_subtrees_mutex_);
  tlbmc_owned_urls_ = GetTlbmcOwnedUrls();
  tlbmc_owned_subtrees_ = internal::SimpleTrie(GetTlbmcOwnedSubtrees());
}

}  // namespace crow
