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

#include <stddef.h>
#include <utility>

#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/extension_install_error_menu_item_id_provider.h"
#include "chrome/browser/extensions/extension_install_prompt_show_params.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/external_install_error_constants.h"
#include "chrome/browser/extensions/external_install_manager.h"
#include "chrome/browser/extensions/webstore_data_fetcher.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/global_error/global_error.h"
#include "chrome/browser/ui/global_error/global_error_service.h"
#include "chrome/browser/ui/global_error/global_error_service_factory.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_features.h"
#include "chrome/grit/generated_resources.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/browser/storage_partition.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/uninstall_reason.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"

namespace extensions {

namespace {

// Return the menu label for a global error.
base::string16 GetMenuItemLabel(const Extension* extension) {
  if (!extension)
    return base::string16();

  int id = -1;
  if (extension->is_app())
    id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_APP;
  else if (extension->is_theme())
    id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_THEME;
  else
    id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_EXTENSION;

  return l10n_util::GetStringFUTF16(id, base::UTF8ToUTF16(extension->name()));
}

ExternalInstallError::DefaultDialogButtonSetting
MapDefaultButtonStringToSetting(const std::string& button_setting_string) {
  if (button_setting_string == kDefaultDialogButtonSettingOk)
    return ExternalInstallError::DIALOG_BUTTON_OK;
  if (button_setting_string == kDefaultDialogButtonSettingCancel)
    return ExternalInstallError::DIALOG_BUTTON_CANCEL;
  if (button_setting_string == kDefaultDialogButtonSettingNoDefault)
    return ExternalInstallError::NO_DEFAULT_DIALOG_BUTTON;

  NOTREACHED() << "Unexpected default button string: " << button_setting_string;
  return ExternalInstallError::NOT_SPECIFIED;
}

// A global error that spawns a dialog when the menu item is clicked.
class ExternalInstallMenuAlert : public GlobalError {
 public:
  explicit ExternalInstallMenuAlert(ExternalInstallError* error);
  ~ExternalInstallMenuAlert() override;

 private:
  // GlobalError implementation.
  Severity GetSeverity() override;
  bool HasMenuItem() override;
  int MenuItemCommandID() override;
  base::string16 MenuItemLabel() override;
  void ExecuteMenuItem(Browser* browser) override;
  bool HasBubbleView() override;
  bool HasShownBubbleView() override;
  void ShowBubbleView(Browser* browser) override;
  GlobalErrorBubbleViewBase* GetBubbleView() override;

  // The owning ExternalInstallError.
  ExternalInstallError* error_;

  // Provides menu item id for GlobalError.
  ExtensionInstallErrorMenuItemIdProvider id_provider_;

  DISALLOW_COPY_AND_ASSIGN(ExternalInstallMenuAlert);
};

// A global error that spawns a bubble when the menu item is clicked.
class ExternalInstallBubbleAlert : public GlobalErrorWithStandardBubble {
 public:
  ExternalInstallBubbleAlert(ExternalInstallError* error,
                             ExtensionInstallPrompt::Prompt* prompt);
  ~ExternalInstallBubbleAlert() override;

 private:
  // GlobalError implementation.
  Severity GetSeverity() override;
  bool HasMenuItem() override;
  int MenuItemCommandID() override;
  base::string16 MenuItemLabel() override;
  void ExecuteMenuItem(Browser* browser) override;

  // GlobalErrorWithStandardBubble implementation.
  gfx::Image GetBubbleViewIcon() override;
  base::string16 GetBubbleViewTitle() override;
  std::vector<base::string16> GetBubbleViewMessages() override;
  base::string16 GetBubbleViewAcceptButtonLabel() override;
  base::string16 GetBubbleViewCancelButtonLabel() override;
  int GetDefaultDialogButton() const override;
  void OnBubbleViewDidClose(Browser* browser) override;
  void BubbleViewAcceptButtonPressed(Browser* browser) override;
  void BubbleViewCancelButtonPressed(Browser* browser) override;

  // The owning ExternalInstallError.
  ExternalInstallError* error_;
  ExtensionInstallErrorMenuItemIdProvider id_provider_;

  // The Prompt with all information, which we then use to populate the bubble.
  // Owned by |error|.
  ExtensionInstallPrompt::Prompt* prompt_;

