// Copyright 2016 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/ui/webui/plugins/plugins_handler.h"

#include <memory>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/plugins/plugin_finder.h"
#include "chrome/browser/plugins/plugin_metadata.h"
#include "chrome/browser/plugins/plugin_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pepper_flash.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/web_ui.h"
#include "content/public/common/content_constants.h"
#include "mojo/common/common_type_converters.h"
#include "ui/base/l10n/l10n_util.h"

using content::WebPluginInfo;
// Holds grouped plugins. The key is the group identifier and
// the value is the list of plugins belonging to the group.
using PluginGroups =
    base::hash_map<std::string, std::vector<const content::WebPluginInfo*>>;

namespace {

// Callback function to process result of EnablePlugin method.
void AssertPluginEnabled(bool did_enable) {
  DCHECK(did_enable);
}

base::string16 PluginTypeToString(int type) {
  // The type is stored as an |int|, but doing the switch on the right
  // enumeration type gives us better build-time error checking (if someone adds
  // a new type).
  switch (static_cast<WebPluginInfo::PluginType>(type)) {
    case WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS:
      return l10n_util::GetStringUTF16(IDS_PLUGINS_PPAPI_IN_PROCESS);
    case WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS:
      return l10n_util::GetStringUTF16(IDS_PLUGINS_PPAPI_OUT_OF_PROCESS);
    case WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN:
      return l10n_util::GetStringUTF16(IDS_PLUGINS_BROWSER_PLUGIN);
  }
  NOTREACHED();
  return base::string16();
}

base::string16 GetPluginDescription(const WebPluginInfo& plugin) {
  // If this plugin is Pepper Flash, and the plugin path is the same as the
  // path for the Pepper Flash System plugin, then mark this plugin
  // description as the system plugin to help the user disambiguate the
  // two plugins.
  base::string16 desc = plugin.desc;
  if (plugin.is_pepper_plugin() &&
      plugin.name == base::ASCIIToUTF16(content::kFlashPluginName)) {
    base::FilePath system_flash_path;
    PathService::Get(chrome::FILE_PEPPER_FLASH_SYSTEM_PLUGIN,
                     &system_flash_path);
    if (base::FilePath::CompareEqualIgnoreCase(plugin.path.value(),
                                               system_flash_path.value())) {
      if (chrome::IsSystemFlashScriptDebuggerPresent())
        desc += base::ASCIIToUTF16(" Debug");
      else
        desc += base::ASCIIToUTF16(" System");
    }
  }
  return desc;
}

mojo::Array<mojom::MimeTypePtr> GeneratePluginMimeTypes(
    const WebPluginInfo& plugin) {
  mojo::Array<mojom::MimeTypePtr> mime_types;
  for (const auto& plugin_mime_type : plugin.mime_types) {
    mojom::MimeTypePtr mime_type(mojom::MimeType::New());
    mime_type->description = mojo::String::From(plugin_mime_type.description);

    mime_type->mime_type = mojo::String::From(plugin_mime_type.mime_type);
    mime_type->file_extensions =
        mojo::Array<mojo::String>::From(plugin_mime_type.file_extensions);
    mime_types.push_back(std::move(mime_type));
  }

  return mime_types;
}

}  // namespace

PluginsPageHandler::PluginsPageHandler(
    content::WebUI* web_ui,
    mojo::InterfaceRequest<mojom::PluginsPageHandler> request)
    : web_ui_(web_ui),
      binding_(this, std::move(request)),
      weak_ptr_factory_(this) {
  Profile* profile = Profile::FromWebUI(web_ui_);
  PrefService* prefs = profile->GetPrefs();
  show_details_.Init(prefs::kPluginsShowDetails, prefs);

  registrar_.Add(this, chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
                 content::Source<Profile>(profile));
}

PluginsPageHandler::~PluginsPageHandler() {}

void PluginsPageHandler::SetPluginEnabled(const mojo::String& plugin_path,
                                          bool enable) {
  Profile* profile = Profile::FromWebUI(web_ui_);
  PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile).get();
  plugin_prefs->EnablePlugin(
      enable, base::FilePath(plugin_path.To<base::FilePath::StringType>()),
      base::Bind(&AssertPluginEnabled));
}

void PluginsPageHandler::SetPluginGroupEnabled(const mojo::String& group_name,
                                               bool enable) {
  Profile* profile = Profile::FromWebUI(web_ui_);
  PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile).get();
  base::string16 group_name_as_string16 = group_name.To<base::string16>();
  plugin_prefs->EnablePluginGroup(enable, group_name_as_string16);
  if (!enable) {
    return;
  }

  // See http://crbug.com/50105 for background.
  base::string16 adobereader =
      base::ASCIIToUTF16(PluginMetadata::kAdobeReaderGroupName);
  base::string16 internalpdf =
      base::ASCIIToUTF16(ChromeContentClient::kPDFPluginName);
  if (group_name_as_string16 == adobereader)
    plugin_prefs->EnablePluginGroup(false, internalpdf);
  else if (group_name_as_string16 == internalpdf)
    plugin_prefs->EnablePluginGroup(false, adobereader);
}

