#include "tlbmc/credentials/credential_manager.h"

#include <filesystem>  // NOLINT
#include <memory>
#include <string>
#include <string_view>
#include <thread>  // NOLINT
#include <utility>

#include "absl/log/log.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "g3/macros.h"
#include "tlbmc/redfish/routes/action_managers/file_manager.h"
#include "tlbmc/utils/shell_command_executor.h"
#include "zatar/cert_error_handling.h"
#include "zatar/generate_cert.h"
#include "openssl/asn1.h"
#include "zatar/g3_misc.h"
#include "openssl/bio.h"
#include "openssl/bn.h"
#include "openssl/buffer.h"
#include "openssl/evp.h"
#include "openssl/pem.h"
#include "openssl/rsa.h"
#include "openssl/stack.h"
#include "openssl/x509.h"

namespace milotic_tlbmc {

using ::milotic::authn::GeneratePrivateKey;
using ::milotic::authn::GetSslErrorOnQueue;
using ::milotic::authn::ReturnErrorIfNotSuccess;
using ::milotic::authn::ReturnErrorIfNull;

namespace {
absl::Status AddNameEntry(X509_NAME* name, std::string_view entry,
                          std::string_view value) {
  ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNotSuccess(
      X509_NAME_add_entry_by_txt(
          name, std::string(entry).c_str(), MBSTRING_ASC,
          reinterpret_cast<const unsigned char*>(value.data()), value.size(),
          /*loc=*/-1,
          /*set=*/0),
      absl::StrCat("Failed to add name entry: ", value, "",
                   GetSslErrorOnQueue())));
  return absl::OkStatus();
}
}  // namespace

absl::StatusOr<std::unique_ptr<CredentialManager>> CredentialManager::Create(
    std::string_view private_key_path, std::string_view cert_path,
    std::string_view owner_verification_cert_rwfs_path,
    std::string_view owner_verification_cert_ramfs_path) {
  // Check that private key are non empty strings and are files in the same
  // folder
  if (private_key_path.empty()) {
    return absl::InvalidArgumentError("Private key path is empty");
  }
  if (cert_path.empty()) {
    return absl::InvalidArgumentError("Cert path is empty");
  }

  // Check that the private key and cert are in the same folder
  std::filesystem::path private_key_path_fs(private_key_path);
  std::filesystem::path cert_path_fs(cert_path);
  if (private_key_path_fs.parent_path() != cert_path_fs.parent_path()) {
    return absl::InvalidArgumentError(
        "Private key and cert are not in the same folder");
  }

  if (owner_verification_cert_rwfs_path.empty()) {
    return absl::InvalidArgumentError(
        "Owner verification cert rwfs path is empty");
  }
  if (owner_verification_cert_ramfs_path.empty()) {
    return absl::InvalidArgumentError(
        "Owner verification cert ramfs path is empty");
  }

  return absl::WrapUnique(new CredentialManager(
      private_key_path, cert_path, owner_verification_cert_rwfs_path,
      owner_verification_cert_ramfs_path));
}

CredentialManager::CredentialManager(
    std::string_view private_key_path, std::string_view cert_path,
    std::string_view owner_verification_cert_rwfs_path,
    std::string_view owner_verification_cert_ramfs_path)
    : private_key_path_(private_key_path),
      cert_path_(cert_path),
      owner_verification_cert_rwfs_path_(owner_verification_cert_rwfs_path),
      owner_verification_cert_ramfs_path_(owner_verification_cert_ramfs_path),
      command_executor_(std::make_unique<ShellExecutor>()) {
  // If the write path already exists, then we should read from there.
  absl::StatusOr<std::string> previous_owner_verification_cert =
      FileManager::ReadFile(owner_verification_cert_ramfs_path_);

  if (previous_owner_verification_cert.ok()) {
    LOG(WARNING) << "Owner verification certificate already exists at: "
                 << owner_verification_cert_ramfs_path_
                 << ". Using the existing owner verification certificate.";
    owner_verification_cert_ = std::move(*previous_owner_verification_cert);
    return;
  }

  // Try to read the owner verification certificate from the read path.
  absl::StatusOr<std::string> owner_verification_cert =
      FileManager::ReadFile(owner_verification_cert_rwfs_path_);
  if (owner_verification_cert.ok()) {
    owner_verification_cert_ = *owner_verification_cert;
  } else {
    LOG(ERROR) << "Failed to read owner verification certificate: "
               << owner_verification_cert.status()
               << ". All owner verification certificate validation will fail.";
    owner_verification_cert_ = "";
  }

  absl::Status status = FileManager::WriteToFile(
      owner_verification_cert_, owner_verification_cert_ramfs_path_);
  if (!status.ok()) {
    LOG(ERROR) << "Failed to write owner verification certificate: " << status;
  }
}

