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

#include "absl/cleanup/cleanup.h"
#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"

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

// A simple implementation of File::TempFile that creates a temporary file with
// the given content and name template. The file will be deleted when the object
// is destroyed.
absl::StatusOr<StagedTempFile> StagedTempFile::Create(
    absl::string_view content, absl::string_view temp_name_template) {
  std::vector<char> tmpname(temp_name_template.begin(),
                            temp_name_template.end());
  tmpname.push_back('\0');
  int fd = mkstemp(&tmpname[0]);
  if (fd == -1) {
    return absl::InternalError("Failed creating staged temp file");
  }

  absl::Cleanup file_unlink = [&] { unlink(&tmpname[0]); };
  absl::Cleanup closefd = [&] { close(fd); };

  ssize_t bytes_written = write(fd, content.data(), content.size());
  if (bytes_written < 0 ||
      static_cast<size_t>(bytes_written) != content.size()) {
    return absl::InternalError("Failed writing staged temp file");
  }
  // successfully create the temp file, the staged temp file will be kept so
  // cancel unlink cleanup.
  std::move(file_unlink).Cancel();
  return StagedTempFile(&tmpname[0]);
}

StagedTempFile::~StagedTempFile() {
  if (!path_.empty()) {
    unlink(path_.c_str());
  }
}

StagedTempFile::StagedTempFile(StagedTempFile&& other) noexcept
    : path_(std::move(other.path_)) {
  other.path_.clear();
}

StagedTempFile& StagedTempFile::operator=(StagedTempFile&& other) noexcept {
  if (this != &other) {
    if (!path_.empty()) {
      unlink(path_.c_str());
    }
    path_ = std::move(other.path_);
    other.path_.clear();
  }
  return *this;
}

StagedTempFile::StagedTempFile(absl::string_view path) : path_(path) {}

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
