// Copyright 2013 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/search_engines/default_search_policy_handler.h"

#include "base/prefs/pref_value_map.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/search_engines/search_terms_data.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/common/pref_names.h"
#include "components/policy/core/browser/policy_error_map.h"
#include "components/policy/core/common/policy_map.h"
#include "content/public/browser/notification_service.h"
#include "grit/component_strings.h"
#include "policy/policy_constants.h"

namespace policy {

// List of policy types to preference names, for policies affecting the default
// search provider.
const PolicyToPreferenceMapEntry kDefaultSearchPolicyMap[] = {
  { key::kDefaultSearchProviderEnabled,
    prefs::kDefaultSearchProviderEnabled,
    Value::TYPE_BOOLEAN },
  { key::kDefaultSearchProviderName,
    prefs::kDefaultSearchProviderName,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderKeyword,
    prefs::kDefaultSearchProviderKeyword,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderSearchURL,
    prefs::kDefaultSearchProviderSearchURL,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderSuggestURL,
    prefs::kDefaultSearchProviderSuggestURL,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderInstantURL,
    prefs::kDefaultSearchProviderInstantURL,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderIconURL,
    prefs::kDefaultSearchProviderIconURL,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderEncodings,
    prefs::kDefaultSearchProviderEncodings,
    Value::TYPE_LIST },
  { key::kDefaultSearchProviderAlternateURLs,
    prefs::kDefaultSearchProviderAlternateURLs,
    Value::TYPE_LIST },
  { key::kDefaultSearchProviderSearchTermsReplacementKey,
    prefs::kDefaultSearchProviderSearchTermsReplacementKey,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderImageURL,
    prefs::kDefaultSearchProviderImageURL,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderNewTabURL,
    prefs::kDefaultSearchProviderNewTabURL,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderSearchURLPostParams,
    prefs::kDefaultSearchProviderSearchURLPostParams,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderSuggestURLPostParams,
    prefs::kDefaultSearchProviderSuggestURLPostParams,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderInstantURLPostParams,
    prefs::kDefaultSearchProviderInstantURLPostParams,
    Value::TYPE_STRING },
  { key::kDefaultSearchProviderImageURLPostParams,
    prefs::kDefaultSearchProviderImageURLPostParams,
    Value::TYPE_STRING },
};

// DefaultSearchEncodingsPolicyHandler implementation --------------------------

DefaultSearchEncodingsPolicyHandler::DefaultSearchEncodingsPolicyHandler()
    : TypeCheckingPolicyHandler(key::kDefaultSearchProviderEncodings,
                                Value::TYPE_LIST) {}

DefaultSearchEncodingsPolicyHandler::~DefaultSearchEncodingsPolicyHandler() {
}

void DefaultSearchEncodingsPolicyHandler::ApplyPolicySettings(
    const PolicyMap& policies, PrefValueMap* prefs) {
  // The DefaultSearchProviderEncodings policy has type list, but the related
  // preference has type string. Convert one into the other here, using
  // ';' as a separator.
  const Value* value = policies.GetValue(policy_name());
  const ListValue* list;
  if (!value || !value->GetAsList(&list))
    return;

  ListValue::const_iterator iter(list->begin());
  ListValue::const_iterator end(list->end());
  std::vector<std::string> string_parts;
  for (; iter != end; ++iter) {
    std::string s;
    if ((*iter)->GetAsString(&s)) {
      string_parts.push_back(s);
    }
  }
  std::string encodings = JoinString(string_parts, ';');
  prefs->SetValue(prefs::kDefaultSearchProviderEncodings,
                  Value::CreateStringValue(encodings));
}


// DefaultSearchPolicyHandler implementation -----------------------------------

DefaultSearchPolicyHandler::DefaultSearchPolicyHandler() {
  for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) {
    const char* policy_name = kDefaultSearchPolicyMap[i].policy_name;
    if (policy_name == key::kDefaultSearchProviderEncodings) {
      handlers_.push_back(new DefaultSearchEncodingsPolicyHandler());
    } else {
      handlers_.push_back(new SimplePolicyHandler(
          policy_name,
          kDefaultSearchPolicyMap[i].preference_path,
          kDefaultSearchPolicyMap[i].value_type));
    }
  }
}

