// Copyright (c) 2011 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/extensions_ui.h"

#include <algorithm>

#include "base/base64.h"
#include "base/callback.h"
#include "base/file_util.h"
#include "base/memory/singleton.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/threading/thread.h"
#include "base/utf_string_conversions.h"
#include "base/version.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_toggle_action.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_disabled_infobar_delegate.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_updater.h"
#include "chrome/browser/google/google_util.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/background_contents.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/webui/extension_icon_source.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_icon_set.h"
#include "chrome/common/extensions/url_pattern.h"
#include "chrome/common/extensions/user_script.h"
#include "chrome/common/jstemplate_builder.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_widget_host.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/tab_contents/tab_contents_view.h"
#include "content/common/notification_service.h"
#include "content/common/notification_type.h"
#include "googleurl/src/gurl.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "net/base/net_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"

namespace {

bool ShouldShowExtension(const Extension* extension) {
  // Don't show themes since this page's UI isn't really useful for themes.
  if (extension->is_theme())
    return false;

  // Don't show component extensions because they are only extensions as an
  // implementation detail of Chrome.
  if (extension->location() == Extension::COMPONENT)
    return false;

  // Always show unpacked extensions and apps.
  if (extension->location() == Extension::LOAD)
    return true;

  // Unless they are unpacked, never show hosted apps.
  if (extension->is_hosted_app())
    return false;

  return true;
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
//
// ExtensionsHTMLSource
//
////////////////////////////////////////////////////////////////////////////////

ExtensionsUIHTMLSource::ExtensionsUIHTMLSource()
    : DataSource(chrome::kChromeUIExtensionsHost, MessageLoop::current()) {
}

void ExtensionsUIHTMLSource::StartDataRequest(const std::string& path,
    bool is_incognito, int request_id) {
  DictionaryValue localized_strings;
  localized_strings.SetString("title",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_TITLE));
  localized_strings.SetString("devModeLink",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_DEVELOPER_MODE_LINK));
  localized_strings.SetString("devModePrefix",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_DEVELOPER_MODE_PREFIX));
  localized_strings.SetString("loadUnpackedButton",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOAD_UNPACKED_BUTTON));
  localized_strings.SetString("packButton",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_PACK_BUTTON));
  localized_strings.SetString("updateButton",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_UPDATE_BUTTON));
  localized_strings.SetString("noExtensions",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_NONE_INSTALLED));
  localized_strings.SetString("suggestGallery",
      l10n_util::GetStringFUTF16(IDS_EXTENSIONS_NONE_INSTALLED_SUGGEST_GALLERY,
          ASCIIToUTF16("<a href='") +
              ASCIIToUTF16(google_util::AppendGoogleLocaleParam(
                  GURL(Extension::ChromeStoreLaunchURL())).spec()) +
              ASCIIToUTF16("'>"),
          ASCIIToUTF16("</a>")));
  localized_strings.SetString("getMoreExtensions",
      ASCIIToUTF16("<a href='") +
      ASCIIToUTF16(google_util::AppendGoogleLocaleParam(
          GURL(Extension::ChromeStoreLaunchURL())).spec()) +
      ASCIIToUTF16("'>") +
      l10n_util::GetStringUTF16(IDS_GET_MORE_EXTENSIONS) +
      ASCIIToUTF16("</a>"));
  localized_strings.SetString("extensionCrashed",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_CRASHED_EXTENSION));
  localized_strings.SetString("extensionDisabled",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_DISABLED_EXTENSION));
  localized_strings.SetString("inDevelopment",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_IN_DEVELOPMENT));
  localized_strings.SetString("viewIncognito",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_VIEW_INCOGNITO));
  localized_strings.SetString("extensionId",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_ID));
  localized_strings.SetString("extensionPath",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_PATH));
  localized_strings.SetString("extensionVersion",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_VERSION));
  localized_strings.SetString("inspectViews",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_INSPECT_VIEWS));
  localized_strings.SetString("inspectPopupsInstructions",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_INSPECT_POPUPS_INSTRUCTIONS));
  localized_strings.SetString("disable",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_DISABLE));
  localized_strings.SetString("enable",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_ENABLE));
  localized_strings.SetString("enableIncognito",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_ENABLE_INCOGNITO));
  localized_strings.SetString("allowFileAccess",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_ALLOW_FILE_ACCESS));
  localized_strings.SetString("incognitoWarning",
      l10n_util::GetStringFUTF16(IDS_EXTENSIONS_INCOGNITO_WARNING,
                                 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
  localized_strings.SetString("reload",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_RELOAD));
  localized_strings.SetString("uninstall",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL));
  localized_strings.SetString("options",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_OPTIONS));
  localized_strings.SetString("policyControlled",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_POLICY_CONTROLLED));
  localized_strings.SetString("packDialogTitle",
      l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_TITLE));
  localized_strings.SetString("packDialogHeading",
      l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_HEADING));
  localized_strings.SetString("rootDirectoryLabel",
      l10n_util::GetStringUTF16(
          IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL));
  localized_strings.SetString("packDialogBrowse",
      l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_BROWSE));
  localized_strings.SetString("privateKeyLabel",
      l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL));
  localized_strings.SetString("okButton",
      l10n_util::GetStringUTF16(IDS_OK));
  localized_strings.SetString("cancelButton",
      l10n_util::GetStringUTF16(IDS_CANCEL));
  localized_strings.SetString("showButton",
      l10n_util::GetStringUTF16(IDS_EXTENSIONS_SHOW_BUTTON));

  SetFontAndTextDirection(&localized_strings);

  static const base::StringPiece extensions_html(
      ResourceBundle::GetSharedInstance().GetRawDataResource(
          IDR_EXTENSIONS_UI_HTML));
  std::string full_html(extensions_html.data(), extensions_html.size());
  jstemplate_builder::AppendJsonHtml(&localized_strings, &full_html);
  jstemplate_builder::AppendI18nTemplateSourceHtml(&full_html);
  jstemplate_builder::AppendI18nTemplateProcessHtml(&full_html);
  jstemplate_builder::AppendJsTemplateSourceHtml(&full_html);

  scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
  html_bytes->data.resize(full_html.size());
  std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());

  SendResponse(request_id, html_bytes);
}

