#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_AUTHZ_CONFIG_PARSER_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_AUTHZ_CONFIG_PARSER_H_

#include <array>
#include <cstdint>
#include <optional>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "gmi/machine_identity.pb.h"
#include "one/offline_node_entities.pb.h"
#include "absl/base/thread_annotations.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "absl/synchronization/mutex.h"
#include "nlohmann/json.hpp"
#include "authorized_entity.pb.h"

namespace milotic::authz {

using ::production_msv::node_entities_proto::OfflineNodeEntityInformation;
using ::security_prodid::GoogleMachineIdentityProto;

constexpr std::array<absl::string_view, 6> kDefaultRedfishPrivileges{
    // go/keep-sorted start
    "ConfigureComponents",
    "ConfigureManager",
    "ConfigureSelf",
    "ConfigureUsers",
    "Login",
    "NoAuth"
    // go/keep-sorted end
};

constexpr absl::string_view kHwopsRole = "insecure-hwops-state";

// Peer's identity.
// Defined in third_party/milotic/internal/auth_config/schema.
struct PeerSpiffeIdentity {
  std::string spiffe_id;
  std::optional<std::string> fqdn;

  std::string DebugString() const {
    std::string res = "|spiffe_id|='";
    res += spiffe_id;
    res += "'; |fqdn|='";
    res += fqdn.value_or("");
    res += '\'';
    return res;
  }
};

struct PeerLoasIdentity {
  std::string username;

  std::string DebugString() const {
    std::string res = "|username|='";
    res += username;
    res += '\'';
    return res;
  }
};

// Stores the configurations for the authorization server or the Redfish
// authorization processor.
// The class is thread-safe
class AuthzConfiguration {
 public:
  struct SpiffeIdMatcher {
    std::string trust_domain_suffix;
    std::string path;
    std::string ca_context;
    std::optional<std::string> realm;  // std::nullopt realm means any realm.
    std::string issuer;  // TODO (b/274144469) issuer is not used for now.

    // Since SPIFFE is unique with the fields (path, ca_context, trust), not
    // using issuer or realm in operator<.
    // issuer is not used and realm may be null when creating matchers.
    bool operator<(const SpiffeIdMatcher& other) const {
      return std::tie(path, ca_context, trust_domain_suffix) <
             std::tie(other.path, other.ca_context, other.trust_domain_suffix);
    }

    bool operator==(const SpiffeIdMatcher& other) const {
      // Realm must exist for both matchers for realm checking
      if (realm.has_value() && other.realm.has_value()) {
        return std::tie(path, ca_context, trust_domain_suffix, realm) ==
               std::tie(other.path, other.ca_context, other.trust_domain_suffix,
                        other.realm);
      }
      return std::tie(path, ca_context, trust_domain_suffix) ==
             std::tie(other.path, other.ca_context, other.trust_domain_suffix);
    }

    std::string DebugString() const {
      return absl::Substitute(
          "SpiffeIdMatcher is |trust_domain_suffix|=$0; |path|=$1; "
          "|ca_context|=$2; |realm|=$3; |issuer|=$4\n",
          trust_domain_suffix, path, ca_context, realm.value_or("ALL"), issuer);
    }
  };

  struct SpiffeIdentityMatcher {
    SpiffeIdMatcher spiffe_id_matcher;
    std::optional<std::string> fqdn;

    bool operator<(const SpiffeIdentityMatcher& other) const {
      return std::tie(spiffe_id_matcher, fqdn) <
             std::tie(other.spiffe_id_matcher, other.fqdn);
    }

    bool operator==(const SpiffeIdentityMatcher& other) const {
      return std::tie(spiffe_id_matcher, fqdn) ==
             std::tie(other.spiffe_id_matcher, other.fqdn);
    }

    std::string DebugString() const {
      return absl::Substitute(
          "SpiffeIdentityMatcher is |spiffe_id_matcher|=$0; |fqdn|=$1\n",
          spiffe_id_matcher.DebugString(), fqdn.value_or("nullopt"));
    }
  };

  struct ResourceOwner {
    SpiffeIdentityMatcher identity_matcher;

    bool operator<(const ResourceOwner& other) const {
      return identity_matcher < other.identity_matcher;
    }

    bool operator==(const ResourceOwner& other) const {
      return identity_matcher == other.identity_matcher;
    }

    std::string DebugString() const {
      return absl::Substitute("ResourceOwner is |SpiffeIdentityMatcher|=$0\n",
                              identity_matcher.DebugString());
    }
  };

  struct SpiffeUser {
    SpiffeIdentityMatcher identity_matcher;
    std::string redfish_role;

    bool operator<(const SpiffeUser& other) const {
      return identity_matcher < other.identity_matcher;
    }

    bool operator==(const SpiffeUser& other) const {
      return identity_matcher == other.identity_matcher;
    }

    bool operator!=(const SpiffeUser& other) const { return !(*this == other); }
  };

  // This class is used to store information when looking up an entity tag in
  // Offline Node Entities.
  struct EntityTagIdentity {
    std::string hostname;
    std::string owner;

    bool operator==(const EntityTagIdentity& other) const = default;
  };

  AuthzConfiguration() = default;

  explicit AuthzConfiguration(const nlohmann::json& config,
                              absl::string_view offline_node_entities_path = "",
                              absl::string_view gmi_path = "");

  std::string GetPeerRedfishRole(const PeerSpiffeIdentity& peer) const;

  uint64_t GetSampleRateLimit(const std::string& peer_role) const;

  bool IsPeerResourceOwner(const PeerSpiffeIdentity& peer) const;

