// 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/chromeos/app_mode/kiosk_external_updater.h"

#include "base/bind.h"
#include "base/files/file_enumerator.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/version.h"
#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
#include "chrome/browser/chromeos/ui/kiosk_external_update_notification.h"
#include "chrome/browser/extensions/sandboxed_unpacker.h"
#include "chrome/common/chrome_version_info.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/common/extension.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"

namespace chromeos {

namespace {

const char kExternalUpdateManifest[] = "external_update.json";
const char kExternalCrx[] = "external_crx";
const char kExternalVersion[] = "external_version";

void ParseExternalUpdateManifest(
    const base::FilePath& external_update_dir,
    base::DictionaryValue* parsed_manifest,
    KioskExternalUpdater::ExternalUpdateErrorCode* error_code) {
  base::FilePath manifest =
      external_update_dir.AppendASCII(kExternalUpdateManifest);
  if (!base::PathExists(manifest)) {
    *error_code = KioskExternalUpdater::ERROR_NO_MANIFEST;
    return;
  }

  JSONFileValueSerializer serializer(manifest);
  std::string error_msg;
  base::Value* extensions = serializer.Deserialize(NULL, &error_msg);
  if (!extensions) {
    *error_code = KioskExternalUpdater::ERROR_INVALID_MANIFEST;
    return;
  }

  base::DictionaryValue* dict_value = NULL;
  if (!extensions->GetAsDictionary(&dict_value)) {
    *error_code = KioskExternalUpdater::ERROR_INVALID_MANIFEST;
    return;
  }

  parsed_manifest->Swap(dict_value);
  *error_code = KioskExternalUpdater::ERROR_NONE;
}

// Copies |external_crx_file| to |temp_crx_file|, and removes |temp_dir|
// created for unpacking |external_crx_file|.
void CopyExternalCrxAndDeleteTempDir(const base::FilePath& external_crx_file,
                                     const base::FilePath& temp_crx_file,
                                     const base::FilePath& temp_dir,
                                     bool* success) {
  base::DeleteFile(temp_dir, true);
  *success = 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;
  else if (update_for_same_version && compare_result == 0)
    return true;
  else
    return false;
}

}  // namespace

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),
      weak_factory_(this) {
  // 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::OnDiskEvent(
    disks::DiskMountManager::DiskEvent event,
    const disks::DiskMountManager::Disk* disk) {
}

