// Copyright 2014 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/browser/ash/app_mode/kiosk_external_updater.h"

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/json/json_file_value_serializer.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
#include "base/version.h"
#include "chrome/browser/ash/app_mode/kiosk_app_manager.h"
#include "chrome/browser/ash/notifications/kiosk_external_update_notification.h"
#include "chrome/grit/generated_resources.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/sandboxed_unpacker.h"
#include "extensions/common/extension.h"
#include "extensions/common/verifier_formats.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"

namespace ash {

namespace {

constexpr base::FilePath::CharType kExternalUpdateManifest[] =
    "external_update.json";
constexpr char kExternalCrx[] = "external_crx";
constexpr char kExternalVersion[] = "external_version";

std::pair<std::unique_ptr<base::DictionaryValue>,
          KioskExternalUpdater::ErrorCode>
ParseExternalUpdateManifest(const base::FilePath& external_update_dir) {
  base::FilePath manifest = external_update_dir.Append(kExternalUpdateManifest);
  if (!base::PathExists(manifest)) {
    return std::make_pair(nullptr,
                          KioskExternalUpdater::ErrorCode::kNoManifest);
  }

  JSONFileValueDeserializer deserializer(manifest);
  std::unique_ptr<base::DictionaryValue> extensions =
      base::DictionaryValue::From(deserializer.Deserialize(nullptr, nullptr));
  if (!extensions) {
    return std::make_pair(nullptr,
                          KioskExternalUpdater::ErrorCode::kInvalidManifest);
  }

  return std::make_pair(std::move(extensions),
                        KioskExternalUpdater::ErrorCode::kNone);
}

// Copies |external_crx_file| to |temp_crx_file|, and removes |temp_dir|
// created for unpacking |external_crx_file|.
bool CopyExternalCrxAndDeleteTempDir(const base::FilePath& external_crx_file,
                                     const base::FilePath& temp_crx_file,
                                     const base::FilePath& temp_dir) {
  base::DeletePathRecursively(temp_dir);
  return base::CopyFile(external_crx_file, temp_crx_file);
}

// Returns true if |version_1| < |version_2|, and
// if |update_for_same_version| is true and |version_1| = |version_2|.
bool ShouldUpdateForHigherVersion(const std::string& version_1,
                                  const std::string& version_2,
                                  bool update_for_same_version) {
  const base::Version v1(version_1);
  const base::Version v2(version_2);
  if (!v1.IsValid() || !v2.IsValid())
    return false;
  int compare_result = v1.CompareTo(v2);
  if (compare_result < 0)
    return true;
  return update_for_same_version && compare_result == 0;
}

}  // namespace

KioskExternalUpdater::ExternalUpdate::ExternalUpdate() {
}

KioskExternalUpdater::ExternalUpdate::ExternalUpdate(
    const ExternalUpdate& other) = default;

KioskExternalUpdater::ExternalUpdate::~ExternalUpdate() {
}

KioskExternalUpdater::KioskExternalUpdater(
    const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner,
    const base::FilePath& crx_cache_dir,
    const base::FilePath& crx_unpack_dir)
    : backend_task_runner_(backend_task_runner),
      crx_cache_dir_(crx_cache_dir),
      crx_unpack_dir_(crx_unpack_dir) {
  // Subscribe to DiskMountManager.
  DCHECK(disks::DiskMountManager::GetInstance());
  disks::DiskMountManager::GetInstance()->AddObserver(this);
}

KioskExternalUpdater::~KioskExternalUpdater() {
  if (disks::DiskMountManager::GetInstance())
    disks::DiskMountManager::GetInstance()->RemoveObserver(this);
}

void KioskExternalUpdater::OnMountEvent(
    disks::DiskMountManager::MountEvent event,
    MountError error_code,
    const disks::DiskMountManager::MountPointInfo& mount_info) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (mount_info.mount_type != MountType::MOUNT_TYPE_DEVICE ||
      error_code != MountError::MOUNT_ERROR_NONE) {
    return;
  }