  DISALLOW_COPY_AND_ASSIGN(ExternalInstallBubbleAlert);
};

////////////////////////////////////////////////////////////////////////////////
// ExternalInstallMenuAlert

ExternalInstallMenuAlert::ExternalInstallMenuAlert(ExternalInstallError* error)
    : error_(error) {
}

ExternalInstallMenuAlert::~ExternalInstallMenuAlert() {
}

GlobalError::Severity ExternalInstallMenuAlert::GetSeverity() {
  return SEVERITY_LOW;
}

bool ExternalInstallMenuAlert::HasMenuItem() {
  return true;
}

int ExternalInstallMenuAlert::MenuItemCommandID() {
  return id_provider_.menu_command_id();
}

base::string16 ExternalInstallMenuAlert::MenuItemLabel() {
  return GetMenuItemLabel(error_->GetExtension());
}

void ExternalInstallMenuAlert::ExecuteMenuItem(Browser* browser) {
  error_->ShowDialog(browser);
}

bool ExternalInstallMenuAlert::HasBubbleView() {
  return false;
}

bool ExternalInstallMenuAlert::HasShownBubbleView() {
  NOTREACHED();
  return true;
}

void ExternalInstallMenuAlert::ShowBubbleView(Browser* browser) {
  NOTREACHED();
}

GlobalErrorBubbleViewBase* ExternalInstallMenuAlert::GetBubbleView() {
  return NULL;
}

////////////////////////////////////////////////////////////////////////////////
// ExternalInstallBubbleAlert

ExternalInstallBubbleAlert::ExternalInstallBubbleAlert(
    ExternalInstallError* error,
    ExtensionInstallPrompt::Prompt* prompt)
    : error_(error), prompt_(prompt) {
  DCHECK(error_);
  DCHECK(prompt_);
}

ExternalInstallBubbleAlert::~ExternalInstallBubbleAlert() {
}

GlobalError::Severity ExternalInstallBubbleAlert::GetSeverity() {
  return SEVERITY_LOW;
}

bool ExternalInstallBubbleAlert::HasMenuItem() {
  return true;
}

int ExternalInstallBubbleAlert::MenuItemCommandID() {
  return id_provider_.menu_command_id();
}

base::string16 ExternalInstallBubbleAlert::MenuItemLabel() {
  return GetMenuItemLabel(error_->GetExtension());
}

void ExternalInstallBubbleAlert::ExecuteMenuItem(Browser* browser) {
  // |browser| is nullptr in unit test.
  if (browser)
    ShowBubbleView(browser);
  error_->DidOpenBubbleView();
}

gfx::Image ExternalInstallBubbleAlert::GetBubbleViewIcon() {
  if (prompt_->icon().IsEmpty())
    return GlobalErrorWithStandardBubble::GetBubbleViewIcon();
  // Scale icon to a reasonable size.
  return gfx::Image(gfx::ImageSkiaOperations::CreateResizedImage(
      *prompt_->icon().ToImageSkia(),
      skia::ImageOperations::RESIZE_BEST,
      gfx::Size(extension_misc::EXTENSION_ICON_SMALL,
                extension_misc::EXTENSION_ICON_SMALL)));
}

base::string16 ExternalInstallBubbleAlert::GetBubbleViewTitle() {
  return l10n_util::GetStringFUTF16(
      IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_BUBBLE_TITLE,
      base::UTF8ToUTF16(prompt_->extension()->name()));
}

std::vector<base::string16>
ExternalInstallBubbleAlert::GetBubbleViewMessages() {
  std::vector<base::string16> messages;
  int heading_id =
      IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_BUBBLE_HEADING_EXTENSION;
  if (prompt_->extension()->is_app())
    heading_id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_BUBBLE_HEADING_APP;
  else if (prompt_->extension()->is_theme())
    heading_id = IDS_EXTENSION_EXTERNAL_INSTALL_ALERT_BUBBLE_HEADING_THEME;
  messages.push_back(l10n_util::GetStringUTF16(heading_id));

  if (prompt_->GetPermissionCount()) {
    messages.push_back(prompt_->GetPermissionsHeading());
    for (size_t i = 0; i < prompt_->GetPermissionCount(); ++i) {
      messages.push_back(l10n_util::GetStringFUTF16(
          IDS_EXTENSION_PERMISSION_LINE, prompt_->GetPermission(i)));
    }
  }
  // TODO(yoz): OAuth issue advice?
  return messages;
}

int ExternalInstallBubbleAlert::GetDefaultDialogButton() const {
  switch (error_->default_dialog_button_setting()) {
    case ExternalInstallError::DIALOG_BUTTON_OK:
      return ui::DIALOG_BUTTON_OK;
    case ExternalInstallError::DIALOG_BUTTON_CANCEL:
      return ui::DIALOG_BUTTON_CANCEL;
    case ExternalInstallError::NO_DEFAULT_DIALOG_BUTTON:
      return ui::DIALOG_BUTTON_NONE;
    case ExternalInstallError::NOT_SPECIFIED:
      break;
  }
  return GlobalErrorWithStandardBubble::GetDefaultDialogButton();
}

base::string16 ExternalInstallBubbleAlert::GetBubbleViewAcceptButtonLabel() {
  return prompt_->GetAcceptButtonLabel();
}

base::string16 ExternalInstallBubbleAlert::GetBubbleViewCancelButtonLabel() {
  return prompt_->GetAbortButtonLabel();
}

void ExternalInstallBubbleAlert::OnBubbleViewDidClose(Browser* browser) {
  error_->DidCloseBubbleView();
}

void ExternalInstallBubbleAlert::BubbleViewAcceptButtonPressed(
    Browser* browser) {
  error_->OnInstallPromptDone(ExtensionInstallPrompt::Result::ACCEPTED);
}

void ExternalInstallBubbleAlert::BubbleViewCancelButtonPressed(
    Browser* browser) {
  error_->OnInstallPromptDone(ExtensionInstallPrompt::Result::USER_CANCELED);
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// ExternalInstallError

// static
ExternalInstallError::DefaultDialogButtonSetting
ExternalInstallError::GetDefaultDialogButton(
    const base::Value& webstore_response) {
  const base::Value* value = webstore_response.FindKeyOfType(
      kExternalInstallDefaultButtonKey, base::Value::Type::STRING);
  if (value) {
    return MapDefaultButtonStringToSetting(value->GetString());
  }

  if (base::FeatureList::IsEnabled(
          ::features::kExternalExtensionDefaultButtonControl)) {
    std::string default_button = base::GetFieldTrialParamValueByFeature(
        ::features::kExternalExtensionDefaultButtonControl,
        kExternalInstallDefaultButtonKey);
    if (!default_button.empty()) {
      return MapDefaultButtonStringToSetting(default_button);
    }
  }

  return NOT_SPECIFIED;
}

ExternalInstallError::ExternalInstallError(
    content::BrowserContext* browser_context,
    const std::string& extension_id,
    AlertType alert_type,
    ExternalInstallManager* manager)
    : browser_context_(browser_context),
      extension_id_(extension_id),
      alert_type_(alert_type),
      manager_(manager),
      error_service_(GlobalErrorServiceFactory::GetForProfile(
          Profile::FromBrowserContext(browser_context_))),
      weak_factory_(this) {
  prompt_.reset(new ExtensionInstallPrompt::Prompt(
      ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT));

  webstore_data_fetcher_.reset(
      new WebstoreDataFetcher(this, GURL(), extension_id_));
  webstore_data_fetcher_->Start(
      content::BrowserContext::GetDefaultStoragePartition(browser_context_)
          ->GetURLLoaderFactoryForBrowserProcess()
          .get());
}

ExternalInstallError::~ExternalInstallError() {
#if DCHECK_IS_ON()
  // Errors should only be removed while the profile is valid, since removing
  // the error can trigger other subsystems listening for changes.
  BrowserContextDependencyManager::GetInstance()
      ->AssertBrowserContextWasntDestroyed(browser_context_);
#endif
  if (global_error_.get())
    error_service_->RemoveUnownedGlobalError(global_error_.get());
}

void ExternalInstallError::OnInstallPromptDone(
    ExtensionInstallPrompt::Result result) {
  const Extension* extension = GetExtension();

  // If the error isn't removed and deleted as part of handling the user's
  // response (which can happen, e.g., if an uninstall fails), be sure to remove
  // the error directly in order to ensure it's not called twice.
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&ExternalInstallError::RemoveError,
                                weak_factory_.GetWeakPtr()));