std::string ExtensionsUIHTMLSource::GetMimeType(const std::string&) const {
  return "text/html";
}

///////////////////////////////////////////////////////////////////////////////
//
// ExtensionsDOMHandler
//
///////////////////////////////////////////////////////////////////////////////

ExtensionsDOMHandler::ExtensionsDOMHandler(ExtensionService* extension_service)
    : extensions_service_(extension_service),
      ignore_notifications_(false),
      deleting_rvh_(NULL) {
  RegisterForNotifications();
}

void ExtensionsDOMHandler::RegisterMessages() {
  web_ui_->RegisterMessageCallback("requestExtensionsData",
      NewCallback(this, &ExtensionsDOMHandler::HandleRequestExtensionsData));
  web_ui_->RegisterMessageCallback("toggleDeveloperMode",
      NewCallback(this, &ExtensionsDOMHandler::HandleToggleDeveloperMode));
  web_ui_->RegisterMessageCallback("inspect",
      NewCallback(this, &ExtensionsDOMHandler::HandleInspectMessage));
  web_ui_->RegisterMessageCallback("reload",
      NewCallback(this, &ExtensionsDOMHandler::HandleReloadMessage));
  web_ui_->RegisterMessageCallback("enable",
      NewCallback(this, &ExtensionsDOMHandler::HandleEnableMessage));
  web_ui_->RegisterMessageCallback("enableIncognito",
      NewCallback(this, &ExtensionsDOMHandler::HandleEnableIncognitoMessage));
  web_ui_->RegisterMessageCallback("allowFileAccess",
      NewCallback(this, &ExtensionsDOMHandler::HandleAllowFileAccessMessage));
  web_ui_->RegisterMessageCallback("uninstall",
      NewCallback(this, &ExtensionsDOMHandler::HandleUninstallMessage));
  web_ui_->RegisterMessageCallback("options",
      NewCallback(this, &ExtensionsDOMHandler::HandleOptionsMessage));
  web_ui_->RegisterMessageCallback("showButton",
      NewCallback(this, &ExtensionsDOMHandler::HandleShowButtonMessage));
  web_ui_->RegisterMessageCallback("load",
      NewCallback(this, &ExtensionsDOMHandler::HandleLoadMessage));
  web_ui_->RegisterMessageCallback("pack",
      NewCallback(this, &ExtensionsDOMHandler::HandlePackMessage));
  web_ui_->RegisterMessageCallback("autoupdate",
      NewCallback(this, &ExtensionsDOMHandler::HandleAutoUpdateMessage));
  web_ui_->RegisterMessageCallback("selectFilePath",
      NewCallback(this, &ExtensionsDOMHandler::HandleSelectFilePathMessage));
}

