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

#include <stddef.h>

#include <memory>
#include <unordered_set>
#include <utility>

#include "base/bind.h"
#include "base/check_op.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/notreached.h"
#include "base/one_shot_event.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "chrome/browser/extensions/extension_garbage_collector_factory.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/install_tracker.h"
#include "chrome/browser/extensions/pending_extension_manager.h"
#include "components/crx_file/id_util.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "extensions/browser/extension_file_task_runner.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extension_util.h"
#include "extensions/common/extension.h"
#include "extensions/common/file_util.h"
#include "extensions/common/manifest_handlers/app_isolation_info.h"

namespace extensions {

namespace {

// Wait this long before trying to garbage collect extensions again.
constexpr base::TimeDelta kGarbageCollectRetryDelay =
    base::TimeDelta::FromSeconds(30);

// Wait this long after startup to see if there are any extensions which can be
// garbage collected.
constexpr base::TimeDelta kGarbageCollectStartupDelay =
    base::TimeDelta::FromSeconds(30);

typedef std::multimap<std::string, base::FilePath> ExtensionPathsMultimap;

void CheckExtensionDirectory(const base::FilePath& path,
                             const ExtensionPathsMultimap& extension_paths) {
  base::FilePath basename = path.BaseName();
  // Clean up temporary files left if Chrome crashed or quit in the middle
  // of an extension install.
  if (basename.value() == file_util::kTempDirectoryName) {
    base::DeletePathRecursively(path);
    return;
  }

  // Parse directory name as a potential extension ID.
  std::string extension_id;
  if (base::IsStringASCII(basename.value())) {
    extension_id = base::UTF16ToASCII(basename.LossyDisplayName());
    if (!crx_file::id_util::IdIsValid(extension_id))
      extension_id.clear();
  }

  // Delete directories that aren't valid IDs.
  if (extension_id.empty()) {
    base::DeletePathRecursively(path);
    return;
  }

  typedef ExtensionPathsMultimap::const_iterator Iter;
  std::pair<Iter, Iter> iter_pair = extension_paths.equal_range(extension_id);

  // If there is no entry in the prefs file, just delete the directory and
  // move on. This can legitimately happen when an uninstall does not
  // complete, for example, when a plugin is in use at uninstall time.
  if (iter_pair.first == iter_pair.second) {
    base::DeletePathRecursively(path);
    return;
  }

  // Clean up old version directories.
  base::FileEnumerator versions_enumerator(
      path, false /* Not recursive */, base::FileEnumerator::DIRECTORIES);
  for (base::FilePath version_dir = versions_enumerator.Next();
       !version_dir.empty();
       version_dir = versions_enumerator.Next()) {
    bool known_version = false;
    for (auto iter = iter_pair.first; iter != iter_pair.second; ++iter) {
      if (version_dir.BaseName() == iter->second.BaseName()) {
        known_version = true;
        break;
      }
    }
    if (!known_version)
      base::DeletePathRecursively(version_dir);
  }
}

}  // namespace

ExtensionGarbageCollector::ExtensionGarbageCollector(
    content::BrowserContext* context)
    : context_(context), crx_installs_in_progress_(0) {
  ExtensionSystem* extension_system = ExtensionSystem::Get(context_);
  DCHECK(extension_system);

  extension_system->ready().PostDelayed(
      FROM_HERE,
      base::BindOnce(&ExtensionGarbageCollector::GarbageCollectExtensions,
                     weak_factory_.GetWeakPtr()),
      kGarbageCollectStartupDelay);

  extension_system->ready().Post(
      FROM_HERE,
      base::BindOnce(
          &ExtensionGarbageCollector::GarbageCollectIsolatedStorageIfNeeded,
          weak_factory_.GetWeakPtr()));

  InstallTracker::Get(context_)->AddObserver(this);
}

ExtensionGarbageCollector::~ExtensionGarbageCollector() {}

// static
ExtensionGarbageCollector* ExtensionGarbageCollector::Get(
    content::BrowserContext* context) {
  return ExtensionGarbageCollectorFactory::GetForBrowserContext(context);
}

void ExtensionGarbageCollector::Shutdown() {
  InstallTracker::Get(context_)->RemoveObserver(this);
}

void ExtensionGarbageCollector::GarbageCollectExtensionsForTest() {
  GarbageCollectExtensions();
}

// static
void ExtensionGarbageCollector::GarbageCollectExtensionsOnFileThread(
    const base::FilePath& install_directory,
    const ExtensionPathsMultimap& extension_paths) {
  DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  // Nothing to clean up if it doesn't exist.
  if (!base::DirectoryExists(install_directory))
    return;

  base::FileEnumerator enumerator(install_directory,
                                  false,  // Not recursive.
                                  base::FileEnumerator::DIRECTORIES);

  for (base::FilePath extension_path = enumerator.Next();
       !extension_path.empty();
       extension_path = enumerator.Next()) {
    CheckExtensionDirectory(extension_path, extension_paths);
  }
}

void ExtensionGarbageCollector::GarbageCollectExtensions() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(context_);
  DCHECK(extension_prefs);

