// 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.

#ifndef COMPONENTS_SEARCH_ENGINES_DEFAULT_SEARCH_MANAGER_H_
#define COMPONENTS_SEARCH_ENGINES_DEFAULT_SEARCH_MANAGER_H_

#include <memory>

#include "base/callback.h"
#include "base/macros.h"
#include "components/prefs/pref_change_registrar.h"

namespace base {
class DictionaryValue;
}

namespace user_prefs {
class PrefRegistrySyncable;
}

class PrefService;
class PrefValueMap;
struct TemplateURLData;

// DefaultSearchManager handles the loading and writing of the user's default
// search engine selection to and from prefs.
class DefaultSearchManager {
 public:
  static const char kDefaultSearchProviderDataPrefName[];

  static const char kID[];
  static const char kShortName[];
  static const char kKeyword[];
  static const char kPrepopulateID[];
  static const char kSyncGUID[];

  static const char kURL[];
  static const char kSuggestionsURL[];
  static const char kInstantURL[];
  static const char kImageURL[];
  static const char kNewTabURL[];
  static const char kFaviconURL[];
  static const char kOriginatingURL[];

  static const char kSearchURLPostParams[];
  static const char kSuggestionsURLPostParams[];
  static const char kInstantURLPostParams[];
  static const char kImageURLPostParams[];

  static const char kSafeForAutoReplace[];
  static const char kInputEncodings[];

  static const char kDateCreated[];
  static const char kLastModified[];

  static const char kUsageCount[];
  static const char kAlternateURLs[];
  static const char kSearchTermsReplacementKey[];
  static const char kCreatedByPolicy[];
  static const char kDisabledByPolicy[];

  enum Source {
    FROM_FALLBACK = 0,
    FROM_USER,
    FROM_EXTENSION,
    FROM_POLICY,
  };

  typedef base::Callback<void(const TemplateURLData*, Source)> ObserverCallback;

  DefaultSearchManager(PrefService* pref_service,
                       const ObserverCallback& change_observer);

  ~DefaultSearchManager();

  // Register prefs needed for tracking the default search provider.
  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);

  // Save default search provider pref values into the map provided.
  static void AddPrefValueToMap(std::unique_ptr<base::DictionaryValue> value,
                                PrefValueMap* pref_value_map);

  // Testing code can call this with |disabled| set to true to cause
  // GetDefaultSearchEngine() to return NULL instead of
  // |fallback_default_search_| in cases where the DSE source is FROM_FALLBACK.
  static void SetFallbackSearchEnginesDisabledForTesting(bool disabled);

  // Gets a pointer to the current Default Search Engine. If NULL, indicates
  // that Default Search is explicitly disabled. |source|, if not NULL, will be
  // filled in with the source of the result.
  TemplateURLData* GetDefaultSearchEngine(Source* source) const;

  // Gets the source of the current Default Search Engine value.
  Source GetDefaultSearchEngineSource() const;

  // Write default search provider data to |pref_service_|.
  void SetUserSelectedDefaultSearchEngine(const TemplateURLData& data);

  // Override the default search provider with an extension.
  void SetExtensionControlledDefaultSearchEngine(const TemplateURLData& data);

  // Clear the extension-provided default search engine. Does not explicitly
  // disable Default Search. The new current default search engine will be
  // defined by policy, extensions, or pre-populated data.
  void ClearExtensionControlledDefaultSearchEngine();

  // Clear the user's default search provider choice from |pref_service_|. Does
  // not explicitly disable Default Search. The new default search
  // engine will be defined by policy, extensions, or pre-populated data.
  void ClearUserSelectedDefaultSearchEngine();

 private:
  // Handles changes to kDefaultSearchProviderData pref. This includes sync and
  // policy changes. Calls LoadDefaultSearchEngineFromPrefs() and
  // NotifyObserver() if the effective DSE might have changed.
  void OnDefaultSearchPrefChanged();

  // Handles changes to kSearchProviderOverrides pref. Calls
  // LoadPrepopulatedDefaultSearch() and NotifyObserver() if the effective DSE
  // might have changed.
  void OnOverridesPrefChanged();

  // Updates |prefs_default_search_| with values from its corresponding
  // pre-populated search provider record, if any.
  void MergePrefsDataWithPrepopulated();

  // Reads default search provider data from |pref_service_|, updating
  // |prefs_default_search_| and |default_search_controlled_by_policy_|.
  // Invokes MergePrefsDataWithPrepopulated().
  void LoadDefaultSearchEngineFromPrefs();

  // Reads pre-populated search providers, which will be built-in or overridden
  // by kSearchProviderOverrides. Updates |fallback_default_search_|. Invoke
  // MergePrefsDataWithPrepopulated().
  void LoadPrepopulatedDefaultSearch();

  // Invokes |change_observer_| if it is not NULL.
  void NotifyObserver();

  PrefService* pref_service_;
  const ObserverCallback change_observer_;
  PrefChangeRegistrar pref_change_registrar_;

  // Default search engine provided by pre-populated data or by the
  // |kSearchProviderOverrides| pref. This will be used when no other default
  // search engine has been selected.
  std::unique_ptr<TemplateURLData> fallback_default_search_;

  // Default search engine provided by extension (usings Settings Override API).
  // This will be null if there are no extensions installed which provide
  // default search engines.
  std::unique_ptr<TemplateURLData> extension_default_search_;

  // Default search engine provided by prefs (either user prefs or policy
  // prefs). This will be null if no value was set in the pref store.
  std::unique_ptr<TemplateURLData> prefs_default_search_;

  // True if the default search is currently enforced by policy.
  bool default_search_controlled_by_policy_;

  DISALLOW_COPY_AND_ASSIGN(DefaultSearchManager);
};

#endif  // COMPONENTS_SEARCH_ENGINES_DEFAULT_SEARCH_MANAGER_H_