absl::StatusOr<std::string> CredentialManager::GenerateCsr(
    const CsrParams& csr_params) {
  // 1. Generate RSA key.
  ECCLESIA_ASSIGN_OR_RETURN(bssl::UniquePtr<EVP_PKEY> pkey,
                            GeneratePrivateKey());
  ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNull(
      pkey.get(),
      absl::StrCat("Failed to generate private key: ", GetSslErrorOnQueue())));

  private_key_ = std::move(pkey);

  // 3. Create X509_REQ.
  bssl::UniquePtr<X509_REQ> x509(X509_REQ_new());
  ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNull(
      x509.get(), absl::StrCat("X509_REQ_new failed: ", GetSslErrorOnQueue())));

  // 4. Set subject name.
  X509_NAME* subject = X509_REQ_get_subject_name(x509.get());
  ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNull(
      subject, absl::StrCat("Failed to get subject name from X509_REQ: ",
                            GetSslErrorOnQueue())));
  ECCLESIA_RETURN_IF_ERROR(AddNameEntry(subject, "C", csr_params.country));
  ECCLESIA_RETURN_IF_ERROR(AddNameEntry(subject, "ST", csr_params.state));
  ECCLESIA_RETURN_IF_ERROR(AddNameEntry(subject, "L", csr_params.city));
  ECCLESIA_RETURN_IF_ERROR(AddNameEntry(subject, "O", csr_params.organization));
  ECCLESIA_RETURN_IF_ERROR(
      AddNameEntry(subject, "OU", csr_params.organizational_unit));
  ECCLESIA_RETURN_IF_ERROR(AddNameEntry(subject, "CN", csr_params.common_name));

  // 5. Add Subject Alternative Names
  if (!csr_params.alternative_names.empty()) {
    std::string san_extension;
    for (int i = 0; i < csr_params.alternative_names.size(); ++i) {
      std::string_view san = csr_params.alternative_names[i];
      // Each SAN needs a DNS: appended to it
      absl::StrAppend(&san_extension, "DNS:", san);

      // Add a comma between each SAN except the last one
      if (i < csr_params.alternative_names.size() - 1) {
        absl::StrAppend(&san_extension, ",");
      }
    }

    bssl::UniquePtr<STACK_OF(X509_EXTENSION)> extensions(
        sk_X509_EXTENSION_new_null());
    bssl::UniquePtr<X509_EXTENSION> san_ext(X509V3_EXT_conf_nid(
        nullptr, nullptr, NID_subject_alt_name, san_extension.c_str()));
    ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNull(
        san_ext.get(), absl::StrCat("Failed to create SAN extension: ",
                                    GetSslErrorOnQueue())));
    ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNotSuccess(
        sk_X509_EXTENSION_push(extensions.get(), san_ext.release()),
        absl::StrCat("Failed to add SAN extension to CSR: ",
                     GetSslErrorOnQueue())));
    ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNotSuccess(
        X509_REQ_add_extensions(x509.get(), extensions.get()),
        absl::StrCat("Failed to add extensions to CSR: ",
                     GetSslErrorOnQueue())));
  }
  // 6. Set public key.
  ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNotSuccess(
      X509_REQ_set_pubkey(x509.get(), private_key_.get()),
      absl::StrCat("Failed to set public key in CSR: ", GetSslErrorOnQueue())));

  // 7. Sign CSR.
  ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNotSuccess(
      X509_REQ_sign(x509.get(), private_key_.get(), EVP_sha256()),
      absl::StrCat("Failed to sign CSR: ", GetSslErrorOnQueue())));

  // 8. Convert CSR to PEM format.
  bssl::UniquePtr<BIO> bio_csr(BIO_new(BIO_s_mem()));
  ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNotSuccess(
      PEM_write_bio_X509_REQ(bio_csr.get(), x509.get()),
      absl::StrCat("Failed to write CSR to BIO: ", GetSslErrorOnQueue())));
  char* csr = nullptr;
  auto csr_len = BIO_get_mem_data(bio_csr.get(), &csr);
  return std::string(csr, csr_len);
}