void ExtensionsDOMHandler::HandleRequestExtensionsData(const ListValue* args) {
  DictionaryValue results;

  // Add the extensions to the results structure.
  ListValue* extensions_list = new ListValue();

  const ExtensionList* extensions = extensions_service_->extensions();
  for (ExtensionList::const_iterator extension = extensions->begin();
       extension != extensions->end(); ++extension) {
    if (ShouldShowExtension(*extension)) {
      extensions_list->Append(CreateExtensionDetailValue(
          extensions_service_.get(),
          *extension,
          GetActivePagesForExtension(*extension),
          true, false));  // enabled, terminated
    }
  }
  extensions = extensions_service_->disabled_extensions();
  for (ExtensionList::const_iterator extension = extensions->begin();
       extension != extensions->end(); ++extension) {
    if (ShouldShowExtension(*extension)) {
      extensions_list->Append(CreateExtensionDetailValue(
          extensions_service_.get(),
          *extension,
          GetActivePagesForExtension(*extension),
          false, false));  // enabled, terminated
    }
  }
  extensions = extensions_service_->terminated_extensions();
  std::vector<ExtensionPage> empty_pages;
  for (ExtensionList::const_iterator extension = extensions->begin();
       extension != extensions->end(); ++extension) {
    if (ShouldShowExtension(*extension)) {
      extensions_list->Append(CreateExtensionDetailValue(
          extensions_service_.get(),
          *extension,
          empty_pages,  // Terminated process has no active pages.
          false, true));  // enabled, terminated
    }
  }
  results.Set("extensions", extensions_list);

  bool developer_mode = web_ui_->GetProfile()->GetPrefs()
      ->GetBoolean(prefs::kExtensionsUIDeveloperMode);
  results.SetBoolean("developerMode", developer_mode);

  web_ui_->CallJavascriptFunction("returnExtensionsData", results);
}

void ExtensionsDOMHandler::RegisterForNotifications() {
  // Register for notifications that we need to reload the page.
  registrar_.Add(this, NotificationType::EXTENSION_LOADED,
      NotificationService::AllSources());
  registrar_.Add(this, NotificationType::EXTENSION_PROCESS_CREATED,
      NotificationService::AllSources());
  registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
      NotificationService::AllSources());
  registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
      NotificationService::AllSources());
  registrar_.Add(this, NotificationType::EXTENSION_FUNCTION_DISPATCHER_CREATED,
      NotificationService::AllSources());
  registrar_.Add(this,
      NotificationType::EXTENSION_FUNCTION_DISPATCHER_DESTROYED,
      NotificationService::AllSources());
  registrar_.Add(this,
      NotificationType::NAV_ENTRY_COMMITTED,
      NotificationService::AllSources());
  registrar_.Add(this,
      NotificationType::RENDER_VIEW_HOST_DELETED,
      NotificationService::AllSources());
  registrar_.Add(this,
      NotificationType::BACKGROUND_CONTENTS_NAVIGATED,
      NotificationService::AllSources());
  registrar_.Add(this,
      NotificationType::BACKGROUND_CONTENTS_DELETED,
      NotificationService::AllSources());
  registrar_.Add(this,
      NotificationType::EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
      NotificationService::AllSources());
}