void KioskExternalUpdater::OnDeviceEvent(
    disks::DiskMountManager::DeviceEvent event,
    const std::string& device_path) {
}

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 != MOUNT_TYPE_DEVICE ||
      error_code != 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::DictionaryValue* parsed_manifest = new base::DictionaryValue();
    ExternalUpdateErrorCode* parsing_error = new ExternalUpdateErrorCode;
    backend_task_runner_->PostTaskAndReply(
        FROM_HERE,
        base::Bind(&ParseExternalUpdateManifest,
                   base::FilePath(mount_info.mount_path),
                   parsed_manifest,
                   parsing_error),
        base::Bind(&KioskExternalUpdater::ProcessParsedManifest,
                   weak_factory_.GetWeakPtr(),
                   base::Owned(parsing_error),
                   base::FilePath(mount_info.mount_path),
                   base::Owned(parsed_manifest)));
  } else {  // unmounting a removable device.
    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::OnFormatEvent(
    disks::DiskMountManager::FormatEvent event,
    FormatError error_code,
    const std::string& device_path) {
}

void KioskExternalUpdater::OnExtenalUpdateUnpackSuccess(
    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 = FAILED;
    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;
  base::FilePath temp_crx_path =
      crx_unpack_dir_.Append(external_crx_path.BaseName());
  bool* success = new bool;
  backend_task_runner_->PostTaskAndReply(
      FROM_HERE,
      base::Bind(&CopyExternalCrxAndDeleteTempDir,
                 external_crx_path,
                 temp_crx_path,
                 temp_dir,
                 success),
      base::Bind(&KioskExternalUpdater::PutValidatedExtension,
                 weak_factory_.GetWeakPtr(),
                 base::Owned(success),
                 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 = FAILED;
  external_updates_[app_id].error =
      ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
          IDS_KIOSK_EXTERNAL_UPDATE_BAD_CRX);
  MaybeValidateNextExternalUpdate();
}

void KioskExternalUpdater::ProcessParsedManifest(
    ExternalUpdateErrorCode* parsing_error,
    const base::FilePath& external_update_dir,
    base::DictionaryValue* parsed_manifest) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (*parsing_error == ERROR_NO_MANIFEST) {
    KioskAppManager::Get()->OnKioskAppExternalUpdateComplete(false);
    return;
  } else if (*parsing_error == ERROR_INVALID_MANIFEST) {
    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 = NULL;
    if (!it.value().GetAsDictionary(&extension)) {
      LOG(ERROR) << "Found bad entry in manifest type " << it.value().GetType();
      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 = external_update_path_.AppendASCII(external_crx_str);
    update.update_status = PENDING;
    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 (ExternalUpdateMap::iterator it = external_updates_.begin();
       it != external_updates_.end();
       ++it) {
    if (it->second.update_status == PENDING) {
      scoped_refptr<KioskExternalUpdateValidator> crx_validator =
          new KioskExternalUpdateValidator(backend_task_runner_,
                                           it->first,
                                           it->second.external_crx,
                                           crx_unpack_dir_,
                                           weak_factory_.GetWeakPtr());
      crx_validator->Start();
      break;
    }
  }
}

bool KioskExternalUpdater::IsExternalUpdatePending() {
  for (ExternalUpdateMap::iterator it = external_updates_.begin();
       it != external_updates_.end();
       ++it) {
    if (it->second.update_status == PENDING) {
      return true;
    }
  }
  return false;
}

bool KioskExternalUpdater::IsAllExternalUpdatesSucceeded() {
  for (ExternalUpdateMap::iterator it = external_updates_.begin();
       it != external_updates_.end();
       ++it) {
    if (it->second.update_status != SUCCESS) {
      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()) {
    chrome::VersionInfo current_version_info;
    if (!ShouldUpdateForHigherVersion(
            min_browser_version, current_version_info.Version(), 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(bool* crx_copied,
                                                 const std::string& app_id,
                                                 const base::FilePath& crx_file,
                                                 const std::string& version) {
  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 = FAILED;
    external_updates_[app_id].error = l10n_util::GetStringFUTF16(
        IDS_KIOSK_EXTERNAL_UPDATE_FAILED_COPY_CRX_TO_TEMP,
        base::UTF8ToUTF16(crx_file.value()));
    MaybeValidateNextExternalUpdate();
    return;
  }

  chromeos::KioskAppManager::Get()->PutValidatedExternalExtension(
      app_id,
      crx_file,
      version,
      base::Bind(&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 = FAILED;
    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.value()));
  } else {
    external_updates_[app_id].update_status = SUCCESS;
  }

  // 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 (ExternalUpdateMap::iterator it = external_updates_.begin();
       it != external_updates_.end();
       ++it) {
    if (it->second.update_status == SUCCESS) {
      KioskAppManager::Get()->OnKioskAppCacheUpdated(it->first);
    }
  }
}

void KioskExternalUpdater::NotifyKioskUpdateProgress(
    const base::string16& message) {
  if (!notification_)
    notification_.reset(new KioskExternalUpdateNotification(message));
  else
    notification_->ShowMessage(message);
}

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

base::string16 KioskExternalUpdater::GetUpdateReportMessage() {
  DCHECK(!IsExternalUpdatePending());
  int updated = 0;
  int failed = 0;
  base::string16 updated_apps;
  base::string16 failed_apps;
  for (ExternalUpdateMap::iterator it = external_updates_.begin();
       it != external_updates_.end();
       ++it) {
    base::string16 app_name = base::UTF8ToUTF16(it->second.app_name);
    if (it->second.update_status == SUCCESS) {
      ++updated;
      if (updated_apps.empty())
        updated_apps = app_name;
      else
        updated_apps = updated_apps + base::ASCIIToUTF16(", ") + app_name;
    } else {  // FAILED
      ++failed;
      if (failed_apps.empty()) {
        failed_apps = app_name + base::ASCIIToUTF16(": ") + it->second.error;
      } else {
        failed_apps = failed_apps + base::ASCIIToUTF16("\n") + app_name +
                      base::ASCIIToUTF16(": ") + it->second.error;
      }
    }
  }

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

  base::string16 failed_app_msg;
  if (failed) {
    failed_app_msg = ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
                         IDS_KIOSK_EXTERNAL_UPDATE_FAILED_UPDATED_APPS) +
                     base::ASCIIToUTF16("\n") + failed_apps;
    message = message + base::ASCIIToUTF16("\n") + failed_app_msg;
  }
  return message;
}

}  // namespace chromeos