  if (event == disks::DiskMountManager::MOUNTING) {
    // If multiple disks have been mounted, skip the rest of them if kiosk
    // update has already been found.
    if (!external_update_path_.empty()) {
      LOG(WARNING) << "External update path already found, skip "
                   << mount_info.mount_path;
      return;
    }

    base::PostTaskAndReplyWithResult(
        backend_task_runner_.get(), FROM_HERE,
        base::BindOnce(&ParseExternalUpdateManifest,
                       base::FilePath(mount_info.mount_path)),
        base::BindOnce(&KioskExternalUpdater::ProcessParsedManifest,
                       weak_factory_.GetWeakPtr(),
                       base::FilePath(mount_info.mount_path)));
    return;
  }

  // unmounting a removable device case.
  if (external_update_path_.value().empty()) {
    // Clear any previously displayed message.
    DismissKioskUpdateNotification();
  } else if (external_update_path_.value() == mount_info.mount_path) {
    DismissKioskUpdateNotification();
    if (IsExternalUpdatePending()) {
      LOG(ERROR) << "External kiosk update is not completed when the usb "
                 << "stick is unmoutned.";
    }
    external_updates_.clear();
    external_update_path_.clear();
  }
}

void KioskExternalUpdater::OnExternalUpdateUnpackSuccess(
    const std::string& app_id,
    const std::string& version,
    const std::string& min_browser_version,
    const base::FilePath& temp_dir) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // User might pull out the usb stick before updating is completed.
  if (CheckExternalUpdateInterrupted())
    return;

  if (!ShouldDoExternalUpdate(app_id, version, min_browser_version)) {
    external_updates_[app_id].update_status = UpdateStatus::kFailed;
    MaybeValidateNextExternalUpdate();
    return;
  }

  // User might pull out the usb stick before updating is completed.
  if (CheckExternalUpdateInterrupted())
    return;

  base::FilePath external_crx_path =
      external_updates_[app_id].external_crx.path;
  base::FilePath temp_crx_path =
      crx_unpack_dir_.Append(external_crx_path.BaseName());
  base::PostTaskAndReplyWithResult(
      backend_task_runner_.get(), FROM_HERE,
      base::BindOnce(&CopyExternalCrxAndDeleteTempDir, external_crx_path,
                     temp_crx_path, temp_dir),
      base::BindOnce(&KioskExternalUpdater::PutValidatedExtension,
                     weak_factory_.GetWeakPtr(), app_id, temp_crx_path,
                     version));
}

void KioskExternalUpdater::OnExternalUpdateUnpackFailure(
    const std::string& app_id) {
  // User might pull out the usb stick before updating is completed.
  if (CheckExternalUpdateInterrupted())
    return;

  external_updates_[app_id].update_status = UpdateStatus::kFailed;
  external_updates_[app_id].error =
      ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
          IDS_KIOSK_EXTERNAL_UPDATE_BAD_CRX);
  MaybeValidateNextExternalUpdate();
}

void KioskExternalUpdater::ProcessParsedManifest(
    const base::FilePath& external_update_dir,
    const ParseManifestResult& result) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  const std::unique_ptr<base::DictionaryValue>& parsed_manifest = result.first;
  ErrorCode parsing_error = result.second;
  if (parsing_error == ErrorCode::kNoManifest) {
    KioskAppManager::Get()->OnKioskAppExternalUpdateComplete(false);
    return;
  }
  if (parsing_error == ErrorCode::kInvalidManifest) {
    NotifyKioskUpdateProgress(
        ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
            IDS_KIOSK_EXTERNAL_UPDATE_INVALID_MANIFEST));
    KioskAppManager::Get()->OnKioskAppExternalUpdateComplete(false);
    return;
  }

  NotifyKioskUpdateProgress(
      ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
          IDS_KIOSK_EXTERNAL_UPDATE_IN_PROGRESS));

  external_update_path_ = external_update_dir;
  for (base::DictionaryValue::Iterator it(*parsed_manifest); !it.IsAtEnd();
       it.Advance()) {
    std::string app_id = it.key();
    std::string cached_version_str;
    base::FilePath cached_crx;
    if (!KioskAppManager::Get()->GetCachedCrx(
            app_id, &cached_crx, &cached_version_str)) {
      LOG(WARNING) << "Can't find app in existing cache " << app_id;
      continue;
    }

    const base::DictionaryValue* extension = nullptr;
    if (!it.value().GetAsDictionary(&extension)) {
      LOG(ERROR) << "Found bad entry in manifest type " << it.value().type();
      continue;
    }

    std::string external_crx_str;
    if (!extension->GetString(kExternalCrx, &external_crx_str)) {
      LOG(ERROR) << "Can't find external crx in manifest " << app_id;
      continue;
    }

    std::string external_version_str;
    if (extension->GetString(kExternalVersion, &external_version_str)) {
      if (!ShouldUpdateForHigherVersion(
              cached_version_str, external_version_str, false)) {
        LOG(WARNING) << "External app " << app_id
                     << " is at the same or lower version comparing to "
                     << " the existing one.";
        continue;
      }
    }

    ExternalUpdate update;
    KioskAppManager::App app;
    if (KioskAppManager::Get()->GetApp(app_id, &app)) {
      update.app_name = app.name;
    } else {
      NOTREACHED();
    }
    update.external_crx = extensions::CRXFileInfo(
        external_update_path_.AppendASCII(external_crx_str),
        extensions::GetExternalVerifierFormat());
    update.external_crx.extension_id = app_id;
    update.update_status = UpdateStatus::kPending;
    external_updates_[app_id] = update;
  }

  if (external_updates_.empty()) {
    NotifyKioskUpdateProgress(
        ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
            IDS_KIOSK_EXTERNAL_UPDATE_NO_UPDATES));
    KioskAppManager::Get()->OnKioskAppExternalUpdateComplete(false);
    return;
  }

  ValidateExternalUpdates();
}