ExtensionUninstallDialog* ExtensionsDOMHandler::GetExtensionUninstallDialog() {
  if (!extension_uninstall_dialog_.get()) {
    extension_uninstall_dialog_.reset(
        new ExtensionUninstallDialog(web_ui_->GetProfile()));
  }
  return extension_uninstall_dialog_.get();
}

void ExtensionsDOMHandler::HandleToggleDeveloperMode(const ListValue* args) {
  bool developer_mode = web_ui_->GetProfile()->GetPrefs()
      ->GetBoolean(prefs::kExtensionsUIDeveloperMode);
  web_ui_->GetProfile()->GetPrefs()->SetBoolean(
      prefs::kExtensionsUIDeveloperMode, !developer_mode);
}

void ExtensionsDOMHandler::HandleInspectMessage(const ListValue* args) {
  std::string render_process_id_str;
  std::string render_view_id_str;
  int render_process_id;
  int render_view_id;
  CHECK(args->GetSize() == 2);
  CHECK(args->GetString(0, &render_process_id_str));
  CHECK(args->GetString(1, &render_view_id_str));
  CHECK(base::StringToInt(render_process_id_str, &render_process_id));
  CHECK(base::StringToInt(render_view_id_str, &render_view_id));
  RenderViewHost* host = RenderViewHost::FromID(render_process_id,
                                                render_view_id);
  if (!host) {
    // This can happen if the host has gone away since the page was displayed.
    return;
  }

  DevToolsManager::GetInstance()->OpenDevToolsWindow(host);
}

void ExtensionsDOMHandler::HandleReloadMessage(const ListValue* args) {
  std::string extension_id = UTF16ToASCII(ExtractStringValue(args));
  CHECK(!extension_id.empty());
  extensions_service_->ReloadExtension(extension_id);
}

void ExtensionsDOMHandler::HandleEnableMessage(const ListValue* args) {
  CHECK(args->GetSize() == 2);
  std::string extension_id, enable_str;
  CHECK(args->GetString(0, &extension_id));
  CHECK(args->GetString(1, &enable_str));
  const Extension* extension =
      extensions_service_->GetExtensionById(extension_id, true);
  DCHECK(extension);
  if (!Extension::UserMayDisable(extension->location())) {
    LOG(ERROR) << "Attempt to enable an extension that is non-usermanagable was"
               << "made. Extension id: " << extension->id();
    return;
  }

  if (enable_str == "true") {
    ExtensionPrefs* prefs = extensions_service_->extension_prefs();
    if (prefs->DidExtensionEscalatePermissions(extension_id)) {
      ShowExtensionDisabledDialog(extensions_service_,
                                  web_ui_->GetProfile(), extension);
    } else {
      extensions_service_->EnableExtension(extension_id);
    }
  } else {
    extensions_service_->DisableExtension(extension_id);
  }
}

void ExtensionsDOMHandler::HandleEnableIncognitoMessage(const ListValue* args) {
  CHECK(args->GetSize() == 2);
  std::string extension_id, enable_str;
  CHECK(args->GetString(0, &extension_id));
  CHECK(args->GetString(1, &enable_str));
  const Extension* extension =
      extensions_service_->GetExtensionById(extension_id, true);
  DCHECK(extension);

  // Flipping the incognito bit will generate unload/load notifications for the
  // extension, but we don't want to reload the page, because a) we've already
  // updated the UI to reflect the change, and b) we want the yellow warning
  // text to stay until the user has left the page.
  //
  // TODO(aa): This creates crapiness in some cases. For example, in a main
  // window, when toggling this, the browser action will flicker because it gets
  // unloaded, then reloaded. It would be better to have a dedicated
  // notification for this case.
  //
  // Bug: http://crbug.com/41384
  ignore_notifications_ = true;
  extensions_service_->SetIsIncognitoEnabled(extension_id,
                                             enable_str == "true");
  ignore_notifications_ = false;
}

