#ifndef THIRD_PARTY_MILOTIC_INTERNAL_CC_AUTHZ_BMCWEB_AUTHORIZER_SINGLETON_H_
#define THIRD_PARTY_MILOTIC_INTERNAL_CC_AUTHZ_BMCWEB_AUTHORIZER_SINGLETON_H_

#include <cstddef>
#include <cstdint>
#include <map>
#include <string>
#include <string_view>
#include <unordered_set>
#include <utility>
#include <vector>

#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
#include "boost/beast/http/verb.hpp"  // NOLINT
#include "authorizer_enums.h"
#include "redfish_v1.pb.h"
#include "grpcpp/security/auth_context.h"
#include "grpcpp/support/status.h"
#include "grpcpp/support/string_ref.h"
#include "nlohmann/json.hpp"
#include "config_parser.h"
#include "redfish_authorizer.h"
#include "zatar/certificate_metadata.h"

namespace milotic::authz {

// Performs dynamic authorization based on configuration files.
// It encapsulates all states and operations that're needed for BMC
// authorization.
// This class is thread-safe.
class BmcWebAuthorizerSingleton {
 public:
  struct RequestState {
    bool with_trust_bundle = true;
    bool peer_authenticated = false;
    std::unordered_set<std::string> peer_privileges;
  };

  virtual ~BmcWebAuthorizerSingleton() = default;

  // Note: the first call will initialize the function local instance. All
  // future calls won't change the state of the singleton.
  // Typical usage:
  //  // Initialize with arguments
  // BmcWebAuthorizerSingleton::Initialize(...);
  //  // Reference without arguments
  // BmcWebAuthorizerSingleton::GetInstance().CheckTarget(...);
  static BmcWebAuthorizerSingleton& Initialize(const AuthorizerOptions& options,
                                               std::string_view oauth_key_path);
  static BmcWebAuthorizerSingleton& GetInstance();

  // Checks if the peer's target matches with the BMC.
  // Shall be called in every RPC.
  grpc::Status CheckTarget(
      const grpc::AuthContext& context,
      const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata,
      const ::redfish::v1::Request& request) const;

  // Authorizes peer via its identity and the status of the request.
  // The identity of the peer can be derived from peer's X.509 SAN, or from
  //  OAuth Token.
  // Returns OK status if the request is authorized. Otherwise returns
  // corresponding error.
  grpc::Status Authorize(std::string_view uri, boost::beast::http::verb verb,
                         const RequestState& request_state) const;

  // Processes the OAuth workflow and gets peer's privileges
  // - decodes the token
  // - verifies the signature of the token
  // - verifies the peer X.509 certificate matches the subject
  // - extract peer's privileges
  grpc::Status GetPrivilegesViaOAuth(
      const grpc::AuthContext& context, const std::string& token,
      std::unordered_set<std::string>& peer_privileges) const;

  // Looks up the peer's privileges by its MTls identity and the authorization
  // configuration
  grpc::Status GetPrivilegesViaMTls(
      const grpc::AuthContext& context,
      std::unordered_set<std::string>& peer_privileges) const;

  // Reloads the authorization configuration and all credentials (GMI, OAuth
  // key, etc).
  void ReloadConfiguration();

  // Records a new subscription for the peer and returns if it is allowed.
  grpc::Status RecordNewSubscription(const PeerSpiffeIdentity& peer);
  // Records a new unsubscription for the peer.
  grpc::Status RecordNewUnsubscription(const PeerSpiffeIdentity& peer);

  static grpc::Status GetPeerIdentityFromAuthContext(
      const grpc::AuthContext& context, PeerSpiffeIdentity& peer_identity);

  // Returns the peer role from the auth context.
  // On error, peer_role will be empty.
  grpc::Status GetPeerRoleFromAuthContext(const grpc::AuthContext& context,
                                          std::string& peer_role) const;

  // Returns the sample rate limit for the peer role.
  uint64_t GetSampleRateLimit(const std::string& peer_role) const;