DefaultSearchPolicyHandler::~DefaultSearchPolicyHandler() {
  STLDeleteElements(&handlers_);
}

bool DefaultSearchPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
                                                     PolicyErrorMap* errors) {
  if (!CheckIndividualPolicies(policies, errors))
    return false;

  if (DefaultSearchProviderIsDisabled(policies)) {
    // Add an error for all specified default search policies except
    // DefaultSearchProviderEnabled.

    for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
             handlers_.begin();
         handler != handlers_.end(); ++handler) {
      const char* policy_name = (*handler)->policy_name();
      if (policy_name != key::kDefaultSearchProviderEnabled &&
          HasDefaultSearchPolicy(policies, policy_name)) {
        errors->AddError(policy_name, IDS_POLICY_DEFAULT_SEARCH_DISABLED);
      }
    }
    return true;
  }

  const Value* url;
  std::string dummy;
  if (DefaultSearchURLIsValid(policies, &url, &dummy) ||
      !AnyDefaultSearchPoliciesSpecified(policies))
    return true;
  errors->AddError(key::kDefaultSearchProviderSearchURL, url ?
      IDS_POLICY_INVALID_SEARCH_URL_ERROR : IDS_POLICY_NOT_SPECIFIED_ERROR);
  return false;
}

void DefaultSearchPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
                                                     PrefValueMap* prefs) {
  if (DefaultSearchProviderIsDisabled(policies)) {
    prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, false);

    // If default search is disabled, the other fields are ignored.
    prefs->SetString(prefs::kDefaultSearchProviderName, std::string());
    prefs->SetString(prefs::kDefaultSearchProviderSearchURL, std::string());
    prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, std::string());
    prefs->SetString(prefs::kDefaultSearchProviderIconURL, std::string());
    prefs->SetString(prefs::kDefaultSearchProviderEncodings, std::string());
    prefs->SetString(prefs::kDefaultSearchProviderKeyword, std::string());
    prefs->SetString(prefs::kDefaultSearchProviderInstantURL, std::string());
    prefs->SetString(prefs::kDefaultSearchProviderNewTabURL, std::string());
    prefs->SetValue(prefs::kDefaultSearchProviderAlternateURLs,
                    new ListValue());
    prefs->SetString(
        prefs::kDefaultSearchProviderSearchTermsReplacementKey, std::string());
    prefs->SetString(prefs::kDefaultSearchProviderImageURL, std::string());
    prefs->SetString(
        prefs::kDefaultSearchProviderSearchURLPostParams, std::string());
    prefs->SetString(
        prefs::kDefaultSearchProviderSuggestURLPostParams, std::string());
    prefs->SetString(
        prefs::kDefaultSearchProviderInstantURLPostParams, std::string());
    prefs->SetString(
        prefs::kDefaultSearchProviderImageURLPostParams, std::string());
  } else {
    // The search URL is required.  The other entries are optional.  Just make
    // sure that they are all specified via policy, so that the regular prefs
    // aren't used.
    const Value* dummy;
    std::string url;
    if (DefaultSearchURLIsValid(policies, &dummy, &url)) {

      for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
               handlers_.begin();
           handler != handlers_.end(); ++handler) {
        (*handler)->ApplyPolicySettings(policies, prefs);
      }

      EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderSuggestURL);
      EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderIconURL);
      EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderEncodings);
      EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderKeyword);
      EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderInstantURL);
      EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderNewTabURL);
      EnsureListPrefExists(prefs, prefs::kDefaultSearchProviderAlternateURLs);
      EnsureStringPrefExists(
          prefs,
          prefs::kDefaultSearchProviderSearchTermsReplacementKey);
      EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderImageURL);
      EnsureStringPrefExists(
          prefs,
          prefs::kDefaultSearchProviderSearchURLPostParams);
      EnsureStringPrefExists(
          prefs,
          prefs::kDefaultSearchProviderSuggestURLPostParams);
      EnsureStringPrefExists(
          prefs,
          prefs::kDefaultSearchProviderInstantURLPostParams);
      EnsureStringPrefExists(
          prefs,
          prefs::kDefaultSearchProviderImageURLPostParams);

      // For the name and keyword, default to the host if not specified.  If
      // there is no host (file: URLs?  Not sure), use "_" to guarantee that the
      // keyword is non-empty.
      std::string name, keyword;
      std::string host(GURL(url).host());
      if (host.empty())
        host = "_";
      if (!prefs->GetString(prefs::kDefaultSearchProviderName, &name) ||
          name.empty()) {
        prefs->SetString(prefs::kDefaultSearchProviderName, host);
      }
      if (!prefs->GetString(prefs::kDefaultSearchProviderKeyword, &keyword) ||
          keyword.empty()) {
        prefs->SetString(prefs::kDefaultSearchProviderKeyword, host);
      }

      // And clear the IDs since these are not specified via policy.
      prefs->SetString(prefs::kDefaultSearchProviderID, std::string());
      prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID,
                       std::string());
    }
  }
  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED,
      content::NotificationService::AllSources(),
      content::NotificationService::NoDetails());
}