void ExtensionsDOMHandler::HandleAllowFileAccessMessage(const ListValue* args) {
  CHECK(args->GetSize() == 2);
  std::string extension_id, allow_str;
  CHECK(args->GetString(0, &extension_id));
  CHECK(args->GetString(1, &allow_str));
  const Extension* extension =
      extensions_service_->GetExtensionById(extension_id, true);
  DCHECK(extension);
  if (!Extension::UserMayDisable(extension->location())) {
    LOG(ERROR) << "Attempt to change allow file access of an extension that is "
               << "non-usermanagable was made. Extension id : "
               << extension->id();
    return;
  }

  extensions_service_->SetAllowFileAccess(extension, allow_str == "true");
}

void ExtensionsDOMHandler::HandleUninstallMessage(const ListValue* args) {
  std::string extension_id = UTF16ToASCII(ExtractStringValue(args));
  CHECK(!extension_id.empty());
  const Extension* extension =
      extensions_service_->GetExtensionById(extension_id, true);
  if (!extension)
    extension = extensions_service_->GetTerminatedExtension(extension_id);
  if (!extension)
    return;

  if (!Extension::UserMayDisable(extension->location())) {
    LOG(ERROR) << "Attempt to uninstall an extension that is non-usermanagable "
               << "was made. Extension id : " << extension->id();
    return;
  }

  if (!extension_id_prompting_.empty())
    return;  // Only one prompt at a time.

  extension_id_prompting_ = extension_id;

  GetExtensionUninstallDialog()->ConfirmUninstall(this, extension);
}

void ExtensionsDOMHandler::ExtensionDialogAccepted() {
  DCHECK(!extension_id_prompting_.empty());

  bool was_terminated = false;

  // The extension can be uninstalled in another window while the UI was
  // showing. Do nothing in that case.
  const Extension* extension =
      extensions_service_->GetExtensionById(extension_id_prompting_, true);
  if (!extension) {
    extension = extensions_service_->GetTerminatedExtension(
        extension_id_prompting_);
    was_terminated = true;
  }
  if (!extension)
    return;

  extensions_service_->UninstallExtension(extension_id_prompting_,
                                          false /* external_uninstall */, NULL);
  extension_id_prompting_ = "";

  // There will be no EXTENSION_UNLOADED notification for terminated
  // extensions as they were already unloaded.
  if (was_terminated)
    HandleRequestExtensionsData(NULL);
}

void ExtensionsDOMHandler::ExtensionDialogCanceled() {
  extension_id_prompting_ = "";
}

void ExtensionsDOMHandler::HandleOptionsMessage(const ListValue* args) {
  const Extension* extension = GetExtension(args);
  if (!extension || extension->options_url().is_empty())
    return;
  web_ui_->GetProfile()->GetExtensionProcessManager()->OpenOptionsPage(
      extension, NULL);
}

void ExtensionsDOMHandler::HandleShowButtonMessage(const ListValue* args) {
  const Extension* extension = GetExtension(args);
  extensions_service_->SetBrowserActionVisibility(extension, true);
}

void ExtensionsDOMHandler::HandleLoadMessage(const ListValue* args) {
  FilePath::StringType string_path;
  CHECK(args->GetSize() == 1) << args->GetSize();
  CHECK(args->GetString(0, &string_path));
  extensions_service_->LoadExtension(FilePath(string_path));
}

void ExtensionsDOMHandler::ShowAlert(const std::string& message) {
  ListValue arguments;
  arguments.Append(Value::CreateStringValue(message));
  web_ui_->CallJavascriptFunction("alert", arguments);
}

void ExtensionsDOMHandler::HandlePackMessage(const ListValue* args) {
  std::string extension_path;
  std::string private_key_path;
  CHECK(args->GetSize() == 2);
  CHECK(args->GetString(0, &extension_path));
  CHECK(args->GetString(1, &private_key_path));

  FilePath root_directory =
      FilePath::FromWStringHack(UTF8ToWide(extension_path));
  FilePath key_file = FilePath::FromWStringHack(UTF8ToWide(private_key_path));

  if (root_directory.empty()) {
    if (extension_path.empty()) {
      ShowAlert(l10n_util::GetStringUTF8(
          IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED));
    } else {
      ShowAlert(l10n_util::GetStringUTF8(
          IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID));
    }

    return;
  }

  if (!private_key_path.empty() && key_file.empty()) {
    ShowAlert(l10n_util::GetStringUTF8(
        IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID));
    return;
  }

  pack_job_ = new PackExtensionJob(this, root_directory, key_file);
  pack_job_->Start();
}