  // Returns feed client target address for the peer role.
  std::string GetAnycastAddress(const std::string& peer_role) const;

  // Reloads the redfish authorizer with the given configuration path.
  void ReloadRedfishAuthorizer(const std::string& configuration_path);

  void RegisterAnycastUser(
      const std::string& service,
      platforms_syshealth::collection::feed::AnycastUser* user);

  void DeregisterAnycastUser(const std::string& service);

  static ecclesia::Operation BoostVerbToOperation(
      boost::beast::http::verb verb);

  ecclesia::ResourceEntity GetEntityTypeFromRedfishUri(
      std::string_view uri) const;

  size_t GetNodeIndexInPatternArray(std::string_view uri) const;

  // Get current Redfish Privilege Registry
  nlohmann::json GetRedfishPrivilegeRegistry() const;

  bool IsBasePrivilegeRegistryFound() const;

  void SetBasePrivilegesFolder(std::string_view base_privileges_folder);

  // Reset GMI path, used by unit test only.
  void ReloadGmiPaths(std::string_view gmi_path);

  BmcWebAuthorizerSingleton(const AuthorizerOptions& options,
                            std::string_view oauth_key_path);

 protected:
  std::string ReadPrimaryFqdnFromGmi() const;
  std::string ReadOauthKeyFromFile() const;
  std::vector<std::string> ReadDomainNameFromOfflineNodeEntity(
      std::string_view primary_fqdn) const;

  virtual grpc::Status AuthorizeWithoutTrustBundle(
      std::string_view uri, boost::beast::http::verb verb) const;

  virtual grpc::Status RecoveryAuthorizeForBloom(
      std::string_view uri, boost::beast::http::verb verb) const;

  virtual grpc::Status AuthorizeWithTrustBundle(
      std::string_view uri, boost::beast::http::verb verb,
      const RequestState& request_state) const;

  std::string GetPrimaryFqdn() const {
    absl::MutexLock lock(&mutex_);
    return primary_fqdn_;
  }
  std::string GetOauthKey() const {
    absl::MutexLock lock(&mutex_);
    return oauth_key_;
  }
  std::vector<std::string> GetInterfaceFqdns() const {
    absl::MutexLock lock(&mutex_);
    return interface_fqdns_;
  }
  void SetPrimaryFqdn(std::string_view fqdn) {
    absl::MutexLock lock(&mutex_);
    primary_fqdn_ = fqdn;
  }
  void SetOauthKey(std::string_view oauth_key) {
    absl::MutexLock lock(&mutex_);
    oauth_key_ = oauth_key;
  }
  void SetInterfaceFqdns(std::vector<std::string>&& fqdns) {
    absl::MutexLock lock(&mutex_);
    interface_fqdns_ = std::move(fqdns);
  }

  bool tlbmc_trust_bundle_install_module_is_enabled_;

 private:
  mutable absl::Mutex mutex_;

  std::string gmi_path_;
  std::string oauth_key_path_;
  std::string offline_node_entity_path_;

  // |primary_fqdn_| is read from GMI file at |gmi_path_|; empty string means an
  // error happened, e.g., missing or corrupted GMI file
  std::string primary_fqdn_ ABSL_GUARDED_BY(mutex_);

  // |interface_fqdns_| is read from offline node entity file; including all
  // interfaces' domain name
  std::vector<std::string> interface_fqdns_ ABSL_GUARDED_BY(mutex_);

  // |oauth_key_| is read from key file at |oauth_key_path_|; empty string means
  // an error happened, e.g., missing or corrupted GMI file
  std::string oauth_key_ ABSL_GUARDED_BY(mutex_);

  RedfishAuthorizer redfish_authorizer_;
  ::milotic::redfish::CertificateMetadataParser metadata_parser_;
};
}  // namespace milotic::authz

#endif  // THIRD_PARTY_MILOTIC_INTERNAL_CC_AUTHZ_BMCWEB_AUTHORIZER_SINGLETON_H_
