// gpowerd is a the safe power local agent  for BMC.
// It  implements the SafePowerLocalAgent service, andis responsible for
// actuating power cycles on the machine.

#include "bmc/auth.h"
#include <gpowerd_build_config.h>

#include <filesystem>  // NOLINT(build/c++17)
#include <memory>
#include <string>
#include <system_error>  // NOLINT(build/c++11)
#include <utility>

#include "bmc/auth_loas3.h"
#include "bmc/gmi_reader.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_format.h"
#include "grpc/grpc_security_constants.h"
#include "grpcpp/security/authorization_policy_provider.h"
#include "grpcpp/security/server_credentials.h"
#include "grpcpp/security/tls_certificate_provider.h"
#include "grpcpp/security/tls_certificate_verifier.h"
#include "grpcpp/security/tls_credentials_options.h"
#include "grpcpp/server_builder.h"
#include "grpcpp/support/status.h"
#include "zatar/generate_self_signed_cert.h"

namespace auth {

using ::grpc::experimental::AuthorizationPolicyProviderInterface;
using ::grpc::experimental::ExternalCertificateVerifier;
using ::grpc::experimental::FileWatcherAuthorizationPolicyProvider;
using ::grpc::experimental::FileWatcherCertificateProvider;
using ::grpc::experimental::TlsServerCredentials;
using ::grpc::experimental::TlsServerCredentialsOptions;
using ::milotic::authn::SelfSignedCertOptions;

absl::StatusOr<std::shared_ptr<grpc::ServerCredentials>> GetCredsInfo() {
#ifdef LOAS3_AUTH
  SetupLoas3();
#else
  LOG(WARNING) << "LOAS3 is not enabled";
#endif

  std::error_code file_error;
  bool file_exist = std::filesystem::exists(kZatarCertFilePath, file_error);
  if (file_error) {
    return absl::NotFoundError("tls file path error: " + file_error.message() +
                               "file path: " + std::string(kZatarCertFilePath));
  }
  std::string keypair_path;
  if (file_exist) {
    keypair_path = std::string(kZatarCertFilePath);
  } else {
    // cert is not present (self sign a cert)
    keypair_path = absl::StrFormat("/tmp/gpowerd_self_signed_%d.pem", getpid());
    absl::StatusOr<std::string> host_name = gmi_reader::ReadGmiHostName();
    if (!host_name.ok()) {
      LOG(ERROR) << "unable to read gmi host name: " << host_name.status();
      return host_name.status();
    }
    SelfSignedCertOptions option;
    option.server_fqdn = *host_name;
    if (absl::Status status =
            GenerateSelfSignedCertAndDump(keypair_path, option);
        !status.ok()) {
      LOG(ERROR) << "unable to write self signed cert: " << status;
      return status;
    }
  }
  auto certificateProvider = std::make_shared<FileWatcherCertificateProvider>(
      keypair_path, keypair_path, std::string(kTrustBundleFilePath),
      /* refresh_interval_sec */ 30);

  TlsServerCredentialsOptions options(certificateProvider);
  options.watch_root_certs();
  options.set_root_cert_name("Zatar");
  options.watch_identity_key_cert_pairs();
  options.set_cert_request_type(
      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
#ifdef LOAS3_AUTH
  auto cert_verifier = ExternalCertificateVerifier::Create<PeerVerifier>();
  options.set_certificate_verifier(std::move(cert_verifier));
#endif
  std::shared_ptr<grpc::ServerCredentials> tlsServerCredentials =
      TlsServerCredentials(options);
  if (tlsServerCredentials == nullptr) {
    LOG(ERROR) << "tls Server Credentials error:";
    return absl::NotFoundError("tls Server Credentials error");
  }
  return tlsServerCredentials;
}

absl::StatusOr<std::shared_ptr<AuthorizationPolicyProviderInterface>>
GetAuthPolicy() {
  grpc::Status policy_status;
  std::shared_ptr<AuthorizationPolicyProviderInterface> policy =
      FileWatcherAuthorizationPolicyProvider::Create(
          std::string(kGpowerDCertAuthZPolicy),
          /* policy refresh_interval_sec = 30 */ 30, &policy_status);
  if (!policy_status.ok()) {
    return absl::NotFoundError(
        "failed to load policy file error: " + policy_status.error_message() +
        "file path:" + std::string(kGpowerDCertAuthZPolicy));
  }
  return policy;
}

}  // namespace auth
