#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_AUTHZ_CONFIG_PARSER_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_AUTHZ_CONFIG_PARSER_H_

#include <array>
#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 = "");

  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();

  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_);
};

}  // namespace milotic::authz

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_AUTHZ_CONFIG_PARSER_H_
