#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_AUTHZ_AUTHZ_SERVER_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_AUTHZ_AUTHZ_SERVER_H_

#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <memory>
#include <string>
#include <string_view>

#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
#include "config_parser.h"
#include "oauth.grpc.pb.h"
#include "oauth.pb.h"
#include "g3/grpc_headers.h"

namespace milotic::authz {
// ssh-keygen user certificate sign command template take parameters:
// {0}: port_id
// {1}: life_time_in_seconds
// {2}: the public key file
constexpr std::string_view kHiscCertGenCmd =
    R"delim(/usr/bin/ssh-keygen \
      -s /run/hiscd/hiscd_ca \
      -I "port-{0}@$(hostname)" \
      -z "$(date +%s)" \
      -n "hisc" \
      -V "+{1}s" \
      -O clear -O permit-pty \
      -O force-command='/usr/libexec/ttf-console.sh -s user port-{0}' \
      {2} 2>&1 | /usr/bin/systemd-cat -t hisc_token -p info
    )delim";

// The maximum life time in seconds of Host Interactive Serial Console token.
constexpr uint32_t kMaxHiscCertLifeTimeInSeconds = 30 * 60;  // 30 mins

// The system dependency of HiscToken RPC
class HiscTokenSystemDependency {
 public:
  virtual ~HiscTokenSystemDependency() = default;
  virtual int LibcMkstemp(char tmpname[]) = 0;
  virtual int RunSshKeyGen(const std::string& cmd,
                           std::string_view input_key_file) = 0;
};

// This class is thread-safe. The thread safety is provided by the system
// functions it calls and the cmd it runs which are thread-safe.
class BMCHiscTokenSystemDependency : public HiscTokenSystemDependency {
 public:
  int LibcMkstemp(char tmpname[]) override { return mkstemp(tmpname); }
  int RunSshKeyGen(const std::string& cmd,
                   [[maybe_unused]] std::string_view input_key_file) override {
    return std::system(cmd.c_str());
  }
};
// The AuthorizationServer only works in mutual TLS mode.
struct ServerConfiguration {
  int port = 0;
  // The credentials used in the gRPC interface.
  std::string trust_bundle_path;
  std::string server_certificate_path;
  std::string server_key_path;
  std::string server_fqdn;
  std::string authz_configuration_path;
  std::string crl_directory;

  // The absolute path where Offline Node Entities file is. (Can be left empty)
  // This should be the file installed on the node during RRI
  // For more information see go/node-entities-api
  std::string offline_node_entities_path;

  // The path where the Google Machine Identity is. If left empty, machines in
  // HWOPS may be configured incorrectly. For more information see
  // go/google-machine-identity-token
  std::string google_machine_identity_path;

  // The path where the server will dump the public key for other processes.
  std::string rsa_public_key_path;
};

namespace impl {

class AuthorizationServiceImpl : public ::oauth::AuthorizationService::Service {
 public:
  explicit AuthorizationServiceImpl(const ServerConfiguration& server_config);

  grpc::Status Exchange(::grpc::ServerContext* /*context*/,
                        const ::oauth::ExchangeRequest* /*request*/,
                        ::oauth::ExchangeResponse* /*response*/) override;

  grpc::Status MintToken(::grpc::ServerContext* context,
                         const ::oauth::MintTokenRequest* request,
                         ::oauth::MintTokenResponse* response) override;

  grpc::Status HiscToken(::grpc::ServerContext* context,
                         const ::oauth::HiscTokenRequest* request,
                         ::oauth::HiscTokenResponse* response) override;

  ~AuthorizationServiceImpl() override = default;

  void LoadAuthzConfig();

  std::string GetRsaPrivateKey() const { return rsa_private_key_; }

  std::string GetServerFqdn();

  void SetServerFqdn(const std::string& server_fqdn);

 protected:
  grpc::Status AuthorizeMintTokenRpc(const grpc::AuthContext& context);

  grpc::Status CheckMintTokenRequest(const ::oauth::MintTokenRequest& request);

  std::string GetAndIncreaseTokenCount();

  grpc::Status AuthorizeHiscTokenRpc(const grpc::AuthContext& context);

  static grpc::Status HiscToken(
      const ::oauth::HiscTokenRequest* request,
      ::oauth::HiscTokenResponse* response,
      HiscTokenSystemDependency& hisc_token_system_dependency);

 private:
  std::unique_ptr<AuthzConfiguration> authz_config_;
  std::string rsa_private_key_;

  absl::Mutex mutex_;
  std::size_t token_count_ ABSL_GUARDED_BY(mutex_);
  ServerConfiguration server_config_ ABSL_GUARDED_BY(mutex_);
  BMCHiscTokenSystemDependency bmc_hisc_token_system_dependency_;
};

}  // namespace impl

// The BMC local authorization server.
// This class is thread-safe.
class AuthorizationServer {
 public:
  explicit AuthorizationServer(const ServerConfiguration& config);
  ~AuthorizationServer();

  void StartServer();

  // Thread safe reload on authz config without updating the RSA key
  void ReloadAuthzConfig(const std::string& server_fqdn);

  // Blocks until process is killed.
  void Wait();

  std::string GetRsaPrivateKey() const { return service_->GetRsaPrivateKey(); }

 private:
  ServerConfiguration server_config_;
  std::unique_ptr<impl::AuthorizationServiceImpl> service_;
  std::unique_ptr<grpc::Server> server_;
};

}  // namespace milotic::authz
#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_AUTHZ_AUTHZ_SERVER_H_
