// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/updater/installer.h"  // NOLINT(build/include)

#include <utility>

#include "base/callback.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "chrome/updater/updater_constants.h"
#include "chrome/updater/util.h"
#include "components/crx_file/crx_verifier.h"
#include "components/update_client/update_client_errors.h"
#include "components/update_client/utils.h"

namespace updater {

namespace {

// Version "0" corresponds to no installed version.
const char kNullVersion[] = "0.0.0.0";

// Returns the full path to the installation directory for the application
// identified by the |crx_id|.
base::FilePath GetAppInstallDir(const std::string& crx_id) {
  base::FilePath app_install_dir;
  if (CreateProductDirectory(&app_install_dir)) {
    app_install_dir = app_install_dir.AppendASCII(kAppsDir);
    app_install_dir = app_install_dir.AppendASCII(crx_id);
  }
  return app_install_dir;
}

}  // namespace

Installer::InstallInfo::InstallInfo() : version(kNullVersion) {}
Installer::InstallInfo::~InstallInfo() = default;

Installer::Installer(const std::vector<uint8_t>& pk_hash)
    : pk_hash_(pk_hash),
      crx_id_(update_client::GetCrxIdFromPublicKeyHash(pk_hash)),
      install_info_(std::make_unique<InstallInfo>()) {}

Installer::~Installer() = default;

update_client::CrxComponent Installer::MakeCrxComponent() {
  update_client::CrxComponent component;
  component.installer = scoped_refptr<Installer>(this);
  component.requires_network_encryption = false;
  component.crx_format_requirement =
      crx_file::VerifierFormat::CRX3_WITH_PUBLISHER_PROOF;
  component.pk_hash = pk_hash_;
  component.name = crx_id_;
  component.version = install_info_->version;
  component.fingerprint = install_info_->fingerprint;
  return component;
}

void Installer::FindInstallOfApp() {
  VLOG(1) << __func__ << " for " << crx_id_;

  const base::FilePath app_install_dir = GetAppInstallDir(crx_id_);
  if (app_install_dir.empty() || !base::PathExists(app_install_dir)) {
    install_info_ = std::make_unique<InstallInfo>();
    return;
  }

  base::Version latest_version(kNullVersion);
  base::FilePath latest_path;
  std::vector<base::FilePath> older_paths;
  base::FileEnumerator file_enumerator(app_install_dir, false,
                                       base::FileEnumerator::DIRECTORIES);
  for (auto path = file_enumerator.Next(); !path.value().empty();
       path = file_enumerator.Next()) {
    const base::Version version(path.BaseName().MaybeAsASCII());

    // Ignore folders that don't have valid version names.
    if (!version.IsValid()) continue;

    // The |version| not newer than the latest found version is marked for
    // removal. |kNullVersion| is also removed.
    if (version.CompareTo(latest_version) <= 0) {
      older_paths.push_back(path);
      continue;
    }

    // New valid |version| folder found.
    if (!latest_path.empty()) older_paths.push_back(latest_path);

    latest_version = version;
    latest_path = path;
  }

  install_info_->version = latest_version;
  install_info_->install_dir = latest_path;
  install_info_->manifest = update_client::ReadManifest(latest_path);
  base::ReadFileToString(latest_path.AppendASCII("manifest.fingerprint"),
                         &install_info_->fingerprint);

  for (const auto& older_path : older_paths) base::DeleteFile(older_path, true);
}

Installer::Result Installer::InstallHelper(const base::FilePath& unpack_path) {
  auto local_manifest = update_client::ReadManifest(unpack_path);
  if (!local_manifest) return Result(update_client::InstallError::BAD_MANIFEST);

  std::string version_ascii;
  local_manifest->GetStringASCII("version", &version_ascii);
  const base::Version manifest_version(version_ascii);

  VLOG(1) << "Installed version=" << install_info_->version.GetString()
          << ", installing version=" << manifest_version.GetString();

  if (!manifest_version.IsValid())
    return Result(update_client::InstallError::INVALID_VERSION);

  if (install_info_->version.CompareTo(manifest_version) > 0)
    return Result(update_client::InstallError::VERSION_NOT_UPGRADED);

  const base::FilePath app_install_dir = GetAppInstallDir(crx_id_);
  if (app_install_dir.empty())
    return Result(update_client::InstallError::NO_DIR_COMPONENT_USER);
  if (!base::CreateDirectory(app_install_dir)) {
    return Result(
        static_cast<int>(update_client::InstallError::CUSTOM_ERROR_BASE) +
        kCustomInstallErrorCreateAppInstallDirectory);
  }

  const auto versioned_install_dir =
      app_install_dir.AppendASCII(manifest_version.GetString());
  if (base::PathExists(versioned_install_dir)) {
    if (!base::DeleteFile(versioned_install_dir, true))
      return Result(update_client::InstallError::CLEAN_INSTALL_DIR_FAILED);
  }

  VLOG(1) << "Install_path=" << versioned_install_dir.AsUTF8Unsafe();

  if (!base::Move(unpack_path, versioned_install_dir)) {
    PLOG(ERROR) << "Move failed.";
    base::DeleteFile(versioned_install_dir, true);
    return Result(update_client::InstallError::MOVE_FILES_ERROR);
  }

  DCHECK(!base::PathExists(unpack_path));
  DCHECK(base::PathExists(versioned_install_dir));

  install_info_->manifest = std::move(local_manifest);
  install_info_->version = manifest_version;
  install_info_->install_dir = versioned_install_dir;
  base::ReadFileToString(
      versioned_install_dir.AppendASCII("manifest.fingerprint"),
      &install_info_->fingerprint);

  return Result(update_client::InstallError::NONE);
}

void Installer::OnUpdateError(int error) {
  LOG(ERROR) << "updater error: " << error << " for " << crx_id_;
}

void Installer::Install(const base::FilePath& unpack_path,
                        const std::string& public_key, Callback callback) {
  std::unique_ptr<base::DictionaryValue> manifest;
  base::Version version;
  base::FilePath install_path;

  const auto result = InstallHelper(unpack_path);
  base::DeleteFile(unpack_path, true);
  std::move(callback).Run(result);
}

bool Installer::GetInstalledFile(const std::string& file,
                                 base::FilePath* installed_file) {
  return false;
}

bool Installer::Uninstall() { return false; }

}  // namespace updater
