#include "tlbmc/redfish/routes/action_managers/trust_bundle_manager.h"

#include <cstdlib>
#include <filesystem>  // NOLINT
#include <fstream>
#include <iterator>
#include <string>
#include <system_error>  // NOLINT
#include <thread>        // NOLINT
#include <utility>

#include "absl/functional/any_invocable.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "g3/macros.h"
#include "tlbmc/redfish/routes/action_managers/file_manager.h"

namespace milotic_tlbmc::certificate_service {
namespace {

constexpr absl::string_view kTempTrustBundlePath = "/tmp/trust_bundle_XXXXXX";
constexpr absl::string_view kTempSignaturePath = "/tmp/signature_XXXXXX";
constexpr absl::string_view kTempOutputFile = "/tmp/openssl_output_XXXXXX";
constexpr absl::string_view kBloomCaCertPath =
    "/var/google/ca-store/bloom-ca.crt";

// The command to verify the trust bundle signature and verify the signer
// certificate with the CA file to make sure the signer is trusted.
constexpr absl::string_view kTrustBundleVerifyWithCaCommand =
    "openssl smime -verify -binary -inform PEM -in '%s' -content '%s' "
    "-CApath '%s' -purpose any -out /dev/null 2> '%s'";

// The command to verify the trust bundle signature without the CA file. Just
// blindly trust the signer certificate bundle in the PKCS#7 signature.
constexpr absl::string_view kTrustBundleVerifyNoCaCommand =
    "openssl smime -verify -binary -inform PEM -in '%s' -content '%s' "
    "-noverify -purpose any -out /dev/null 2> '%s'";

// The command to install the trust bundle and restart bmcweb. The command will
// be executed in a subprocess. And the subprocess will get SIGTERM as bmcweb
// service kill mode is group. Here as we use --no-block, it is fine that
// the restart command get terminated, it is still better to trap the SIGTERM.
constexpr absl::string_view kInstallAndRestartBmcWebCommand =
    "trap '' TERM; mv %s %s && /usr/bin/systemctl restart --no-block bmcweb";

// The path to the trust bundle file.
constexpr absl::string_view kTrustBundlePath =
    "/var/google/trust_bundle/trust_bundle.pem";

}  // namespace

void TrustBundleManager::SetCaller(
    absl::AnyInvocable<int(const char*) const>&& caller) {
  system_caller_ = std::move(caller);
}

absl::Status TrustBundleManager::RestartGrpcServer(
    absl::string_view staged_temp_file_path) {
  if (staged_temp_file_path.empty()) {
    return absl::InvalidArgumentError("Staged temp file path is empty.");
  }

  int result =
      system_caller_(absl::StrFormat(kInstallAndRestartBmcWebCommand,
                                     staged_temp_file_path, kTrustBundlePath)
                         .c_str());
  if (result != 0) {
    return absl::InternalError(
        "Issuing restart command failed. The installed trust bundle will "
        "be applied in next restart.");
  }
  return absl::OkStatus();
}

absl::StatusOr<StagedTempFile> TrustBundleManager::VerifyAndStageTrustBundle(
    absl::string_view trust_bundle, absl::string_view signature,
    absl::string_view ca_file_path) {
  ECCLESIA_ASSIGN_OR_RETURN(
      StagedTempFile trust_bundle_file,
      StagedTempFile::Create(trust_bundle, kTempTrustBundlePath));
  ECCLESIA_ASSIGN_OR_RETURN(
      StagedTempFile signature_file,
      StagedTempFile::Create(signature, kTempSignaturePath));
  ECCLESIA_ASSIGN_OR_RETURN(StagedTempFile output_file,
                            StagedTempFile::Create("", kTempOutputFile));

  std::string command;
  std::error_code ec;
  if (std::filesystem::exists(ca_file_path, ec)) {
    command = absl::StrFormat(
        kTrustBundleVerifyWithCaCommand, signature_file.path(),
        trust_bundle_file.path(),
        std::filesystem::path(std::string(ca_file_path)).parent_path().string(),
        output_file.path());
  } else {
    command =
        absl::StrFormat(kTrustBundleVerifyNoCaCommand, signature_file.path(),
                        trust_bundle_file.path(), output_file.path());
  }

  int result = std::system(command.c_str());
  std::string output;
  if (std::filesystem::exists(output_file.path(), ec)) {
    std::ifstream ifs(output_file.path());
    if (ifs) {
      output.assign((std::istreambuf_iterator<char>(ifs)),
                    (std::istreambuf_iterator<char>()));
    }
  }
  LOG(WARNING) << "Trust bundle verify result: " << output;
  if (result != 0) {
    return absl::InvalidArgumentError(
        absl::StrFormat("Failed to verify trust bundle signature. %s", output));
  }
  return trust_bundle_file;
}

absl::Status TrustBundleManager::InstallTrustBundle(
    absl::string_view trust_bundle, absl::string_view signature) {
  absl::MutexLock lock(mutex_);
  if (last_install_time_ != absl::InfinitePast() &&
      absl::Now() - last_install_time_ <
          absl::Seconds(kTrustBundleRetryDelaySeconds)) {
    std::string error_message = absl::StrFormat(
        "A trust bundle, installed at %s, is pending to be applied at %s. "
        "Retry after %s.",
        absl::FormatTime(last_install_time_),
        absl::FormatTime(last_install_time_ +
                         absl::Seconds(kTrustBundleRestartDelaySeconds)),
        absl::FormatTime(last_install_time_ +
                         absl::Seconds(kTrustBundleRetryDelaySeconds)));
    LOG(ERROR) << error_message;
    return absl::UnavailableError(error_message);
  }

#ifdef BLOOM_CA_CERT_PATH
  absl::string_view ca_file_path = BLOOM_CA_CERT_PATH;
#else
  absl::string_view ca_file_path = kBloomCaCertPath;
#endif
  ECCLESIA_ASSIGN_OR_RETURN(
      StagedTempFile staged_trust_bundle,
      VerifyAndStageTrustBundle(trust_bundle, signature, ca_file_path));

  last_install_time_ = absl::Now();

  std::thread([this, staged_temp_file = std::move(staged_trust_bundle)]() {
    absl::SleepFor(absl::Seconds(kTrustBundleRestartDelaySeconds));
    absl::Status status = RestartGrpcServer(staged_temp_file.path());
    if (!status.ok()) {
      LOG(ERROR) << status;
    }
  }).detach();

  return absl::OkStatus();
}

}  // namespace milotic_tlbmc::certificate_service