void ExtensionsDOMHandler::OnPackSuccess(const FilePath& crx_file,
                                         const FilePath& pem_file) {
  ShowAlert(UTF16ToUTF8(PackExtensionJob::StandardSuccessMessage(crx_file,
                                                                 pem_file)));

  ListValue results;
  web_ui_->CallJavascriptFunction("hidePackDialog", results);
}

void ExtensionsDOMHandler::OnPackFailure(const std::string& error) {
  ShowAlert(error);
}

void ExtensionsDOMHandler::HandleAutoUpdateMessage(const ListValue* args) {
  ExtensionUpdater* updater = extensions_service_->updater();
  if (updater)
    updater->CheckNow();
}

void ExtensionsDOMHandler::HandleSelectFilePathMessage(const ListValue* args) {
  std::string select_type;
  std::string operation;
  CHECK(args->GetSize() == 2);
  CHECK(args->GetString(0, &select_type));
  CHECK(args->GetString(1, &operation));

  SelectFileDialog::Type type = SelectFileDialog::SELECT_FOLDER;
  static SelectFileDialog::FileTypeInfo info;
  int file_type_index = 0;
  if (select_type == "file")
    type = SelectFileDialog::SELECT_OPEN_FILE;

  string16 select_title;
  if (operation == "load") {
    select_title = l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY);
  } else if (operation == "packRoot") {
    select_title = l10n_util::GetStringUTF16(
        IDS_EXTENSION_PACK_DIALOG_SELECT_ROOT);
  } else if (operation == "pem") {
    select_title = l10n_util::GetStringUTF16(
        IDS_EXTENSION_PACK_DIALOG_SELECT_KEY);
    info.extensions.push_back(std::vector<FilePath::StringType>());
        info.extensions.front().push_back(FILE_PATH_LITERAL("pem"));
        info.extension_description_overrides.push_back(
            l10n_util::GetStringUTF16(
                IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION));
        info.include_all_files = true;
    file_type_index = 1;
  } else {
    NOTREACHED();
    return;
  }

  load_extension_dialog_ = SelectFileDialog::Create(this);
  load_extension_dialog_->SelectFile(type, select_title, FilePath(), &info,
      file_type_index, FILE_PATH_LITERAL(""), web_ui_->tab_contents(),
      web_ui_->tab_contents()->view()->GetTopLevelNativeWindow(), NULL);
}


void ExtensionsDOMHandler::FileSelected(const FilePath& path, int index,
                                        void* params) {
  // Add the extensions to the results structure.
  ListValue results;
  results.Append(Value::CreateStringValue(path.value()));
  web_ui_->CallJavascriptFunction("window.handleFilePathSelected", results);
}

void ExtensionsDOMHandler::MultiFilesSelected(
    const std::vector<FilePath>& files, void* params) {
  NOTREACHED();
}

