// Copyright (c) 2012 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/plugins/plugin_policy_handler.h"

#include <string>

#include "base/memory/ptr_util.h"
#include "base/strings/pattern.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "chrome/browser/plugins/plugin_metadata.h"
#include "chrome/browser/plugins/plugin_prefs.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/pref_names.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/policy/core/browser/policy_error_map.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/common/content_constants.h"

namespace {

// Retrieves a list typed policy or nullptr if not present or not a list.
const base::ListValue* GetListPolicy(const policy::PolicyMap& policies,
                                     const std::string& policy) {
  const base::Value* value = policies.GetValue(policy);
  if (!value)
    return nullptr;

  const base::ListValue* policy_value = nullptr;
  value->GetAsList(&policy_value);
  return policy_value;
}

}  // namespace

PluginPolicyHandler::PluginPolicyHandler() {}

PluginPolicyHandler::~PluginPolicyHandler() {}

void PluginPolicyHandler::ProcessPolicy(const policy::PolicyMap& policies,
                                        PrefValueMap* prefs,
                                        const std::string& policy,
                                        bool disable_pdf_plugin,
                                        ContentSetting flash_content_setting) {
  const base::ListValue* plugins = GetListPolicy(policies, policy);
  if (!plugins)
    return;

  const int size = plugins->GetSize();
  for (int i = 0; i < size; ++i) {
    std::string plugin;
    if (!plugins->GetString(i, &plugin))
      continue;
    if (base::MatchPattern(ChromeContentClient::kPDFPluginName, plugin) &&
        !policies.GetValue(policy::key::kAlwaysOpenPdfExternally)) {
      prefs->SetValue(
          prefs::kPluginsAlwaysOpenPdfExternally,
          base::MakeUnique<base::FundamentalValue>(disable_pdf_plugin));
    }
    if ((base::MatchPattern(
             PluginMetadata::kAdobeFlashPlayerGroupName, plugin) ||
         base::MatchPattern(content::kFlashPluginName, plugin)) &&
        !policies.GetValue(policy::key::kDefaultPluginsSetting)) {
      prefs->SetValue(
          prefs::kManagedDefaultPluginsSetting,
          base::MakeUnique<base::FundamentalValue>(flash_content_setting));
    }
  }
}

bool PluginPolicyHandler::CheckPolicySettings(const policy::PolicyMap& policies,
                                              policy::PolicyErrorMap* errors) {
  const std::string checked_policies[] = {
      policy::key::kEnabledPlugins, policy::key::kDisabledPlugins,
      policy::key::kDisabledPluginsExceptions};
  bool ok = true;
  for (size_t i = 0; i < arraysize(checked_policies); ++i) {
    const base::Value* value = policies.GetValue(checked_policies[i]);
    if (value && !value->IsType(base::Value::TYPE_LIST)) {
      errors->AddError(checked_policies[i], IDS_POLICY_TYPE_ERROR,
                       base::Value::GetTypeName(base::Value::TYPE_LIST));
      ok = false;
    }
  }
  return ok;
}

void PluginPolicyHandler::ApplyPolicySettings(const policy::PolicyMap& policies,
                                              PrefValueMap* prefs) {
  // This order makes enabled plugins take precedence as is now.
  ProcessPolicy(policies, prefs, policy::key::kDisabledPlugins, true,
                CONTENT_SETTING_BLOCK);
  ProcessPolicy(policies, prefs, policy::key::kEnabledPlugins, false,
                CONTENT_SETTING_ALLOW);

  // Finally check if any of the two is in the exceptions list and remove the
  // policy changes.
  const base::ListValue* plugins =
      GetListPolicy(policies, policy::key::kDisabledPluginsExceptions);
  if (!plugins)
    return;
  const int size = plugins->GetSize();
  for (int i = 0; i < size; ++i) {
    std::string plugin;
    if (!plugins->GetString(i, &plugin))
      continue;
    if (base::MatchPattern(ChromeContentClient::kPDFPluginName, plugin) &&
        !policies.GetValue(policy::key::kAlwaysOpenPdfExternally)) {
      prefs->RemoveValue(prefs::kPluginsAlwaysOpenPdfExternally);
    }
    if ((base::MatchPattern(
            PluginMetadata::kAdobeFlashPlayerGroupName, plugin) ||
         base::MatchPattern(content::kFlashPluginName, plugin)) &&
        !policies.GetValue(policy::key::kDefaultPluginsSetting)) {
      prefs->RemoveValue(prefs::kManagedDefaultPluginsSetting);
    }
  }
}