bool KioskExternalUpdater::CheckExternalUpdateInterrupted() {
  if (external_updates_.empty()) {
    // This could happen if user pulls out the usb stick before the updating
    // operation is completed.
    LOG(ERROR) << "external_updates_ has been cleared before external "
               << "updating completes.";
    return true;
  }

  return false;
}

void KioskExternalUpdater::ValidateExternalUpdates() {
  for (const auto& it : external_updates_) {
    const ExternalUpdate& update = it.second;
    if (update.update_status == UpdateStatus::kPending) {
      auto crx_validator = base::MakeRefCounted<KioskExternalUpdateValidator>(
          backend_task_runner_, update.external_crx, crx_unpack_dir_,
          weak_factory_.GetWeakPtr());
      crx_validator->Start();
      break;
    }
  }
}

bool KioskExternalUpdater::IsExternalUpdatePending() const {
  for (const auto& it : external_updates_) {
    if (it.second.update_status == UpdateStatus::kPending)
      return true;
  }
  return false;
}

bool KioskExternalUpdater::IsAllExternalUpdatesSucceeded() const {
  for (const auto& it : external_updates_) {
    if (it.second.update_status != UpdateStatus::kSuccess)
      return false;
  }
  return true;
}

bool KioskExternalUpdater::ShouldDoExternalUpdate(
    const std::string& app_id,
    const std::string& version,
    const std::string& min_browser_version) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  std::string existing_version_str;
  base::FilePath existing_path;
  bool cached = KioskAppManager::Get()->GetCachedCrx(
      app_id, &existing_path, &existing_version_str);
  DCHECK(cached);

  // Compare app version.
  ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
  if (!ShouldUpdateForHigherVersion(existing_version_str, version, false)) {
    external_updates_[app_id].error = rb->GetLocalizedString(
        IDS_KIOSK_EXTERNAL_UPDATE_SAME_OR_LOWER_APP_VERSION);
    return false;
  }

  // Check minimum browser version.
  if (!min_browser_version.empty() &&
      !ShouldUpdateForHigherVersion(min_browser_version,
                                    version_info::GetVersionNumber(), true)) {
    external_updates_[app_id].error = l10n_util::GetStringFUTF16(
        IDS_KIOSK_EXTERNAL_UPDATE_REQUIRE_HIGHER_BROWSER_VERSION,
        base::UTF8ToUTF16(min_browser_version));
    return false;
  }

  return true;
}