  switch (result) {
    case ExtensionInstallPrompt::Result::ACCEPTED:
      if (extension) {
        ExtensionSystem::Get(browser_context_)
            ->extension_service()
            ->GrantPermissionsAndEnableExtension(extension);
      }
      break;
    case ExtensionInstallPrompt::Result::USER_CANCELED:
      if (extension) {
        bool uninstallation_result = ExtensionSystem::Get(browser_context_)
            ->extension_service()
            ->UninstallExtension(extension_id_,
                                 extensions::UNINSTALL_REASON_INSTALL_CANCELED,
                                 nullptr);  // Ignore error.
        UMA_HISTOGRAM_BOOLEAN("Extensions.ExternalWarningUninstallationResult",
                              uninstallation_result);
      }
      break;
    case ExtensionInstallPrompt::Result::ABORTED:
      manager_->DidChangeInstallAlertVisibility(this, false);
      break;
  }
  // NOTE: We may be deleted here!
}

void ExternalInstallError::DidOpenBubbleView() {
  manager_->DidChangeInstallAlertVisibility(this, true);
}

void ExternalInstallError::DidCloseBubbleView() {
  manager_->DidChangeInstallAlertVisibility(this, false);
}

void ExternalInstallError::ShowDialog(Browser* browser) {
  DCHECK(install_ui_.get());
  DCHECK(prompt_.get());
  DCHECK(browser);
  content::WebContents* web_contents = NULL;
  web_contents = browser->tab_strip_model()->GetActiveWebContents();
  install_ui_show_params_.reset(
      new ExtensionInstallPromptShowParams(web_contents));
  manager_->DidChangeInstallAlertVisibility(this, true);
  ExtensionInstallPrompt::GetDefaultShowDialogCallback().Run(
      install_ui_show_params_.get(),
      base::Bind(&ExternalInstallError::OnInstallPromptDone,
                 weak_factory_.GetWeakPtr()),
      std::move(prompt_));
}

const Extension* ExternalInstallError::GetExtension() const {
  return ExtensionRegistry::Get(browser_context_)
      ->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING);
}