void ExtensionsDOMHandler::Observe(NotificationType type,
                                   const NotificationSource& source,
                                   const NotificationDetails& details) {
  switch (type.value) {
    // We listen for notifications that will result in the page being
    // repopulated with data twice for the same event in certain cases.
    // For instance, EXTENSION_LOADED & EXTENSION_PROCESS_CREATED because
    // we don't know about the views for an extension at EXTENSION_LOADED, but
    // if we only listen to EXTENSION_PROCESS_CREATED, we'll miss extensions
    // that don't have a process at startup. Similarly, NAV_ENTRY_COMMITTED &
    // EXTENSION_FUNCTION_DISPATCHER_CREATED because we want to handle both
    // the case of live app pages (which don't have an EFD) and
    // chrome-extension:// urls which are served in a TabContents.
    //
    // Doing it this way gets everything but causes the page to be rendered
    // more than we need. It doesn't seem to result in any noticeable flicker.
    case NotificationType::RENDER_VIEW_HOST_DELETED:
      deleting_rvh_ = Source<RenderViewHost>(source).ptr();
      MaybeUpdateAfterNotification();
      break;
    case NotificationType::BACKGROUND_CONTENTS_DELETED:
      deleting_rvh_ = Details<BackgroundContents>(details)->render_view_host();
      MaybeUpdateAfterNotification();
      break;
    case NotificationType::EXTENSION_LOADED:
    case NotificationType::EXTENSION_PROCESS_CREATED:
    case NotificationType::EXTENSION_UNLOADED:
    case NotificationType::EXTENSION_UPDATE_DISABLED:
    case NotificationType::EXTENSION_FUNCTION_DISPATCHER_CREATED:
    case NotificationType::EXTENSION_FUNCTION_DISPATCHER_DESTROYED:
    case NotificationType::NAV_ENTRY_COMMITTED:
    case NotificationType::BACKGROUND_CONTENTS_NAVIGATED:
    case NotificationType::EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED:
      MaybeUpdateAfterNotification();
      break;
    default:
      NOTREACHED();
  }
}

const Extension* ExtensionsDOMHandler::GetExtension(const ListValue* args) {
  std::string extension_id = UTF16ToASCII(ExtractStringValue(args));
  CHECK(!extension_id.empty());
  return extensions_service_->GetExtensionById(extension_id, true);
}

void ExtensionsDOMHandler::MaybeUpdateAfterNotification() {
  if (!ignore_notifications_ &&
      web_ui_->tab_contents() &&
      web_ui_->tab_contents()->render_view_host()) {
    HandleRequestExtensionsData(NULL);
  }
  deleting_rvh_ = NULL;
}

// Static
DictionaryValue* ExtensionsDOMHandler::CreateExtensionDetailValue(
    ExtensionService* service, const Extension* extension,
    const std::vector<ExtensionPage>& pages, bool enabled, bool terminated) {
  DictionaryValue* extension_data = new DictionaryValue();
  GURL icon =
      ExtensionIconSource::GetIconURL(extension,
                                      Extension::EXTENSION_ICON_MEDIUM,
                                      ExtensionIconSet::MATCH_BIGGER,
                                      !enabled);
  extension_data->SetString("id", extension->id());
  extension_data->SetString("name", extension->name());
  extension_data->SetString("description", extension->description());
  if (extension->location() == Extension::LOAD)
    extension_data->SetString("path", extension->path().value());
  extension_data->SetString("version", extension->version()->GetString());
  extension_data->SetString("icon", icon.spec());
  extension_data->SetBoolean("isUnpacked",
                             extension->location() == Extension::LOAD);
  extension_data->SetBoolean("mayDisable",
                             Extension::UserMayDisable(extension->location()));
  extension_data->SetBoolean("enabled", enabled);
  extension_data->SetBoolean("terminated", terminated);
  extension_data->SetBoolean("enabledIncognito",
      service ? service->IsIncognitoEnabled(extension->id()) : false);
  extension_data->SetBoolean("wantsFileAccess", extension->wants_file_access());
  extension_data->SetBoolean("allowFileAccess",
      service ? service->AllowFileAccess(extension) : false);
  extension_data->SetBoolean("allow_reload",
                             extension->location() == Extension::LOAD);
  extension_data->SetBoolean("is_hosted_app", extension->is_hosted_app());

  // Determine the sort order: Extensions loaded through --load-extensions show
  // up at the top. Disabled extensions show up at the bottom.
  if (extension->location() == Extension::LOAD)
    extension_data->SetInteger("order", 1);
  else
    extension_data->SetInteger("order", 2);

  if (!extension->options_url().is_empty())
    extension_data->SetString("options_url", extension->options_url().spec());

  if (service && !service->GetBrowserActionVisibility(extension))
    extension_data->SetBoolean("enable_show_button", true);

  // Add views
  ListValue* views = new ListValue;
  for (std::vector<ExtensionPage>::const_iterator iter = pages.begin();
       iter != pages.end(); ++iter) {
    DictionaryValue* view_value = new DictionaryValue;
    if (iter->url.scheme() == chrome::kExtensionScheme) {
      // No leading slash.
      view_value->SetString("path", iter->url.path().substr(1));
    } else {
      // For live pages, use the full URL.
      view_value->SetString("path", iter->url.spec());
    }
    view_value->SetInteger("renderViewId", iter->render_view_id);
    view_value->SetInteger("renderProcessId", iter->render_process_id);
    view_value->SetBoolean("incognito", iter->incognito);
    views->Append(view_value);
  }
  extension_data->Set("views", views);
  extension_data->SetBoolean("hasPopupAction",
      extension->browser_action() || extension->page_action());
  extension_data->SetString("homepageUrl", extension->GetHomepageURL().spec());

  return extension_data;
}