void KioskExternalUpdater::PutValidatedExtension(const std::string& app_id,
                                                 const base::FilePath& crx_file,
                                                 const std::string& version,
                                                 bool crx_copied) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (CheckExternalUpdateInterrupted())
    return;

  if (!crx_copied) {
    LOG(ERROR) << "Cannot copy external crx file to " << crx_file.value();
    external_updates_[app_id].update_status = UpdateStatus::kFailed;
    external_updates_[app_id].error = l10n_util::GetStringFUTF16(
        IDS_KIOSK_EXTERNAL_UPDATE_FAILED_COPY_CRX_TO_TEMP,
        base::UTF8ToUTF16(crx_file.value()));
    MaybeValidateNextExternalUpdate();
    return;
  }

  KioskAppManager::Get()->PutValidatedExternalExtension(
      app_id, crx_file, version,
      base::BindOnce(&KioskExternalUpdater::OnPutValidatedExtension,
                     weak_factory_.GetWeakPtr()));
}

void KioskExternalUpdater::OnPutValidatedExtension(const std::string& app_id,
                                                   bool success) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (CheckExternalUpdateInterrupted())
    return;

  if (!success) {
    external_updates_[app_id].update_status = UpdateStatus::kFailed;
    external_updates_[app_id].error = l10n_util::GetStringFUTF16(
        IDS_KIOSK_EXTERNAL_UPDATE_CANNOT_INSTALL_IN_LOCAL_CACHE,
        base::UTF8ToUTF16(external_updates_[app_id].external_crx.path.value()));
  } else {
    external_updates_[app_id].update_status = UpdateStatus::kSuccess;
  }

  // Validate the next pending external update.
  MaybeValidateNextExternalUpdate();
}

void KioskExternalUpdater::MaybeValidateNextExternalUpdate() {
  if (IsExternalUpdatePending())
    ValidateExternalUpdates();
  else
    MayBeNotifyKioskAppUpdate();
}

void KioskExternalUpdater::MayBeNotifyKioskAppUpdate() {
  if (IsExternalUpdatePending())
    return;

  NotifyKioskUpdateProgress(GetUpdateReportMessage());
  NotifyKioskAppUpdateAvailable();
  KioskAppManager::Get()->OnKioskAppExternalUpdateComplete(
      IsAllExternalUpdatesSucceeded());
}

void KioskExternalUpdater::NotifyKioskAppUpdateAvailable() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  for (const auto& it : external_updates_) {
    if (it.second.update_status == UpdateStatus::kSuccess) {
      KioskAppManager::Get()->OnKioskAppCacheUpdated(it.first);
    }
  }
}

void KioskExternalUpdater::NotifyKioskUpdateProgress(
    const std::u16string& message) {
  if (!notification_)
    notification_ = std::make_unique<KioskExternalUpdateNotification>(message);
  else
    notification_->ShowMessage(message);
}

void KioskExternalUpdater::DismissKioskUpdateNotification() {
  if (notification_.get()) {
    notification_.reset();
  }
}

std::u16string KioskExternalUpdater::GetUpdateReportMessage() const {
  DCHECK(!IsExternalUpdatePending());
  int updated = 0;
  int failed = 0;
  std::u16string updated_apps;
  std::u16string failed_apps;
  for (const auto& it : external_updates_) {
    const ExternalUpdate& update = it.second;
    std::u16string app_name = base::UTF8ToUTF16(update.app_name);
    if (update.update_status == UpdateStatus::kSuccess) {
      ++updated;
      if (updated_apps.empty())
        updated_apps = app_name;
      else
        updated_apps += u", " + app_name;
    } else {  // UpdateStatus::kFailed
      ++failed;
      if (failed_apps.empty()) {
        failed_apps = app_name + u": " + update.error;
      } else {
        failed_apps += u"\n" + app_name + u": " + update.error;
      }
    }
  }

  std::u16string message =
      ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
          IDS_KIOSK_EXTERNAL_UPDATE_COMPLETE);
  if (updated) {
    std::u16string success_app_msg = l10n_util::GetStringFUTF16(
        IDS_KIOSK_EXTERNAL_UPDATE_SUCCESSFUL_UPDATED_APPS, updated_apps);
    message += u"\n" + success_app_msg;
  }

  if (failed) {
    std::u16string failed_app_msg =
        ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
            IDS_KIOSK_EXTERNAL_UPDATE_FAILED_UPDATED_APPS) +
        u"\n" + failed_apps;
    message += u"\n" + failed_app_msg;
  }
  return message;
}

}  // namespace ash