bool DefaultSearchPolicyHandler::CheckIndividualPolicies(
    const PolicyMap& policies,
    PolicyErrorMap* errors) {
  for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
           handlers_.begin();
       handler != handlers_.end(); ++handler) {
    if (!(*handler)->CheckPolicySettings(policies, errors))
      return false;
  }
  return true;
}

bool DefaultSearchPolicyHandler::HasDefaultSearchPolicy(
    const PolicyMap& policies,
    const char* policy_name) {
  return policies.Get(policy_name) != NULL;
}

bool DefaultSearchPolicyHandler::AnyDefaultSearchPoliciesSpecified(
    const PolicyMap& policies) {
  for (std::vector<TypeCheckingPolicyHandler*>::const_iterator handler =
           handlers_.begin();
       handler != handlers_.end(); ++handler) {
    if (policies.Get((*handler)->policy_name()))
      return true;
  }
  return false;
}

bool DefaultSearchPolicyHandler::DefaultSearchProviderIsDisabled(
    const PolicyMap& policies) {
  const Value* provider_enabled =
      policies.GetValue(key::kDefaultSearchProviderEnabled);
  bool enabled = true;
  return provider_enabled && provider_enabled->GetAsBoolean(&enabled) &&
      !enabled;
}

bool DefaultSearchPolicyHandler::DefaultSearchURLIsValid(
    const PolicyMap& policies,
    const Value** url_value,
    std::string* url_string) {
  *url_value = policies.GetValue(key::kDefaultSearchProviderSearchURL);
  if (!*url_value || !(*url_value)->GetAsString(url_string) ||
      url_string->empty())
    return false;
  TemplateURLData data;
  data.SetURL(*url_string);
  SearchTermsData search_terms_data;
  return TemplateURL(NULL, data).SupportsReplacementUsingTermsData(
      search_terms_data);
}

void DefaultSearchPolicyHandler::EnsureStringPrefExists(
    PrefValueMap* prefs,
    const std::string& path) {
  std::string value;
  if (!prefs->GetString(path, &value))
    prefs->SetString(path, value);
}

void DefaultSearchPolicyHandler::EnsureListPrefExists(
    PrefValueMap* prefs,
    const std::string& path) {
  base::Value* value;
  base::ListValue* list_value;
  if (!prefs->GetValue(path, &value) || !value->GetAsList(&list_value))
    prefs->SetValue(path, new ListValue());
}

}  // namespace policy