void PluginsPageHandler::GetShowDetails(
    const GetShowDetailsCallback& callback) {
  callback.Run(show_details_.GetValue());
}

void PluginsPageHandler::SaveShowDetailsToPrefs(bool details_mode) {
  show_details_.SetValue(details_mode);
}

void PluginsPageHandler::SetPluginAlwaysAllowed(const mojo::String& plugin,
                                                bool allowed) {
  Profile* profile = Profile::FromWebUI(web_ui_);
  HostContentSettingsMapFactory::GetForProfile(profile)
      ->SetContentSettingCustomScope(
          ContentSettingsPattern::Wildcard(),
          ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_PLUGINS,
          plugin.get(),
          allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_DEFAULT);

  // Keep track of the whitelist separately, so that we can distinguish plugins
  // whitelisted by the user from automatically whitelisted ones.
  DictionaryPrefUpdate update(profile->GetPrefs(),
                              prefs::kContentSettingsPluginWhitelist);
  update->SetBoolean(plugin, allowed);
}

void PluginsPageHandler::GetPluginsData(
    const GetPluginsDataCallback& callback) {
  if (weak_ptr_factory_.HasWeakPtrs())
    return;

  content::PluginService::GetInstance()->GetPlugins(
      base::Bind(&PluginsPageHandler::RespondWithPluginsData,
                 weak_ptr_factory_.GetWeakPtr(), callback));
}

void PluginsPageHandler::SetClientPage(mojom::PluginsPagePtr page) {
  page_ = std::move(page);
}

void PluginsPageHandler::Observe(int type,
                                 const content::NotificationSource& source,
                                 const content::NotificationDetails& details) {
  DCHECK_EQ(chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, type);

  if (weak_ptr_factory_.HasWeakPtrs())
    return;

  content::PluginService::GetInstance()->GetPlugins(
      base::Bind(&PluginsPageHandler::NotifyWithPluginsData,
                 weak_ptr_factory_.GetWeakPtr()));
}

void PluginsPageHandler::RespondWithPluginsData(
    const GetPluginsDataCallback& callback,
    const std::vector<WebPluginInfo>& plugins) {
  callback.Run(GeneratePluginsData(plugins));
}

void PluginsPageHandler::NotifyWithPluginsData(
    const std::vector<WebPluginInfo>& plugins) {
  if (page_)
    page_->OnPluginsUpdated(GeneratePluginsData(plugins));
}

mojo::Array<mojom::PluginDataPtr> PluginsPageHandler::GeneratePluginsData(
    const std::vector<WebPluginInfo>& plugins) {
  Profile* profile = Profile::FromWebUI(web_ui_);
  PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile).get();

  PluginFinder* plugin_finder = PluginFinder::GetInstance();
  // Group plugins by identifier. This is done to be able to display
  // the plugins in UI in a grouped fashion.
  PluginGroups groups;
  for (size_t i = 0; i < plugins.size(); ++i) {
    std::unique_ptr<PluginMetadata> plugin(
        plugin_finder->GetPluginMetadata(plugins[i]));
    groups[plugin->identifier()].push_back(&plugins[i]);
  }

  mojo::Array<mojom::PluginDataPtr> plugins_data;

  for (PluginGroups::const_iterator it = groups.begin(); it != groups.end();
       ++it) {
    mojom::PluginDataPtr plugin_data(mojom::PluginData::New());
    const std::vector<const WebPluginInfo*>& group_plugins = it->second;

    std::unique_ptr<PluginMetadata> plugin_metadata(
        plugin_finder->GetPluginMetadata(*group_plugins[0]));
    std::string group_identifier = plugin_metadata->identifier();
    plugin_data->id = mojo::String::From(group_identifier);

    const WebPluginInfo* active_plugin = nullptr;
    bool group_enabled = false;

    mojo::Array<mojom::PluginFilePtr> plugin_files;
    for (const auto& group_plugin : group_plugins) {
      bool plugin_enabled = plugin_prefs->IsPluginEnabled(*group_plugin);

      plugin_files.push_back(GeneratePluginFile(
          *group_plugin, plugin_metadata->name(), plugin_enabled));

      // Update |active_plugin| and |group_enabled|.
      if (!active_plugin || (plugin_enabled && !group_enabled))
        active_plugin = group_plugin;
      group_enabled = plugin_enabled || group_enabled;
    }

    plugin_data->enabled_mode = mojo::String::From(
        GetPluginGroupEnabledMode(plugin_files, group_enabled));

    plugin_data->always_allowed = false;
    plugin_data->trusted = false;

    if (group_enabled) {
      if (plugin_metadata->GetSecurityStatus(*active_plugin) ==
          PluginMetadata::SECURITY_STATUS_FULLY_TRUSTED) {
        plugin_data->trusted = true;
        plugin_data->always_allowed = true;
      } else {
        const base::DictionaryValue* whitelist =
            profile->GetPrefs()->GetDictionary(
                prefs::kContentSettingsPluginWhitelist);
        whitelist->GetBoolean(group_identifier, &plugin_data->always_allowed);
      }
    }

    plugin_data->critical = false;
    plugin_data->update_url = "";
#if defined(ENABLE_PLUGIN_INSTALLATION)
    bool out_of_date = plugin_metadata->GetSecurityStatus(*active_plugin) ==
                       PluginMetadata::SECURITY_STATUS_OUT_OF_DATE;
    plugin_data->critical = out_of_date;
    plugin_data->update_url = plugin_metadata->plugin_url().spec();
#endif

    plugin_data->description = mojo::String::From(active_plugin->desc);
    plugin_data->name = base::UTF16ToUTF8(plugin_metadata->name());
    plugin_data->plugin_files = std::move(plugin_files);
    plugin_data->version = mojo::String::From(active_plugin->version);
    plugins_data.push_back(std::move(plugin_data));
  }

  return plugins_data;
}

