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

#include <algorithm>

#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/version.h"
#include "chrome/common/extensions/extension_constants.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "url/gurl.h"

using content::BrowserThread;

namespace {

// Install predicate used by AddFromExternalUpdateUrl().
bool AlwaysInstall(const extensions::Extension* extension) {
  return true;
}

std::string GetVersionString(const base::Version& version) {
  return version.IsValid() ? version.GetString() : "invalid";
}

}  // namespace

namespace extensions {

PendingExtensionManager::PendingExtensionManager(
    content::BrowserContext* context)
    : context_(context) {}

PendingExtensionManager::~PendingExtensionManager() {}

const PendingExtensionInfo* PendingExtensionManager::GetById(
    const std::string& id) const {
  PendingExtensionList::const_iterator iter;
  for (iter = pending_extension_list_.begin();
       iter != pending_extension_list_.end();
       ++iter) {
    if (id == iter->id())
      return &(*iter);
  }

  return NULL;
}

bool PendingExtensionManager::Remove(const std::string& id) {
  if (base::ContainsKey(expected_policy_reinstalls_, id)) {
    base::TimeDelta latency =
        base::TimeTicks::Now() - expected_policy_reinstalls_[id];
    UMA_HISTOGRAM_LONG_TIMES("Extensions.CorruptPolicyExtensionResolved",
                             latency);
    expected_policy_reinstalls_.erase(id);
  }
  PendingExtensionList::iterator iter;
  for (iter = pending_extension_list_.begin();
       iter != pending_extension_list_.end();
       ++iter) {
    if (id == iter->id()) {
      pending_extension_list_.erase(iter);
      return true;
    }
  }

  return false;
}

bool PendingExtensionManager::IsIdPending(const std::string& id) const {
  return GetById(id) != NULL;
}

bool PendingExtensionManager::HasPendingExtensions() const {
  return !pending_extension_list_.empty();
}

bool PendingExtensionManager::HasPendingExtensionFromSync() const {
  PendingExtensionList::const_iterator iter;
  for (iter = pending_extension_list_.begin();
       iter != pending_extension_list_.end();
       ++iter) {
    if (iter->is_from_sync())
      return true;
  }

  return false;
}

void PendingExtensionManager::ExpectPolicyReinstallForCorruption(
    const ExtensionId& id) {
  expected_policy_reinstalls_[id] = base::TimeTicks::Now();
  UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptPolicyExtensionDetected", true);
}

bool PendingExtensionManager::IsPolicyReinstallForCorruptionExpected(
    const ExtensionId& id) const {
  return base::ContainsKey(expected_policy_reinstalls_, id);
}

bool PendingExtensionManager::HasAnyPolicyReinstallForCorruption() const {
  return !expected_policy_reinstalls_.empty();
}

bool PendingExtensionManager::AddFromSync(
    const std::string& id,
    const GURL& update_url,
    const base::Version& version,
    PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
    bool remote_install) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  if (ExtensionRegistry::Get(context_)->GetExtensionById(
          id, ExtensionRegistry::EVERYTHING)) {
    LOG(ERROR) << "Trying to add pending extension " << id
               << " which already exists";
    return false;
  }

  // Make sure we don't ever try to install the CWS app, because even though
  // it is listed as a syncable app (because its values need to be synced) it
  // should already be installed on every instance.
  if (id == extensions::kWebStoreAppId) {
    NOTREACHED();
    return false;
  }

  static const bool kIsFromSync = true;
  static const Manifest::Location kSyncLocation = Manifest::INTERNAL;
  static const bool kMarkAcknowledged = false;

  return AddExtensionImpl(id,
                          std::string(),
                          update_url,
                          version,
                          should_allow_install,
                          kIsFromSync,
                          kSyncLocation,
                          Extension::NO_FLAGS,
                          kMarkAcknowledged,
                          remote_install);
}

bool PendingExtensionManager::AddFromExtensionImport(
    const std::string& id,
    const GURL& update_url,
    PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  if (ExtensionRegistry::Get(context_)->GetExtensionById(
          id, ExtensionRegistry::EVERYTHING)) {
    LOG(ERROR) << "Trying to add pending extension " << id
               << " which already exists";
    return false;
  }

  static const bool kIsFromSync = false;
  static const Manifest::Location kManifestLocation = Manifest::INTERNAL;
  static const bool kMarkAcknowledged = false;
  static const bool kRemoteInstall = false;

  return AddExtensionImpl(id,
                          std::string(),
                          update_url,
                          base::Version(),
                          should_allow_install,
                          kIsFromSync,
                          kManifestLocation,
                          Extension::NO_FLAGS,
                          kMarkAcknowledged,
                          kRemoteInstall);
}

