#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 "tlbmc/anycast_user.h"
#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 "nlohmann/json.hpp"
#include "config_parser.h"
#include "redfish_authorizer.h"
#include "g3/grpc_headers.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);

  // Reloads the redfish authorizer with the current configuration path.
  void ReloadRedfishAuthorizer();

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

  nlohmann::json GetConfig() const;

  nlohmann::json GetPrivilegeRegistry() const;

 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_