mojom::PluginFilePtr PluginsPageHandler::GeneratePluginFile(
    const WebPluginInfo& plugin,
    const base::string16& group_name,
    bool plugin_enabled) const {
  mojom::PluginFilePtr plugin_file(mojom::PluginFile::New());
  plugin_file->description = mojo::String::From(GetPluginDescription(plugin));
  plugin_file->enabled_mode = mojo::String::From(
      GetPluginEnabledMode(plugin.name, group_name, plugin_enabled));
  plugin_file->name = mojo::String::From(plugin.name);
  plugin_file->path = mojo::String::From(plugin.path.value());
  plugin_file->type = mojo::String::From(PluginTypeToString(plugin.type));
  plugin_file->version = mojo::String::From(plugin.version);
  plugin_file->mime_types = GeneratePluginMimeTypes(plugin);

  return plugin_file;
}

std::string PluginsPageHandler::GetPluginEnabledMode(
    const base::string16& plugin_name,
    const base::string16& group_name,
    bool plugin_enabled) const {
  Profile* profile = Profile::FromWebUI(web_ui_);
  PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile).get();
  PluginPrefs::PolicyStatus plugin_status =
      plugin_prefs->PolicyStatusForPlugin(plugin_name);
  PluginPrefs::PolicyStatus group_status =
      plugin_prefs->PolicyStatusForPlugin(group_name);

  if (plugin_status == PluginPrefs::POLICY_ENABLED ||
      group_status == PluginPrefs::POLICY_ENABLED) {
    return "enabledByPolicy";
  }
  if (plugin_status == PluginPrefs::POLICY_DISABLED ||
      group_status == PluginPrefs::POLICY_DISABLED) {
    return "disabledByPolicy";
  }
  return plugin_enabled ? "enabledByUser" : "disabledByUser";
}

std::string PluginsPageHandler::GetPluginGroupEnabledMode(
    const mojo::Array<mojom::PluginFilePtr>& plugin_files,
    bool group_enabled) const {
  bool plugins_enabled_by_policy = true;
  bool plugins_disabled_by_policy = true;
  bool plugins_managed_by_policy = true;

  for (size_t i = 0; i < plugin_files.size(); i++) {
    std::string plugin_enabled_mode = plugin_files[i]->enabled_mode;

    plugins_enabled_by_policy =
        plugins_enabled_by_policy && plugin_enabled_mode == "enabledByPolicy";
    plugins_disabled_by_policy =
        plugins_disabled_by_policy && plugin_enabled_mode == "disabledByPolicy";
    plugins_managed_by_policy = plugins_managed_by_policy &&
                                (plugin_enabled_mode == "enabledByPolicy" ||
                                 plugin_enabled_mode == "disabledByPolicy");
  }

  if (plugins_enabled_by_policy)
    return "enabledByPolicy";
  if (plugins_disabled_by_policy)
    return "disabledByPolicy";
  if (plugins_managed_by_policy)
    return "managedByPolicy";
  return group_enabled ? "enabledByUser" : "disabledByUser";
}