bool PendingExtensionManager::AddFromExternalUpdateUrl(
    const std::string& id,
    const std::string& install_parameter,
    const GURL& update_url,
    Manifest::Location location,
    int creation_flags,
    bool mark_acknowledged) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  static const bool kIsFromSync = false;
  static const bool kRemoteInstall = false;

  const Extension* extension = ExtensionRegistry::Get(context_)
      ->GetExtensionById(id, ExtensionRegistry::EVERYTHING);
  if (extension && location == Manifest::GetHigherPriorityLocation(
                                   location, extension->location())) {
    // If the new location has higher priority than the location of an existing
    // extension, let the update process overwrite the existing extension.
  } else {
    // Skip the installation if the extension was removed by the user and it's
    // not specified to be force-installed through the policy.
    if (!Manifest::IsPolicyLocation(location) &&
        ExtensionPrefs::Get(context_)->IsExternalExtensionUninstalled(id)) {
      return false;
    }

    if (extension) {
      LOG(DFATAL) << "Trying to add extension " << id
                  << " by external update, but it is already installed.";
      return false;
    }
  }

  return AddExtensionImpl(id,
                          install_parameter,
                          update_url,
                          base::Version(),
                          &AlwaysInstall,
                          kIsFromSync,
                          location,
                          creation_flags,
                          mark_acknowledged,
                          kRemoteInstall);
}


bool PendingExtensionManager::AddFromExternalFile(
    const std::string& id,
    Manifest::Location install_source,
    const base::Version& version,
    int creation_flags,
    bool mark_acknowledged) {
  // TODO(skerner): AddFromSync() checks to see if the extension is
  // installed, but this method assumes that the caller already
  // made sure it is not installed.  Make all AddFrom*() methods
  // consistent.
  const GURL& kUpdateUrl = GURL::EmptyGURL();
  static const bool kIsFromSync = false;
  static const bool kRemoteInstall = false;

  return AddExtensionImpl(id,
                          std::string(),
                          kUpdateUrl,
                          version,
                          &AlwaysInstall,
                          kIsFromSync,
                          install_source,
                          creation_flags,
                          mark_acknowledged,
                          kRemoteInstall);
}

void PendingExtensionManager::GetPendingIdsForUpdateCheck(
    std::list<std::string>* out_ids_for_update_check) const {
  PendingExtensionList::const_iterator iter;
  for (iter = pending_extension_list_.begin();
       iter != pending_extension_list_.end();
       ++iter) {
    Manifest::Location install_source = iter->install_source();

    // Some install sources read a CRX from the filesystem.  They can
    // not be fetched from an update URL, so don't include them in the
    // set of ids.
    if (install_source == Manifest::EXTERNAL_PREF ||
        install_source == Manifest::EXTERNAL_REGISTRY ||
        install_source == Manifest::EXTERNAL_POLICY) {
      continue;
    }

    out_ids_for_update_check->push_back(iter->id());
  }
}

bool PendingExtensionManager::AddExtensionImpl(
    const std::string& id,
    const std::string& install_parameter,
    const GURL& update_url,
    const base::Version& version,
    PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
    bool is_from_sync,
    Manifest::Location install_source,
    int creation_flags,
    bool mark_acknowledged,
    bool remote_install) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  PendingExtensionInfo info(id,
                            install_parameter,
                            update_url,
                            version,
                            should_allow_install,
                            is_from_sync,
                            install_source,
                            creation_flags,
                            mark_acknowledged,
                            remote_install);

  if (const PendingExtensionInfo* pending = GetById(id)) {
    // Bugs in this code will manifest as sporadic incorrect extension
    // locations in situations where multiple install sources run at the
    // same time. For example, on first login to a chrome os machine, an
    // extension may be requested by sync and the default extension set.
    // The following logging will help diagnose such issues.
    VLOG(1) << "Extension id " << id
            << " was entered for update more than once."
            << "  old location: " << pending->install_source()
            << "  new location: " << install_source
            << "  old version: " << GetVersionString(pending->version())
            << "  new version: " << GetVersionString(version);

    // Never override an existing extension with an older version. Only
    // extensions from local CRX files have a known version; extensions from an
    // update URL will get the latest version.

    // If |pending| has the same or higher precedence than |info| then don't
    // install |info| over |pending|.
    if (pending->CompareTo(info) >= 0)
      return false;

    VLOG(1) << "Overwrite existing record.";

    std::replace(pending_extension_list_.begin(),
                 pending_extension_list_.end(),
                 *pending,
                 info);
  } else {
    pending_extension_list_.push_back(info);
  }

  return true;
}

void PendingExtensionManager::AddForTesting(
    const PendingExtensionInfo& pending_extension_info) {
  pending_extension_list_.push_back(pending_extension_info);
}

}  // namespace extensions
