// Copyright 2014 The Chromium Authors
// 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_error_controller_factory.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/management_policy.h"
#include "extensions/browser/pending_extension_manager.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/extension_set.h"

#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/extensions/extension_error_ui_android.h"
#else
#include "chrome/browser/extensions/extension_error_ui_desktop.h"
#endif

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

namespace extensions {

namespace {

ExtensionErrorUI* CreateDefaultExtensionErrorUI(
    ExtensionErrorUI::Delegate* delegate) {
#if BUILDFLAG(IS_ANDROID)
  return new ExtensionErrorUIAndroid(delegate);
#else
  return new ExtensionErrorUIDesktop(delegate);
#endif
}

ExtensionErrorController::UICreateMethod g_create_ui =
    CreateDefaultExtensionErrorUI;
}  // namespace

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

ExtensionErrorController::~ExtensionErrorController() = default;

// static
ExtensionErrorController* ExtensionErrorController::Get(
    content::BrowserContext* browser_context) {
  return ExtensionErrorControllerFactory::GetForBrowserContext(browser_context);
}

void ExtensionErrorController::ShowErrorIfNeeded() {
  if (error_ui_.get()) {
    return;
  }

  IdentifyAlertableExtensions();

  // Make sure there's something to show, and that there isn't currently a
  // bubble displaying.
  if (!blocklisted_extensions_.empty()) {
    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::GetBlocklistedExtensions() {
  return blocklisted_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 = blocklisted_extensions_.begin();
       iter != blocklisted_extensions_.end(); ++iter) {
    prefs->AcknowledgeBlocklistedExtension((*iter)->id());
  }

  blocklisted_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.
  blocklisted_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& blocklisted_set = registry->blocklisted_extensions();
  for (ExtensionSet::const_iterator iter = blocklisted_set.begin();
       iter != blocklisted_set.end(); ++iter) {
    if (!prefs->IsBlocklistedExtensionAcknowledged((*iter)->id()))
      blocklisted_extensions_.Insert(*iter);
  }

  ExtensionSystem* system = ExtensionSystem::Get(browser_context_);
  ManagementPolicy* management_policy = system->management_policy();

  PendingExtensionManager* pending_extension_manager =
      PendingExtensionManager::Get(browser_context_);
  // We only show the error UI for the enabled set. This means that an
  // extension that is blocked while browser is not running will never
  // be displayed in the UI.
  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 blocklisted
    // extensions. We use similar triggering logic for the dialog, but the
    // strings will be different.
    if (!management_policy->UserMayLoad(extension) &&
        !prefs->IsBlocklistedExtensionAcknowledged(extension->id())) {
      blocklisted_extensions_.Insert(extension);
    }
  }
}

}  // namespace extensions