  if (extension_prefs->pref_service()->ReadOnly())
    return;

  if (crx_installs_in_progress_ > 0) {
    // Don't garbage collect while there are installations in progress,
    // which may be using the temporary installation directory. Try to garbage
    // collect again later.
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(&ExtensionGarbageCollector::GarbageCollectExtensions,
                       weak_factory_.GetWeakPtr()),
        kGarbageCollectRetryDelay);
    return;
  }

  std::unique_ptr<ExtensionPrefs::ExtensionsInfo> info(
      extension_prefs->GetInstalledExtensionsInfo());
  std::multimap<std::string, base::FilePath> extension_paths;
  for (size_t i = 0; i < info->size(); ++i) {
    extension_paths.insert(
        std::make_pair(info->at(i)->extension_id, info->at(i)->extension_path));
  }

  info = extension_prefs->GetAllDelayedInstallInfo();
  for (size_t i = 0; i < info->size(); ++i) {
    extension_paths.insert(
        std::make_pair(info->at(i)->extension_id, info->at(i)->extension_path));
  }

  ExtensionService* service =
      ExtensionSystem::Get(context_)->extension_service();
  if (!GetExtensionFileTaskRunner()->PostTask(
          FROM_HERE,
          base::BindOnce(&GarbageCollectExtensionsOnFileThread,
                         service->install_directory(), extension_paths))) {
    NOTREACHED();
  }
}

void ExtensionGarbageCollector::GarbageCollectIsolatedStorageIfNeeded() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(context_);
  DCHECK(extension_prefs);
  if (!extension_prefs->NeedsStorageGarbageCollection())
    return;
  extension_prefs->SetNeedsStorageGarbageCollection(false);

  std::unique_ptr<std::unordered_set<base::FilePath>> active_paths(
      new std::unordered_set<base::FilePath>());
  std::unique_ptr<ExtensionSet> extensions =
      ExtensionRegistry::Get(context_)->GenerateInstalledExtensionsSet();
  for (ExtensionSet::const_iterator iter = extensions->begin();
       iter != extensions->end();
       ++iter) {
    if (AppIsolationInfo::HasIsolatedStorage(iter->get())) {
      active_paths->insert(
          util::GetStoragePartitionForExtensionId((*iter)->id(), context_)
              ->GetPath());
    }
  }

  DCHECK(!installs_delayed_for_gc_);
  installs_delayed_for_gc_ = true;
  content::BrowserContext::GarbageCollectStoragePartitions(
      context_, std::move(active_paths),
      base::BindOnce(
          &ExtensionGarbageCollector::OnGarbageCollectIsolatedStorageFinished,
          weak_factory_.GetWeakPtr()));
}

void ExtensionGarbageCollector::OnGarbageCollectIsolatedStorageFinished() {
  DCHECK(installs_delayed_for_gc_);
  installs_delayed_for_gc_ = false;

  ExtensionSystem::Get(context_)
      ->extension_service()
      ->MaybeFinishDelayedInstallations();
}

void ExtensionGarbageCollector::OnBeginCrxInstall(
    const std::string& extension_id) {
  crx_installs_in_progress_++;
}

void ExtensionGarbageCollector::OnFinishCrxInstall(
    const std::string& extension_id,
    bool success) {
  crx_installs_in_progress_--;
  if (crx_installs_in_progress_ < 0) {
    // This can only happen if there is a mismatch in our begin/finish
    // accounting.
    NOTREACHED();

    // Don't let the count go negative to avoid garbage collecting when
    // an install is actually in progress.
    crx_installs_in_progress_ = 0;
  }
}

InstallGate::Action ExtensionGarbageCollector::ShouldDelay(
    const Extension* extension,
    bool install_immediately) {
  return installs_delayed_for_gc_ ? DELAY : INSTALL;
}

}  // namespace extensions