absl::Status CredentialManager::InstallServerCert(
    std::string_view certificate) {
  // If GenerateCSR has not been called, we cannot install the cert.
  if (private_key_ == nullptr) {
    return absl::InternalError(
        "GenerateCSR must be called before InstallServerCert");
  }

  // 1. Load the certificate from the PEM string
  bssl::UniquePtr<BIO> bio_cert(BIO_new_mem_buf(
      certificate.data(), static_cast<uint32_t>(certificate.length())));
  bssl::UniquePtr<X509> cert(
      PEM_read_bio_X509(bio_cert.get(), nullptr, nullptr, nullptr));
  ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNull(
      cert.get(),
      absl::StrCat("Failed to parse certificate PEM: ", GetSslErrorOnQueue())));

  ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNotSuccess(
      X509_check_private_key(cert.get(), private_key_.get()),
      "Certificate does not match the private key"));

  bssl::UniquePtr<BIO> bio_privkey(BIO_new(BIO_s_mem()));
  ECCLESIA_RETURN_IF_ERROR(ReturnErrorIfNotSuccess(
      PEM_write_bio_PrivateKey(bio_privkey.get(), private_key_.get(), nullptr,
                               nullptr, 0, nullptr, nullptr),
      absl::StrCat("PEM_write_bio_PrivateKey failed: ", GetSslErrorOnQueue())));

  char* private_key = nullptr;
  auto private_key_len = BIO_get_mem_data(bio_privkey.get(), &private_key);
  std::string private_key_pem(private_key, private_key_len);

  // Install the cert and key on the machine.
  // We must do directory name change here as the key and cert have to both be
  // changed atomically
  std::string credential_dir = std::filesystem::path(cert_path_).parent_path();
  std::string cert_filename = std::filesystem::path(cert_path_).filename();
  std::string private_key_filename =
      std::filesystem::path(private_key_path_).filename();

  // Write to a temp dir
  std::string temp_credential_dir = absl::StrCat(credential_dir, "-tmp");
  ECCLESIA_RETURN_IF_ERROR(FileManager::WriteToFile(
      certificate, absl::StrCat(temp_credential_dir, "/", cert_filename)));
  ECCLESIA_RETURN_IF_ERROR(FileManager::WriteToFile(
      private_key_pem,
      absl::StrCat(temp_credential_dir, "/", private_key_filename)));

  // Atomically change both key and cert
  ECCLESIA_RETURN_IF_ERROR(
      FileManager::RenamePath(temp_credential_dir, credential_dir, true));

  std::thread([this]() {
    absl::SleepFor(absl::Seconds(kServerCertRestartDelaySeconds));
    absl::StatusOr<std::string> status =
        command_executor_->Execute(std::string(kRestartBmcWebCommand));
    if (!status.ok()) {
      LOG(ERROR) << "Failed to restart bmcweb: " << status.status();
    }
    if (restart_bmcweb_callback_ != nullptr) {
      restart_bmcweb_callback_(status.status());
    }
  }).detach();

  return absl::OkStatus();
}

}  // namespace milotic_tlbmc
