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

#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/pending_extension_manager.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension_set.h"

namespace extensions {

namespace {

ExtensionErrorController::UICreateMethod g_create_ui =
    ExtensionErrorUI::Create;

}

ExtensionErrorController::ExtensionErrorController(
    content::BrowserContext* context,
    bool is_first_run)
    : browser_context_(context),
      is_first_run_(is_first_run) {}

ExtensionErrorController::~ExtensionErrorController() {}

void ExtensionErrorController::ShowErrorIfNeeded() {
  IdentifyAlertableExtensions();

  // Make sure there's something to show, and that there isn't currently a
  // bubble displaying.
  if (!blacklisted_extensions_.is_empty() && !error_ui_.get()) {
    if (!is_first_run_) {
      error_ui_.reset(g_create_ui(this));
      if (!error_ui_->ShowErrorInBubbleView())  // Couldn't find a browser.
        error_ui_.reset();
    } else {
      // First run. Just acknowledge all the extensions, silently, by
      // shortcutting the display of the UI and going straight to the
      // callback for pressing the Accept button.
      OnAlertClosed();
    }
  }
}

// static
void ExtensionErrorController::SetUICreateMethodForTesting(
    UICreateMethod method) {
  g_create_ui = method;
}

content::BrowserContext* ExtensionErrorController::GetContext() {
  return browser_context_;
}

const ExtensionSet& ExtensionErrorController::GetExternalExtensions() {
  return external_extensions_;
}

const ExtensionSet& ExtensionErrorController::GetBlacklistedExtensions() {
  return blacklisted_extensions_;
}

void ExtensionErrorController::OnAlertAccept() {
  error_ui_->Close();
}

void ExtensionErrorController::OnAlertDetails() {
  error_ui_->ShowExtensions();

  // ShowExtensions() may cause the error UI to close synchronously, e.g. if it
  // causes a navigation.
  if (error_ui_)
    error_ui_->Close();
}

void ExtensionErrorController::OnAlertClosed() {
  ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_);
  for (ExtensionSet::const_iterator iter = blacklisted_extensions_.begin();
       iter != blacklisted_extensions_.end();
       ++iter) {
    prefs->AcknowledgeBlacklistedExtension((*iter)->id());
  }

  blacklisted_extensions_.Clear();
  error_ui_.reset();
}

void ExtensionErrorController::IdentifyAlertableExtensions() {
  ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
  ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_);

  // This should be clear, but in case a bubble crashed somewhere along the
  // line, let's make sure we start fresh.
  blacklisted_extensions_.Clear();

  // Build up the lists of extensions that require acknowledgment. If this is
  // the first time, grandfather extensions that would have caused
  // notification.

  const ExtensionSet& blacklisted_set = registry->blacklisted_extensions();
  for (ExtensionSet::const_iterator iter = blacklisted_set.begin();
       iter != blacklisted_set.end();
       ++iter) {
    if (!prefs->IsBlacklistedExtensionAcknowledged((*iter)->id()))
      blacklisted_extensions_.Insert(*iter);
  }

  ExtensionSystem* system = ExtensionSystem::Get(browser_context_);
  ManagementPolicy* management_policy = system->management_policy();
  PendingExtensionManager* pending_extension_manager =
      system->extension_service()->pending_extension_manager();
  const ExtensionSet& enabled_set = registry->enabled_extensions();

  for (ExtensionSet::const_iterator iter = enabled_set.begin();
       iter != enabled_set.end();
       ++iter) {
    const Extension* extension = iter->get();

    // Skip for extensions that have pending updates. They will be checked again
    // once the pending update is finished.
    if (pending_extension_manager->IsIdPending(extension->id()))
      continue;

    // Extensions disabled by policy. Note: this no longer includes blacklisted
    // extensions, though we still show the same UI.
    if (!management_policy->UserMayLoad(extension, NULL /* ignore error */)) {
      if (!prefs->IsBlacklistedExtensionAcknowledged(extension->id()))
        blacklisted_extensions_.Insert(extension);
    }
  }
}

}  // namespace extensions