std::vector<ExtensionPage> ExtensionsDOMHandler::GetActivePagesForExtension(
    const Extension* extension) {
  std::vector<ExtensionPage> result;

  // Get the extension process's active views.
  ExtensionProcessManager* process_manager =
      extensions_service_->profile()->GetExtensionProcessManager();
  GetActivePagesForExtensionProcess(
      process_manager->GetExtensionProcess(extension->url()),
      extension, &result);

  // Repeat for the incognito process, if applicable.
  if (extensions_service_->profile()->HasOffTheRecordProfile() &&
      extension->incognito_split_mode()) {
    ExtensionProcessManager* process_manager =
        extensions_service_->profile()->GetOffTheRecordProfile()->
            GetExtensionProcessManager();
    GetActivePagesForExtensionProcess(
        process_manager->GetExtensionProcess(extension->url()),
        extension, &result);
  }

  return result;
}

void ExtensionsDOMHandler::GetActivePagesForExtensionProcess(
    RenderProcessHost* process,
    const Extension* extension,
    std::vector<ExtensionPage> *result) {
  if (!process)
    return;

  RenderProcessHost::listeners_iterator iter = process->ListenersIterator();
  for (; !iter.IsAtEnd(); iter.Advance()) {
    const RenderWidgetHost* widget =
        static_cast<const RenderWidgetHost*>(iter.GetCurrentValue());
    DCHECK(widget);
    if (!widget || !widget->IsRenderView())
      continue;
    const RenderViewHost* host = static_cast<const RenderViewHost*>(widget);
    if (host == deleting_rvh_ ||
        ViewType::EXTENSION_POPUP == host->delegate()->GetRenderViewType())
      continue;

    GURL url = host->delegate()->GetURL();
    if (url.SchemeIs(chrome::kExtensionScheme)) {
      if (url.host() != extension->id())
        continue;
    } else if (!extension->web_extent().ContainsURL(url)) {
      continue;
    }

    result->push_back(ExtensionPage(url, process->id(), host->routing_id(),
                                    process->profile()->IsOffTheRecord()));
  }
}

ExtensionsDOMHandler::~ExtensionsDOMHandler() {
  // There may be pending file dialogs, we need to tell them that we've gone
  // away so they don't try and call back to us.
  if (load_extension_dialog_.get())
    load_extension_dialog_->ListenerDestroyed();

  if (pack_job_.get())
    pack_job_->ClearClient();

  registrar_.RemoveAll();
}

// ExtensionsDOMHandler, public: -----------------------------------------------

ExtensionsUI::ExtensionsUI(TabContents* contents) : WebUI(contents) {
  ExtensionService *exstension_service =
      GetProfile()->GetOriginalProfile()->GetExtensionService();

  ExtensionsDOMHandler* handler = new ExtensionsDOMHandler(exstension_service);
  AddMessageHandler(handler);
  handler->Attach(this);

  ExtensionsUIHTMLSource* html_source = new ExtensionsUIHTMLSource();

  // Set up the chrome://extensions/ source.
  contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
}

// static
RefCountedMemory* ExtensionsUI::GetFaviconResourceBytes() {
  return ResourceBundle::GetSharedInstance().
      LoadDataResourceBytes(IDR_PLUGIN);
}

// static
void ExtensionsUI::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterBooleanPref(prefs::kExtensionsUIDeveloperMode, false);
}