void ExternalInstallError::OnWebstoreRequestFailure() {
  OnFetchComplete();
}

void ExternalInstallError::OnWebstoreResponseParseSuccess(
    std::unique_ptr<base::DictionaryValue> webstore_data) {
  std::string localized_user_count;
  double average_rating = 0;
  int rating_count = 0;
  if (!webstore_data->GetString(kUsersKey, &localized_user_count) ||
      !webstore_data->GetDouble(kAverageRatingKey, &average_rating) ||
      !webstore_data->GetInteger(kRatingCountKey, &rating_count)) {
    // If we don't get a valid webstore response, short circuit, and continue
    // to show a prompt without webstore data.
    OnFetchComplete();
    return;
  }

  default_dialog_button_setting_ = GetDefaultDialogButton(*webstore_data.get());

  bool show_user_count = true;
  webstore_data->GetBoolean(kShowUserCountKey, &show_user_count);

  prompt_->SetWebstoreData(
      localized_user_count, show_user_count, average_rating, rating_count);
  OnFetchComplete();
}

void ExternalInstallError::OnWebstoreResponseParseFailure(
    const std::string& error) {
  OnFetchComplete();
}

void ExternalInstallError::OnFetchComplete() {
  // Create a new ExtensionInstallPrompt. We pass in NULL for the UI
  // components because we display at a later point, and don't want
  // to pass ones which may be invalidated.
  install_ui_.reset(
      new ExtensionInstallPrompt(Profile::FromBrowserContext(browser_context_),
                                 NULL));  // NULL native window.

  install_ui_->ShowDialog(base::Bind(&ExternalInstallError::OnInstallPromptDone,
                                     weak_factory_.GetWeakPtr()),
                          GetExtension(),
                          nullptr,  // Force a fetch of the icon.
                          std::move(prompt_),
                          base::Bind(&ExternalInstallError::OnDialogReady,
                                     weak_factory_.GetWeakPtr()));
}

void ExternalInstallError::OnDialogReady(
    ExtensionInstallPromptShowParams* show_params,
    const ExtensionInstallPrompt::DoneCallback& callback,
    std::unique_ptr<ExtensionInstallPrompt::Prompt> prompt) {
  prompt_ = std::move(prompt);

  if (alert_type_ == BUBBLE_ALERT) {
    global_error_.reset(new ExternalInstallBubbleAlert(this, prompt_.get()));
    error_service_->AddUnownedGlobalError(global_error_.get());

    if (!manager_->has_currently_visible_install_alert()) {
      // |browser| is nullptr during unit tests, so call
      // DidChangeInstallAlertVisibility() regardless because we depend on this
      // in unit tests.
      manager_->DidChangeInstallAlertVisibility(this, true);
      Browser* browser = chrome::FindTabbedBrowser(
          Profile::FromBrowserContext(browser_context_), true);
      if (browser)
        global_error_->ShowBubbleView(browser);
    }
  } else {
    DCHECK(alert_type_ == MENU_ALERT);
    global_error_.reset(new ExternalInstallMenuAlert(this));
    error_service_->AddUnownedGlobalError(global_error_.get());
  }
}

void ExternalInstallError::RemoveError() {
  manager_->RemoveExternalInstallError(extension_id_);
}

}  // namespace extensions
