// 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/extensions/shared_module_service.h"

#include <set>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/version.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/pending_extension_manager.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/uninstall_reason.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_urls.h"

namespace extensions {

namespace {

typedef std::vector<SharedModuleInfo::ImportInfo> ImportInfoVector;
typedef std::list<SharedModuleInfo::ImportInfo> ImportInfoList;

}  // namespace

SharedModuleService::SharedModuleService(content::BrowserContext* context)
    : extension_registry_observer_(this), browser_context_(context) {
  extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
}

SharedModuleService::~SharedModuleService() {
}

SharedModuleService::ImportStatus SharedModuleService::CheckImports(
    const Extension* extension,
    ImportInfoList* missing_modules,
    ImportInfoList* outdated_modules) {
  DCHECK(extension);
  DCHECK(missing_modules && missing_modules->empty());
  DCHECK(outdated_modules && outdated_modules->empty());

  ImportStatus status = IMPORT_STATUS_OK;

  // TODO(crbug.com/420147): Code like this lives in CrxInstaller and
  // UnpackedInstaller.  If a change is made here that is important to enforce
  // at install time, those locations need to be updated.
  ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
  const ImportInfoVector& imports = SharedModuleInfo::GetImports(extension);
  for (auto iter = imports.begin(); iter != imports.end(); ++iter) {
    base::Version version_required(iter->minimum_version);
    const Extension* imported_module =
        registry->GetExtensionById(iter->extension_id,
                                   ExtensionRegistry::EVERYTHING);
    if (!imported_module) {
      if (extension->from_webstore()) {
        status = IMPORT_STATUS_UNSATISFIED;
        missing_modules->push_back(*iter);
      } else {
        return IMPORT_STATUS_UNRECOVERABLE;
      }
    } else if (!SharedModuleInfo::IsSharedModule(imported_module)) {
      return IMPORT_STATUS_UNRECOVERABLE;
    } else if (version_required.IsValid() &&
               imported_module->version().CompareTo(version_required) < 0) {
      if (imported_module->from_webstore()) {
        outdated_modules->push_back(*iter);
        status = IMPORT_STATUS_UNSATISFIED;
      } else {
        return IMPORT_STATUS_UNRECOVERABLE;
      }
    }
  }

  return status;
}

SharedModuleService::ImportStatus SharedModuleService::SatisfyImports(
    const Extension* extension) {
  ImportInfoList missing_modules;
  ImportInfoList outdated_modules;
  ImportStatus status =
      CheckImports(extension, &missing_modules, &outdated_modules);

  ExtensionService* service =
      ExtensionSystem::Get(browser_context_)->extension_service();

  PendingExtensionManager* pending_extension_manager =
      service->pending_extension_manager();
  DCHECK(pending_extension_manager);

  if (status == IMPORT_STATUS_UNSATISFIED) {
    for (ImportInfoList::const_iterator iter = missing_modules.begin();
         iter != missing_modules.end();
         ++iter) {
      pending_extension_manager->AddFromExtensionImport(
          iter->extension_id,
          extension_urls::GetWebstoreUpdateUrl(),
          SharedModuleInfo::IsSharedModule);
    }
    service->CheckForUpdatesSoon();
  }
  return status;
}

std::unique_ptr<ExtensionSet> SharedModuleService::GetDependentExtensions(
    const Extension* extension) {
  std::unique_ptr<ExtensionSet> dependents(new ExtensionSet());

  if (SharedModuleInfo::IsSharedModule(extension)) {
    ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
    ExtensionService* service =
        ExtensionSystem::Get(browser_context_)->extension_service();

    ExtensionSet set_to_check;
    set_to_check.InsertAll(registry->enabled_extensions());
    set_to_check.InsertAll(registry->disabled_extensions());
    set_to_check.InsertAll(*service->delayed_installs());

    for (ExtensionSet::const_iterator iter = set_to_check.begin();
         iter != set_to_check.end();
         ++iter) {
      if (SharedModuleInfo::ImportsExtensionById(iter->get(),
                                                 extension->id())) {
        dependents->Insert(*iter);
      }
    }
  }
  return dependents;
}

InstallGate::Action SharedModuleService::ShouldDelay(const Extension* extension,
                                                     bool install_immediately) {
  ImportStatus status = SatisfyImports(extension);
  switch (status) {
    case IMPORT_STATUS_OK:
      return INSTALL;
    case IMPORT_STATUS_UNSATISFIED:
      return DELAY;
    case IMPORT_STATUS_UNRECOVERABLE:
      return ABORT;
  }

  NOTREACHED();
  return INSTALL;
}

void SharedModuleService::PruneSharedModules() {
  ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
  ExtensionService* service =
      ExtensionSystem::Get(browser_context_)->extension_service();

  ExtensionSet set_to_check;
  set_to_check.InsertAll(registry->enabled_extensions());
  set_to_check.InsertAll(registry->disabled_extensions());
  set_to_check.InsertAll(*service->delayed_installs());

  std::vector<std::string> shared_modules;
  std::set<std::string> used_shared_modules;

  for (ExtensionSet::const_iterator iter = set_to_check.begin();
       iter != set_to_check.end();
       ++iter) {
    if (SharedModuleInfo::IsSharedModule(iter->get()))
      shared_modules.push_back(iter->get()->id());

    const ImportInfoVector& imports = SharedModuleInfo::GetImports(iter->get());
    for (auto imports_iter = imports.begin(); imports_iter != imports.end();
         ++imports_iter) {
      used_shared_modules.insert(imports_iter->extension_id);
    }
  }

  std::vector<std::string>::const_iterator shared_modules_iter;
  for (shared_modules_iter = shared_modules.begin();
       shared_modules_iter != shared_modules.end();
       shared_modules_iter++) {
    if (used_shared_modules.count(*shared_modules_iter))
      continue;
    service->UninstallExtension(
        *shared_modules_iter,
        extensions::UNINSTALL_REASON_ORPHANED_SHARED_MODULE,
        NULL);  // Ignore error.
  }
}

void SharedModuleService::OnExtensionInstalled(
    content::BrowserContext* browser_context,
    const Extension* extension,
    bool is_update) {
  if (is_update)
    PruneSharedModules();
}

void SharedModuleService::OnExtensionUninstalled(
    content::BrowserContext* browser_context,
    const Extension* extension,
    extensions::UninstallReason reason) {
  // Do not call PruneSharedModules() for an uninstall that we were responsible
  // for.
  if (reason == extensions::UNINSTALL_REASON_ORPHANED_SHARED_MODULE)
    return;

  PruneSharedModules();
}

}  // namespace extensions
