#include "redfish_entity_trie.h"

#include <algorithm>
#include <cstddef>
#include <iterator>
#include <limits>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "absl/container/flat_hash_set.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/strings/substitute.h"
#include "absl/synchronization/mutex.h"
#include "authorizer_enums.h"
#include "redfish_entity_trie_node.h"
#include "redfish_privileges.h"
#include "redfish_subtree_privileges_trie_node.h"

namespace milotic::authz {

using ::milotic::authz::internal::RedfishEntityTrieNode;
using ::milotic::authz::internal::RedfishSubtreePrivilegesTrieNode;

namespace {

// When authorizing we can ignore URI fragments. Authorizing /uri#fragment is
// the same as authorizing /uri
std::string_view IgnoreFragment(std::string_view uri) {
  return uri.substr(0, uri.find('#'));
}

bool ValidUri(std::string_view uri) {
  return !uri.empty() && uri.front() == '/';
}

absl::StatusOr<std::vector<std::string>> SplitUri(std::string_view uri) {
  if (!ValidUri(uri)) {
    return absl::InvalidArgumentError(absl::StrCat("Invalid URI: ", uri));
  }

  // Depending on if uri ends with /, then the last element of uri_split could
  // be empty
  std::vector<std::string> uri_split = absl::StrSplit(IgnoreFragment(uri), '/');

  if (!uri_split.empty() && uri_split.back().empty()) {
    uri_split.pop_back();
  }

  return uri_split;
}

}  // namespace

RedfishEntityTrie::RedfishEntityTrie()
    : entity_trie_root_(std::make_unique<RedfishEntityTrieNode>()),
      subtree_privileges_trie_root_(
          std::make_unique<RedfishSubtreePrivilegesTrieNode>()) {}

void RedfishEntityTrie::InsertUri(std::string_view uri,
                                  ecclesia::ResourceEntity entity_tag,
                                  std::size_t node_index_in_pattern_array) {
  absl::StatusOr<std::vector<std::string>> uri_split = SplitUri(uri);
  if (!uri_split.ok()) {
    return;
  }

  RedfishEntityTrieNode* cur = entity_trie_root_.get();

  // Every URI starts with a / so the first element is always empty
  for (size_t i = 1; i < uri_split->size(); ++i) {
    RedfishEntityTrieNode* child = cur->GetOrDefaultChild((*uri_split)[i]);

    // If the child is a wildcard path, set cur to IsCollection
    // Collection must be set after because collection is checked in
    // GetOrDefaultChild
    cur->SetCollection((*uri_split)[i].front() == '{');

    cur = child;
  }
  cur->SetEntityTag(entity_tag);
  cur->SetNodeIndexInPatternArray(node_index_in_pattern_array);
}

const RedfishEntityTrieNode* RedfishEntityTrie::GetTrieNode(
    std::string_view uri) const {
  absl::StatusOr<std::vector<std::string>> uri_split = SplitUri(uri);
  if (!uri_split.ok()) {
    return nullptr;
  }
  const RedfishEntityTrieNode* cur = entity_trie_root_.get();

  for (size_t i = 1; i < uri_split->size(); ++i) {
    const RedfishEntityTrieNode* child = cur->GetChild((*uri_split)[i]);

    if (child == nullptr) {
      return nullptr;
    }

    cur = child;
  }
  return cur;
}

ecclesia::ResourceEntity RedfishEntityTrie::GetEntityType(
    std::string_view uri) const {
  const RedfishEntityTrieNode* cur = GetTrieNode(uri);
  if (cur == nullptr) {
    return ecclesia::ResourceEntity::kUndefined;
  }
  return cur->GetEntityTag();
}

std::size_t RedfishEntityTrie::GetNodeIndexInPatternArray(
    std::string_view uri) const {
  const RedfishEntityTrieNode* cur = GetTrieNode(uri);
  if (cur == nullptr) {
    return std::numeric_limits<std::size_t>::max();
  }
  return cur->GetNodeIndexInPatternArray();
}

absl::Status RedfishEntityTrie::AddSubtreeMapping(
    SubtreePrivilegeMapping&& subtree_privilege_mapping) {
  absl::StatusOr<std::vector<std::string>> uri_split =
      SplitUri(subtree_privilege_mapping.url);
  if (!uri_split.ok()) {
    return uri_split.status();
  }

  RedfishSubtreePrivilegesTrieNode* cur = subtree_privileges_trie_root_.get();

  // Every URI starts with a / so the first element is always empty
  for (size_t i = 1; i < uri_split->size(); ++i) {
    RedfishSubtreePrivilegesTrieNode* child =
        cur->GetOrDefaultChild((*uri_split)[i]);
    if (child->ContainsPrivilegeForSubtree(
            subtree_privilege_mapping.operation,
            subtree_privilege_mapping.privileges)) {
      return absl::AlreadyExistsError(absl::Substitute(
          "URI: $0 already exists in the trie", subtree_privilege_mapping.url));
    }
    cur = child;
  }
  cur->AddPrivilegeForSubtree(subtree_privilege_mapping.operation,
                              std::move(subtree_privilege_mapping.privileges));

  return absl::OkStatus();
}

void RedfishEntityTrie::ReplaceSubtreePrivilegeMappings(
    std::vector<SubtreePrivilegeMapping>&& subtree_privilege_mappings) {
  // Sort based on strings as order of addition of subtree mappings into the
  // trie matters.
  // TODO: Lazy propagation can be done to eliminate the need for this sort
  std::sort(subtree_privilege_mappings.begin(),
            subtree_privilege_mappings.end());

  absl::MutexLock lock(&subtree_privileges_mutex_);

  // Clear the subtree_privileges trie
  subtree_privileges_trie_root_->Clear();

  for (auto& mapping : subtree_privilege_mappings) {
    // Have to get mapping string first before moving struct.
    std::string mapping_string = mapping.ToString();
    absl::Status status = AddSubtreeMapping(std::move(mapping));
    // Log all failures but continue to add mappings
    if (!status.ok()) {
      LOG(ERROR) << mapping_string << " was not added due to error: " << status;
    }
  }
}

absl::flat_hash_set<RedfishPrivileges>
RedfishEntityTrie::GetAdditionalSubtreePrivileges(
    std::string_view uri, const ecclesia::Operation& operation) const {
  absl::flat_hash_set<RedfishPrivileges> privileges_list;
  absl::StatusOr<std::vector<std::string>> uri_split = SplitUri(uri);
  if (!uri_split.ok()) {
    return privileges_list;
  }

  absl::MutexLock lock(&subtree_privileges_mutex_);
  RedfishSubtreePrivilegesTrieNode* cur = subtree_privileges_trie_root_.get();

  // increment cur_uri_len to incorporate the / per for loop iteration
  for (size_t i = 1; i < uri_split->size(); ++i) {
    RedfishSubtreePrivilegesTrieNode* child = cur->GetChild((*uri_split)[i]);

    // If the URI does not exist in the trie, return current privileges we
    // have gotten
    if (child == nullptr) {
      return privileges_list;
    }

    std::vector<RedfishPrivileges> privileges_for_subtree =
        child->GetPrivilegesForSubtree(operation);

    privileges_list.insert(
        std::make_move_iterator(privileges_for_subtree.begin()),
        std::make_move_iterator(privileges_for_subtree.end()));

    cur = child;
  }

  return privileges_list;
}

}  // namespace milotic::authz
