#include "install/installer.h"

#include <sys/wait.h>
#include <unistd.h>

#include <algorithm>
#include <cmath>
#include <cstddef>
#include <filesystem>  // NOLINT
#include <fstream>
#include <ios>
#include <sstream>
#include <string>
#include <system_error>  // NOLINT
#include <vector>

#include "owner_certificate/owner_verification_cert_configuration.pb.h"
#include "absl/cleanup/cleanup.h"
#include "absl/container/flat_hash_set.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "nlohmann/json.hpp"
#include "google/protobuf/text_format.h"

namespace bloom_install {

using ::bloom_install::internal::StatusReporter;

// LINT.IfChange
constexpr char kStatusKeyStatus[] = "status";
constexpr char kStatusKeyPercentComplete[] = "percent_complete";
constexpr char kStatusKeyMessage[] = "message";
constexpr char kStatusKeyStartTime[] = "start_time";
constexpr char kStatusKeyLastUpdateTime[] = "last_update_time";
// LINT.ThenChange(//depot/google3/third_party/milotic/external/cc/tlbmc/redfish/routes/task_service.cc)

ProgressLogger::ProgressLogger(const std::string& log_file_path)
    : log_file_path_(log_file_path),
      log_file_(log_file_path_, std::ios_base::app),
      is_healthy_(log_file_.is_open()) {}

bool ProgressLogger::IsHealthy() const { return is_healthy_; }

void ProgressLogger::Log(State state, absl::Duration elapsed_time,
                         const std::string& message, LogCode code,
                         int retries) {
  if (!is_healthy_) {
    return;
  }

  nlohmann::json log_entry;
  log_entry["state"] = StateToString(state);
  log_entry["time"] = absl::ToDoubleSeconds(elapsed_time);
  log_entry["message"] = message;
  log_entry["code"] = LogCodeToString(code);

  if (state == State::kFailureRetry) {
    log_entry["retries"] = retries;
  }

  // TODO(nanzhou): Remove dump. It's not very useful as we have separate
  // journal logs. I kept them because of the test was checking the files.
  const std::string log_str = log_entry.dump();
  log_file_ << log_str << "\n";
  LOG(INFO) << log_str;
  log_file_.flush();
}

namespace internal {

StatusReporter StatusReporter::Create(const std::string& status_path,
                                      int total_packages) {
  return StatusReporter(status_path, total_packages);
}

StatusReporter::StatusReporter(const std::string& status_path,
                               int total_packages)
    : status_path_(status_path), total_packages_(std::max(total_packages, 1)) {}

void StatusReporter::Start(const std::string& message) {
  status_json_[kStatusKeyStatus] = "New";
  status_json_[kStatusKeyPercentComplete] = 0;
  status_json_[kStatusKeyMessage] = message;
  const std::string now_str = absl::FormatTime(absl::Now());
  status_json_[kStatusKeyStartTime] = now_str;
  status_json_[kStatusKeyLastUpdateTime] = now_str;
  WriteStatus();
}

void StatusReporter::RecordSuccess(const std::string& message) {
  if (packages_completed_ < total_packages_) {
    packages_completed_++;
  }
  UpdateProgress(message);
}

void StatusReporter::UpdateProgress(const std::string& message) {
  status_json_[kStatusKeyPercentComplete] =
      std::round((packages_completed_ * 100.0) / total_packages_);
  status_json_[kStatusKeyMessage] = message;
  status_json_[kStatusKeyLastUpdateTime] = absl::FormatTime(absl::Now());
  WriteStatus();
}

void StatusReporter::Complete(bool success, const std::string& message) {
  status_json_[kStatusKeyStatus] = success ? "Completed" : "Exception";
  if (success) {
    status_json_[kStatusKeyPercentComplete] = 100;
  }
  status_json_[kStatusKeyMessage] = message;
  status_json_[kStatusKeyLastUpdateTime] = absl::FormatTime(absl::Now());
  WriteStatus();
}

void StatusReporter::WriteStatus() {
  const std::string temp_path = status_path_ + ".tmp";
  {
    std::ofstream temp_file(temp_path);
    if (!temp_file.is_open()) {
      return;
    }
    temp_file << status_json_.dump(4);
  }

  std::error_code ec;
  if (std::filesystem::rename(temp_path, status_path_, ec); ec) {
    std::filesystem::remove(temp_path);
  }
}

// Helper to get the set of files listed in the manifest.
absl::flat_hash_set<std::string> GetManifestFiles(
    const std::string& sha256sums_file_path) {
  absl::flat_hash_set<std::string> manifest_files;
  std::ifstream sums_file(sha256sums_file_path);
  if (!sums_file.is_open()) {
    LOG(ERROR) << "Could not open manifest file: " << sha256sums_file_path;
    return manifest_files;
  }

  std::string line;
  while (std::getline(sums_file, line)) {
    // sha256sum format is: <hash> <mode><file_path>
    // mode is ' ' for text and '*' for binary.
    size_t first_space = line.find(' ');
    if (first_space == std::string::npos || first_space + 2 > line.length()) {
      continue;
    }

    absl::string_view path(line);
    // Remove the hash, the space and the 1-character mode flag (* or [space]).
    path.remove_prefix(first_space + 2);
    manifest_files.insert(
        std::filesystem::path(path).lexically_normal().string());
  }
  return manifest_files;
}

// Returns true if the directory entry represents a valid package.
// A valid package must be a directory containing both post_install.sh and
// activation_check.sh, and both files must be present in the manifest.
bool IsPackageValid(const std::string& package_path_str,
                    const absl::flat_hash_set<std::string>& manifest_files) {
  std::error_code ec;
  std::filesystem::path package_path(package_path_str);
  if (!std::filesystem::is_directory(package_path, ec)) {
    return false;
  }

  if (!std::filesystem::exists(package_path / "post_install.sh", ec) ||
      !std::filesystem::exists(package_path / "activation_check.sh", ec)) {
    return false;
  }

  std::string post_install_path = (std::filesystem::path("firmware_bundle") /
                                   package_path.filename() / "post_install.sh")
                                      .string();
  std::string activation_check_path =
      (std::filesystem::path("firmware_bundle") / package_path.filename() /
       "activation_check.sh")
          .string();
  return manifest_files.contains(post_install_path) &&
         manifest_files.contains(activation_check_path);
}

}  // namespace internal

Installer::Installer(const InstallerOptions& options)
    : options_(options),
      logger_(options.log_path),
      status_reporter_(StatusReporter::Create(
          options.status_path, static_cast<int>(options.packages.size()))) {
  if (options.packages.empty()) {
    LOG(WARNING) << "No packages to install. Post install or activation "
                    "check will succeed with no-op.";
  }
}

// Helper function to verify a detached signature using OpenSSL.
bool Installer::VerifyDetachedSignature(const std::string& file_to_verify,
                                        const std::string& signature_file,
                                        const std::string& public_key_file) {
  absl::Time check_start_time = absl::Now();

  std::vector<std::string> args = {
      "openssl",       "dgst",       "-sha256",      "-verify",
      public_key_file, "-signature", signature_file, file_to_verify};
  int result = ExecuteCommand(args);
  if (result != 0) {
    const std::string error_msg = absl::Substitute(
        "Detached signature verification failed for $0 with exit code: $1",
        file_to_verify, result);
    logger_.Log(State::kFailureFatal, absl::Now() - check_start_time, error_msg,
                LogCode::kBundleSignatureFail);
    return false;
  }
  const std::string success_msg = absl::Substitute(
      "Successfully verified detached signature for $0", file_to_verify);
  logger_.Log(State::kSuccess, absl::Now() - check_start_time, success_msg,
              LogCode::kBundleSignatureSuccess);
  return true;
}

bool Installer::CheckBundleSignature(const std::string& sha256sums_file_path,
                                     const std::string& signature_file_path,
                                     const std::string& public_key_path) {
  absl::Time check_start_time = absl::Now();

  const std::string start_msg = "Starting bundle signature check";
  logger_.Log(State::kCheckingBundleSignature, absl::ZeroDuration(), start_msg,
              LogCode::kBundleSignatureCheckStart);
  status_reporter_.Start(start_msg);

  // First, verify signature over the sums file
  if (!VerifyDetachedSignature(sha256sums_file_path, signature_file_path,
                               public_key_path)) {
    const std::string error_msg = "Detached signature verification failed.";
    logger_.Log(State::kFailureFatal, absl::Now() - check_start_time, error_msg,
                LogCode::kBundleSignatureFail);
    status_reporter_.Complete(false, error_msg);
    return false;
  }

  // Now verify that file hashes match the sums file
  std::filesystem::path sums_file_parent_path =
      std::filesystem::path(sha256sums_file_path).parent_path();
  std::vector<std::string> args = {"sha256sum", "-c", sha256sums_file_path};
  int result = ExecuteCommand(args, sums_file_parent_path.string());
  if (result != 0) {
    const std::string error_msg = absl::Substitute(
        "Bundle file hash verification failed for command 'sha256sum -c $0'. "
        "Exit code: $1",
        sha256sums_file_path, result);
    logger_.Log(State::kFailureFatal, absl::Now() - check_start_time, error_msg,
                LogCode::kBundleHashFail);
    status_reporter_.Complete(false, error_msg);
    return false;
  }

  const std::string success_msg = "Bundle signature check successful.";
  logger_.Log(State::kSuccess, absl::Now() - check_start_time, success_msg,
              LogCode::kBundleSignatureSuccess);
  status_reporter_.Complete(true, success_msg);
  return true;
}

absl::StatusOr<owner_certificate::OwnerVerificationCertConfiguration>
Installer::GetOwnerConfiguration(const std::string& config_file_path) {
  absl::Time start_time = absl::Now();
  const std::string start_msg = absl::Substitute(
      "Starting to retrieve owner configuration from $0", config_file_path);
  logger_.Log(State::kGettingOwnerConfiguration, absl::ZeroDuration(),
              start_msg, LogCode::kGetOwnerConfigStart);

  std::ifstream config_file(config_file_path);
  if (!config_file.is_open()) {
    std::string msg = absl::Substitute(
        "Could not open owner configuration file: $0", config_file_path);
    LOG(ERROR) << msg;
    logger_.Log(State::kFailureFatal, absl::Now() - start_time, msg,
                LogCode::kGetOwnerConfigFail);
    status_reporter_.Complete(false, msg);
    return absl::NotFoundError(msg);
  }

  std::stringstream buffer;
  buffer << config_file.rdbuf();
  if (config_file.bad()) {
    std::string msg = absl::Substitute(
        "Failed to read owner configuration file from $0", config_file_path);
    LOG(ERROR) << msg;
    logger_.Log(State::kFailureFatal, absl::Now() - start_time, msg,
                LogCode::kGetOwnerConfigFail);
    status_reporter_.Complete(false, msg);
    return absl::InternalError(msg);
  }

  std::string config_str = buffer.str();
  if (absl::StripAsciiWhitespace(config_str).empty()) {
    std::string msg = absl::Substitute(
        "Owner configuration file $0 is empty or contains only whitespace.",
        config_file_path);
    LOG(ERROR) << msg;
    logger_.Log(State::kFailureFatal, absl::Now() - start_time, msg,
                LogCode::kGetOwnerConfigFail);
    status_reporter_.Complete(false, msg);
    return absl::InternalError(msg);
  }

  owner_certificate::OwnerVerificationCertConfiguration config;
  // TODO(b/489183188): Remove this temporary default once all test machines
  // have the field deployed.
  config.set_bundle_dev_verification_enabled(true);
  if (!::google::protobuf::TextFormat::MergeFromString(config_str, &config)) {
    std::string msg =
        absl::Substitute("Failed to parse $0 as a textproto", config_file_path);
    LOG(ERROR) << msg;
    logger_.Log(State::kFailureFatal, absl::Now() - start_time, msg,
                LogCode::kGetOwnerConfigFail);
    status_reporter_.Complete(false, msg);
    return absl::InvalidArgumentError(msg);
  }

  const std::string success_msg = "Successfully retrieved owner configuration";
  logger_.Log(State::kSuccess, absl::Now() - start_time, success_msg,
              LogCode::kGetOwnerConfigSuccess);
  status_reporter_.Complete(true, success_msg);
  return config;
}

bool Installer::PostInstall() {
  absl::Time total_start_time = absl::Now();

  if (options_.packages.empty()) {
    const std::string complete_msg =
        "No packages to install. Process complete.";
    logger_.Log(State::kSuccess, absl::Now() - total_start_time, complete_msg,
                LogCode::kInstallComplete);
    return true;
  }

  const std::string start_msg = "Starting installation process.";
  logger_.Log(State::kStarting, absl::ZeroDuration(), start_msg,
              LogCode::kInitStart);
  status_reporter_.Start(start_msg);

  int packages_completed_for_logging = 0;
  for (const auto& package : options_.packages) {
    if (!InstallPackage(package)) {
      const std::string failure_msg =
          absl::Substitute("Installation failed on package: $0", package.name);
      absl::Duration elapsed = absl::Now() - total_start_time;
      logger_.Log(
          State::kFailureFatal, elapsed,
          absl::Substitute("Installation halted due to failure in package: $0",
                           package.name),
          LogCode::kInstallHalt);
      status_reporter_.Complete(false, failure_msg);
      return false;
    }
    // Persist the activation scripts togather with other scripts to the
    // activation check directory.
    std::filesystem::path activation_package_dir =
        options_.activation_check_dir;
    activation_package_dir /= package.name;
    std::error_code ec;
    if (std::filesystem::create_directories(activation_package_dir, ec); ec) {
      const std::string failure_msg = absl::Substitute(
          "Could not create activation check script directory: $0 with error: "
          "$1",
          activation_package_dir.c_str(), ec.message());
      logger_.Log(State::kFailureFatal, absl::Now() - total_start_time,
                  failure_msg, LogCode::kInstallHalt);
      status_reporter_.Complete(false, failure_msg);
      return false;
    }

    const std::filesystem::path package_dir =
        std::filesystem::path(package.activation_script_path).parent_path();
    ec.clear();

    for (auto it = std::filesystem::directory_iterator(package_dir, ec);
         it != std::filesystem::directory_iterator(); it.increment(ec)) {
      if (ec) {
        break;
      }
      std::filesystem::directory_entry file_entry = *it;
      if (!file_entry.is_regular_file()) {
        continue;
      }

      if (file_entry.path().extension() == ".sh" ||
          file_entry.path().filename() == "VERSION") {
        std::filesystem::path dest_path = activation_package_dir;
        dest_path /= file_entry.path().filename();
        std::error_code copy_ec;
        if (std::filesystem::copy(
                file_entry.path(), dest_path,
                std::filesystem::copy_options::overwrite_existing, copy_ec);
            copy_ec) {
          const std::string failure_msg = absl::Substitute(
              "Could not copy file: $0 to: $1 with error: $2",
              file_entry.path().c_str(), dest_path.c_str(), copy_ec.message());
          logger_.Log(State::kFailureFatal, absl::Now() - total_start_time,
                      failure_msg, LogCode::kInstallHalt);
          status_reporter_.Complete(false, failure_msg);
          return false;
        }
      }
    }

    packages_completed_for_logging++;
    const std::string progress_msg = absl::Substitute(
        "Successfully completed package $0 ($1 of $2).", package.name,
        packages_completed_for_logging, options_.packages.size());
    status_reporter_.RecordSuccess(progress_msg);
  }

  const std::string success_msg = "All packages installed successfully.";
  absl::Duration elapsed = absl::Now() - total_start_time;
  logger_.Log(State::kSuccess, elapsed, success_msg, LogCode::kInstallComplete);
  status_reporter_.Complete(true, success_msg);
  return true;
}

bool Installer::InstallPackage(const Package& package) {
  absl::Time check_start_time = absl::Now();
  logger_.Log(
      State::kCheckingActivation, absl::ZeroDuration(),
      absl::Substitute("Checking activation for package: $0", package.name),
      LogCode::kPkgActivationCheckStart);

  int activation_return_code = ExecuteCommand(package.activation_script_path);
  absl::Duration check_elapsed = absl::Now() - check_start_time;

  if (activation_return_code == 0) {
    logger_.Log(
        State::kSkipped, check_elapsed,
        absl::Substitute("Package already active, skipping installation: $0",
                         package.name),
        LogCode::kPkgActivationSkip);
    return true;
  }

  logger_.Log(State::kInstalling, absl::ZeroDuration(),
              absl::Substitute(
                  "Package not active, proceeding with installation for: $0",
                  package.name),
              LogCode::kPkgInstallProceed);

  for (int attempt = 0; attempt <= options_.max_retries; ++attempt) {
    absl::Time attempt_start_time = absl::Now();
    logger_.Log(
        State::kInstalling, absl::ZeroDuration(),
        absl::Substitute("Attempting to install package: $0", package.name),
        LogCode::kPkgInstallStart);
    int return_code = ExecuteCommand(package.install_script_path);
    absl::Duration elapsed = absl::Now() - attempt_start_time;

    if (return_code == 0) {
      logger_.Log(
          State::kSuccess, elapsed,
          absl::Substitute("Successfully installed package: $0", package.name),
          LogCode::kPkgInstallSuccess);
      return true;
    }

    if (attempt < options_.max_retries) {
      logger_.Log(State::kFailureRetry, elapsed,
                  absl::Substitute("Failed to install package: $0. Retrying.",
                                   package.name),
                  LogCode::kPkgInstallFailRetry, attempt + 1);
      absl::SleepFor(absl::Seconds(2));
    } else {
      logger_.Log(
          State::kFailureFatal, elapsed,
          absl::Substitute("Fatal error installing package: $0", package.name),
          LogCode::kPkgInstallFailFatal);
      return false;
    }
  }
  return false;
}

void Installer::ActivationCheck() {
  for (const auto& package : options_.packages) {
    // Ignore the return code of the activation script so that all packages are
    // checked.
    ExecuteCommand(package.activation_script_path);
  }
}

int Installer::ExecuteCommand(const std::vector<std::string>& args,
                              const std::string& working_dir) {
  if (args.empty()) {
    return -1;
  }

  pid_t pid = fork();
  if (pid == -1) {
    return -1;
  }

  if (pid == 0) {
    // Child process
    if (!working_dir.empty()) {
      if (chdir(working_dir.c_str()) != 0) {
        // Exit with 127 to mimic std::system behavior.
        // Use _exit() to avoid libc process cleanup behavior.
        _exit(127);
      }
    }

    std::vector<char*> argv;
    argv.reserve(args.size() + 1);
    for (const auto& arg : args) {
      argv.push_back(const_cast<char*>(arg.c_str()));
    }
    argv.push_back(nullptr);

    execvp(argv[0], argv.data());
    // execvp() should not return on success. If it returns, exit child with
    // 127 to mimic std::system behavior.
    // Use _exit() to avoid libc process cleanup behavior..
    _exit(127);
  }

  // Parent process
  int status;
  if (waitpid(pid, &status, 0) == -1) {
    return -1;
  }

  if (WIFEXITED(status)) {
    return WEXITSTATUS(status);
  }
  return -1;
}

int Installer::ExecuteCommand(const std::string& command,
                              const std::string& working_dir) {
  return ExecuteCommand(absl::StrSplit(command, ' ', absl::SkipWhitespace()),
                        working_dir);
}

int ActivationMain(const std::string& activation_check_dir) {
  std::vector<Package> packages;
  std::error_code ec;
  for (const auto& entry :
       std::filesystem::directory_iterator(activation_check_dir, ec)) {
    if (!ec && entry.is_directory() &&
        std::filesystem::exists(entry.path() / "activation_check.sh")) {
      Package package;
      package.name = entry.path().filename().string();
      package.activation_script_path = entry.path() / "activation_check.sh";
      packages.push_back(package);
    }
  }
  InstallerOptions options;
  options.packages = packages;
  Installer installer(options);
  installer.ActivationCheck();
  LOG(INFO) << "Activation check completed successfully.";
  return 0;
}

int SignatureCheckMain(const std::string& bundle_tar_file_path,
                       const std::string& public_key_path) {
  InstallerOptions options;
  Installer installer(options);
  std::filesystem::path sha256sums_file = bundle_tar_file_path;
  sha256sums_file.remove_filename();
  sha256sums_file /= "bundle_files.SHA256SUM";

  std::filesystem::path signature_file = sha256sums_file.string() + ".sig";
  if (!installer.CheckBundleSignature(
          sha256sums_file.string(), signature_file.string(), public_key_path)) {
    LOG(ERROR) << "Bundle signature check failed";
    return 1;  // Exit if signature verification fails
  }
  LOG(INFO) << "Bundle signature check successful.";
  return 0;
}

std::vector<Package> ParsePostInstallPackages(
    const std::string& tar_file_path, const std::string& sha256sums_file_path) {
  std::vector<Package> packages;
  std::filesystem::path untar_dir = tar_file_path;
  untar_dir.remove_filename();
  untar_dir /= "firmware_bundle";
  LOG(INFO) << "Firmware bundle directory: " << untar_dir;

  absl::flat_hash_set<std::string> manifest_files =
      internal::GetManifestFiles(sha256sums_file_path);

  std::error_code ec;
  for (const auto& entry : std::filesystem::directory_iterator(untar_dir, ec)) {
    if (!ec &&
        internal::IsPackageValid(entry.path().string(), manifest_files)) {
      LOG(INFO) << "Found package: " << entry.path().filename().string();
      Package package;
      package.name = entry.path().filename().string();
      package.activation_script_path = entry.path() / "activation_check.sh";
      package.install_script_path = entry.path() / "post_install.sh";
      packages.push_back(package);
    } else if (!ec) {
      LOG(INFO) << "Not a valid package or missing from the manifest: "
                << entry.path().filename().string();
    }
  }
  return packages;
}

int PostInstallMain(const std::string& inventory_dir,
                    const std::string& install_lock_file_path,
                    const std::string& bundle_tar_file_path,
                    const std::string& activation_check_dir) {
  InstallerOptions options;
  // Check if an installation is already running.
  std::filesystem::path install_lock_file = install_lock_file_path;
  if (std::error_code ec; std::filesystem::exists(install_lock_file, ec)) {
    LOG(ERROR) << "Installation is already in progress. Lock file found: "
               << install_lock_file;
    return 1;
  }
  std::error_code ec;
  if (std::filesystem::create_directories(inventory_dir, ec); ec) {
    LOG(ERROR) << "Error: Could not create installation directory: "
               << inventory_dir << " with error: " << ec.message();
    return 1;
  }
  ec.clear();
  if (std::filesystem::create_directories(install_lock_file.parent_path(), ec);
      ec) {
    LOG(ERROR) << "Error: Could not create installation lock file directory: "
               << install_lock_file.parent_path()
               << " with error: " << ec.message();
    return 1;
  }

  // Create the installation lock file to signal that an install is starting.
  std::ofstream lock_file_stream(install_lock_file);
  if (!lock_file_stream) {
    LOG(ERROR) << "Error: Could not create lock file: " << install_lock_file
               << " with error: " << lock_file_stream.rdstate();
    return 1;
  }
  absl::Cleanup lock_file_cleanup = [install_lock_file] {
    std::error_code ec;
    if (std::filesystem::remove(install_lock_file, ec); ec) {
      LOG(ERROR) << "Error: Could not remove lock file: " << install_lock_file;
    }
    LOG(INFO) << "Successfully removed lock file: " << install_lock_file;
  };
  LOG(INFO) << "Successfully created lock file: " << install_lock_file;

  // Now run install
  std::filesystem::path sha256sums_file = bundle_tar_file_path;
  sha256sums_file.remove_filename();
  sha256sums_file /= "bundle_files.SHA256SUM";

  std::vector<Package> packages_to_install =
      ParsePostInstallPackages(bundle_tar_file_path, sha256sums_file.string());

  options.packages = packages_to_install;
  options.max_retries = 2;
  std::filesystem::path log_path = inventory_dir;
  log_path.remove_filename();
  log_path /= "progress_internal.log";
  options.log_path = log_path.c_str();
  options.activation_check_dir = activation_check_dir;

  Installer installer(options);
  LOG(INFO) << "Starting installation process...";

  if (!installer.PostInstall()) {
    LOG(ERROR) << "Post install failed. Check log at " << log_path
               << " for details.";
    return 1;
  }

  LOG(INFO) << "Post install completed successfully.";
  return 0;
}

int CheckDevKeysEnabledMain(const std::string& config_file_path) {
  InstallerOptions options;
  Installer installer(options);
  absl::StatusOr<owner_certificate::OwnerVerificationCertConfiguration> status =
      installer.GetOwnerConfiguration(config_file_path);
  if (!status.ok()) {
    LOG(ERROR) << "Failed to get owner configuration: " << status.status();
    LOG(ERROR) << "Dev verification keys use will be disabled by default.";
    return kDevKeysError;
  }

  owner_certificate::OwnerVerificationCertConfiguration config = status.value();
  if (config.bundle_dev_verification_enabled()) {
    LOG(INFO) << "Dev verification keys are enabled via " << config_file_path;
    return kDevKeysEnabled;
  }

  LOG(INFO) << "Dev verification keys are explicitly disabled in "
            << config_file_path;
  return kDevKeysDisabled;
}

}  // namespace bloom_install
