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

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

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

 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_
