#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;

  std::string GetAnycastAddress(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,
                          const nlohmann::json& platform_config);
  void ReloadRoleToPrivileges(const nlohmann::json& config,
                              const nlohmann::json& platform_config);
  void ReloadOfflineNodeEntities();
  void ReloadGmi();
  void ReloadSampleRateLimit(const nlohmann::json& config);

  void AddRedfishUsersInfoFromConfig(
      const nlohmann::json& config,
      std::vector<AuthzConfiguration::SpiffeUser>& spiffe_users,
      std::unordered_map<std::string, std::string>& username_to_role,
      std::unordered_map<std::string, std::string>& group_to_role);

  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_);
  std::unordered_map<std::string, std::string> role_to_anycast_address_
      ABSL_GUARDED_BY(mutex_);
};

}  // namespace milotic::authz

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_AUTHZ_CONFIG_PARSER_H_