  // Returns the Redfish privileges of the given user identified by SPIFFE.
  std::unordered_set<std::string> GetPeerRedfishPrivileges(
      const PeerSpiffeIdentity& peer) const;

  // Returns the Redfish privileges of the given user identified by LOAS name.
  std::unordered_set<std::string> GetPeerRedfishPrivileges(
      const PeerLoasIdentity& peer) const;

  std::unordered_set<std::string> GetRedfishPrivileges(
      const std::string& role) const {
    absl::MutexLock lock(&mutex_);
    auto it = role_to_privileges_.find(role);
    if (it == role_to_privileges_.end()) {
      return {"NoAuth"};
    }
    return it->second;
  }

  std::unordered_set<std::string> GetOemPrivileges() const;

  std::vector<std::string> GetDefaultRedfishPrivileges() const {
    return {kDefaultRedfishPrivileges.begin(), kDefaultRedfishPrivileges.end()};
  }

  void ReloadConfig(const nlohmann::json& config,
                    const nlohmann::json& platform_config);

  OfflineNodeEntityInformation GetOfflineNodeEntities() const {
    absl::MutexLock lock(&mutex_);
    return offline_node_entities_;
  }

  absl::StatusOr<EntityTagIdentity> GetEntityTagIdentity(
      absl::string_view entity_tag) const;

  std::string GetMachineManagerEntityTag() const;

  // Returns all entity tags in which the NodeTypeInfo indicates that the
  // current ResolvedEntity in OfflineNodeEntities is a ComputeNode
  std::vector<std::string> GetAllComputeNodeEntityTags() const;

  // Given a redfish system id, return a list of the entity tags with that
  // system id. If there are none, return empty list
  std::vector<std::string> GetEntityTagsFromRedfishSystemId(
      absl::string_view system_id) const;

  std::vector<std::string> GetAllEntityTagsFromAuthorizedEntity(
      AuthorizedEntity entity) const;

  bool IsHwopsState() const;

  static std::optional<AuthzConfiguration::SpiffeIdentityMatcher>
  CreateIdentityMatcherFromPeerSpiffeIdentity(const PeerSpiffeIdentity& peer);

 protected:
  bool IsResourceOwnerExisting(const ResourceOwner& resource_owner) const;

  absl::StatusOr<std::string> GetRedfishRoleOfSpiffeMatcher(
      const SpiffeUser& spiffe_user) const;

  // USED ONLY IN UNIT TESTS
  std::vector<ResourceOwner> GetResourceOwners() const {
    absl::MutexLock lock(&mutex_);
    return resource_owners_;
  }

  // USED ONLY IN UNIT TESTS
  std::vector<SpiffeUser> GetSpiffeUsers() const {
    absl::MutexLock lock(&mutex_);
    return spiffe_users_;
  }

  std::unordered_map<std::string, std::string> GetGroupToRoles() const {
    absl::MutexLock lock(&mutex_);
    return group_to_role_;
  }

  // Returns the Redfish role of the given user identitfied by username.
  // Returns nullopt if the username is unknown.
  std::optional<std::string> GetRoleByUsername(
      const std::string& username) const {
    absl::MutexLock lock(&mutex_);
    auto it = username_to_role_.find(username);
    if (it != username_to_role_.end()) {
      return it->second;
    } else {
      return std::nullopt;
    }
  }

  // Returns the Redfish role of the given user identitfied by group.
  // The implementation searches the first group that the user is in; if no
  // group is found, returns nullopt.
  std::optional<std::string> GetRoleByGroup(
      [[maybe_unused]] const std::string& username) const {
    return std::nullopt;
  }

  void ReloadResourceOwners(const nlohmann::json& config);
  void ReloadRedfishUsers(const nlohmann::json& config);
  void ReloadRoleToPrivileges(const nlohmann::json& config,
                              const nlohmann::json& platform_config);
  void ReloadOfflineNodeEntities();
  void ReloadGmi();
  void ReloadSampleRateLimit(const nlohmann::json& config);

  std::optional<AuthzConfiguration::SpiffeIdentityMatcher>
  ParseSpiffeIdentityMatcher(const nlohmann::json& config);

  std::vector<SpiffeIdentityMatcher> ParseSpiffeIdentityMatchersUsingOne(
      const nlohmann::json& config) const;

  // When the machine is in HWOPS, GMI reports the actual owner and
  // "in_hwops_state", while certificates use insecure-hwops-state as the role
  // rather than the actual owner. go/aristotle-ownership-change#owner
  absl::string_view GetCertNodeOwner(absl::string_view node_owner) const;

  std::string GetNodeRealm() const;

 private:
  mutable absl::Mutex mutex_;
  const std::string offline_node_entities_path_;
  const std::string gmi_path_;
  OfflineNodeEntityInformation offline_node_entities_ ABSL_GUARDED_BY(mutex_);
  GoogleMachineIdentityProto gmi_ ABSL_GUARDED_BY(mutex_);
  std::vector<ResourceOwner> resource_owners_ ABSL_GUARDED_BY(mutex_);
  std::vector<SpiffeUser> spiffe_users_ ABSL_GUARDED_BY(mutex_);
  std::unordered_map<std::string, std::string> username_to_role_
      ABSL_GUARDED_BY(mutex_);
  std::unordered_map<std::string, std::string> group_to_role_
      ABSL_GUARDED_BY(mutex_);
  std::unordered_map<std::string, std::unordered_set<std::string>>
      role_to_privileges_ ABSL_GUARDED_BY(mutex_);
  std::unordered_map<std::string, uint64_t> role_to_sample_rate_limit_
      ABSL_GUARDED_BY(mutex_);
};

}  // namespace milotic::authz

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_AUTHZ_CONFIG_PARSER_H_
