// 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_TEMPLATE_URL_SERVICE_H_
#define COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_

#include <stddef.h>

#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/callback_list.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/time/default_clock.h"
#include "components/google/core/browser/google_url_tracker.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/search_engines/default_search_manager.h"
#include "components/search_engines/keyword_web_data_service.h"
#include "components/search_engines/search_host_to_urls_map.h"
#include "components/search_engines/search_terms_data.h"
#include "components/search_engines/template_url.h"
#include "components/sync/model/sync_change.h"
#include "components/sync/model/syncable_service.h"
#include "components/webdata/common/web_data_service_consumer.h"

class GURL;
class PrefService;
class TemplateURLServiceClient;
class TemplateURLServiceObserver;
struct TemplateURLData;

namespace rappor {
class RapporServiceImpl;
}

namespace syncer {
class SyncData;
class SyncErrorFactory;
}

namespace user_prefs {
class PrefRegistrySyncable;
}

// TemplateURLService is the backend for keywords. It's used by
// KeywordAutocomplete.
//
// TemplateURLService stores a vector of TemplateURLs. The TemplateURLs are
// persisted to the database maintained by KeywordWebDataService.
// *ALL* mutations to the TemplateURLs must funnel through TemplateURLService.
// This allows TemplateURLService to notify listeners of changes as well as keep
// the database in sync.
//
// TemplateURLService does not load the vector of TemplateURLs in its
// constructor (except for testing). Use the Load method to trigger a load.
// When TemplateURLService has completed loading, observers are notified via
// OnTemplateURLServiceChanged, or by a callback registered prior to calling
// the Load method.
//
// TemplateURLService takes ownership of any TemplateURL passed to it. If there
// is a KeywordWebDataService, deletion is handled by KeywordWebDataService,
// otherwise TemplateURLService handles deletion.

class TemplateURLService : public WebDataServiceConsumer,
                           public KeyedService,
                           public syncer::SyncableService {
 public:
  using QueryTerms = std::map<std::string, std::string>;
  using TemplateURLVector = TemplateURL::TemplateURLVector;
  using OwnedTemplateURLVector = TemplateURL::OwnedTemplateURLVector;
  using SyncDataMap = std::map<std::string, syncer::SyncData>;
  using Subscription = base::CallbackList<void(void)>::Subscription;

  // We may want to treat the keyword in a TemplateURL as being a different
  // length than it actually is.  For example, for keywords that end in a
  // registry, e.g., '.com', we want to consider the registry characters as not
  // a meaningful part of the keyword and not penalize for the user not typing
  // those.)
  using TURLAndMeaningfulLength = std::pair<TemplateURL*, size_t>;
  using TURLsAndMeaningfulLengths = std::vector<TURLAndMeaningfulLength>;

  // Struct used for initializing the data store with fake data.
  // Each initializer is mapped to a TemplateURL.
  struct Initializer {
    const char* const keyword;
    const char* const url;
    const char* const content;
  };

  struct URLVisitedDetails {
    GURL url;
    bool is_keyword_transition;
  };

  TemplateURLService(
      PrefService* prefs,
      std::unique_ptr<SearchTermsData> search_terms_data,
      const scoped_refptr<KeywordWebDataService>& web_data_service,
      std::unique_ptr<TemplateURLServiceClient> client,
      GoogleURLTracker* google_url_tracker,
      rappor::RapporServiceImpl* rappor_service,
      const base::RepeatingClosure& dsp_change_callback);
  // The following is for testing.
  TemplateURLService(const Initializer* initializers, const int count);
  ~TemplateURLService() override;

  // Register Profile preferences in |registry|.
  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);

  // Returns true if there is no TemplateURL that conflicts with the
  // keyword/url pair, or there is one but it can be replaced. If there is an
  // existing keyword that can be replaced and template_url_to_replace is
  // non-NULL, template_url_to_replace is set to the keyword to replace.
  //
  // |url| is the URL of the search query.  This is used to prevent auto-adding
  // a keyword for hosts already associated with a manually-edited keyword.
  bool CanAddAutogeneratedKeyword(const base::string16& keyword,
                                  const GURL& url,
                                  const TemplateURL** template_url_to_replace);

  // Returns whether the engine is a "pre-existing" engine, either from the
  // prepopulate list or created by policy.
  bool IsPrepopulatedOrCreatedByPolicy(const TemplateURL* template_url) const;

  // Returns whether |template_url| should be shown in the list of engines
  // most likely to be selected as a default engine. This is meant to highlight
  // the current default, as well as the other most likely choices of default
  // engine, separately from a full list of all TemplateURLs (which might be
  // very long).
  bool ShowInDefaultList(const TemplateURL* template_url) const;

  // Adds to |matches| all TemplateURLs whose keywords begin with |prefix|,
  // sorted shortest-keyword-first. If |supports_replacement_only| is true, only
  // TemplateURLs that support replacement are returned.
  void AddMatchingKeywords(const base::string16& prefix,
                           bool supports_replacement_only,
                           TURLsAndMeaningfulLengths* matches);

  // Adds to |matches| all TemplateURLs for search engines with the domain
  // name part of the keyword starts with |prefix|, sorted
  // shortest-domain-name-first. If |supports_replacement_only| is true, only
  // TemplateURLs that support replacement are returned.  Does not bother
  // searching/returning keywords that would've been found with an identical
  // call to FindMatchingKeywords(); i.e., doesn't search keywords for which
  // the domain name is the keyword.
  void AddMatchingDomainKeywords(const base::string16& prefix,
                                 bool supports_replacement_only,
                                 TURLsAndMeaningfulLengths* matches);

  // Looks up |keyword| and returns the element it maps to.  Returns NULL if
  // the keyword was not found.
  // The caller should not try to delete the returned pointer; the data store
  // retains ownership of it.
  TemplateURL* GetTemplateURLForKeyword(const base::string16& keyword);
  const TemplateURL* GetTemplateURLForKeyword(
      const base::string16& keyword) const;

  // Returns that TemplateURL with the specified GUID, or NULL if not found.
  // The caller should not try to delete the returned pointer; the data store
  // retains ownership of it.
  TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid);
  const TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid) const;

  // Returns the first TemplateURL found with a URL using the specified |host|,
  // or NULL if there are no such TemplateURLs
  TemplateURL* GetTemplateURLForHost(const std::string& host);
  const TemplateURL* GetTemplateURLForHost(const std::string& host) const;

  // Adds a new TemplateURL to this model.
  //
  // This function guarantees that on return the model will not have two non-
  // extension TemplateURLs with the same keyword.  If that means that it cannot
  // add the provided argument, it will return null.  Otherwise it will return
  // the raw pointer to the TemplateURL.
  //
  // Returns a raw pointer to |template_url| if the addition succeeded, or null
  // on failure.  (Many callers need still need a raw pointer to the TemplateURL
  // so they can access it later.)
  TemplateURL* Add(std::unique_ptr<TemplateURL> template_url);

  // Like Add(), but overwrites the |template_url|'s values with the provided
  // ones.
  TemplateURL* AddWithOverrides(std::unique_ptr<TemplateURL> template_url,
                                const base::string16& short_name,
                                const base::string16& keyword,
                                const std::string& url);

  // Removes the keyword from the model. This deletes the supplied TemplateURL.
  // This fails if the supplied template_url is the default search provider.
  void Remove(const TemplateURL* template_url);

  // Removes any TemplateURL of the specified |type| associated with
  // |extension_id|. Unlike with Remove(), this can be called when the
  // TemplateURL in question is the current default search provider.
  void RemoveExtensionControlledTURL(const std::string& extension_id,
                                     TemplateURL::Type type);

  // Removes all auto-generated keywords that were created on or after the
  // date passed in.
  void RemoveAutoGeneratedSince(base::Time created_after);

  // Removes all auto-generated keywords that were created in the specified
  // range.
  void RemoveAutoGeneratedBetween(base::Time created_after,
                                  base::Time created_before);

  // Removes all auto-generated keywords that were created in the specified
  // range and match |url_filter|. If |url_filter| is_null(), deletes all
  // auto-generated keywords in the range.
  void RemoveAutoGeneratedForUrlsBetween(
      const base::Callback<bool(const GURL&)>& url_filter,
      base::Time created_after,
      base::Time created_before);

  // Adds a TemplateURL for an extension with an omnibox keyword.
  // Only 1 keyword is allowed for a given extension. If a keyword
  // already exists for this extension, does nothing.
  void RegisterOmniboxKeyword(const std::string& extension_id,
                              const std::string& extension_name,
                              const std::string& keyword,
                              const std::string& template_url_string,
                              const base::Time& extension_install_time);

  // Returns the set of URLs describing the keywords. The elements are owned
  // by TemplateURLService and should not be deleted.
  TemplateURLVector GetTemplateURLs();

  // Increment the usage count of a keyword.
  // Called when a URL is loaded that was generated from a keyword.
  void IncrementUsageCount(TemplateURL* url);

  // Resets the title, keyword and search url of the specified TemplateURL.
  // The TemplateURL is marked as not replaceable.
  void ResetTemplateURL(TemplateURL* url,
                        const base::string16& title,
                        const base::string16& keyword,
                        const std::string& search_url);

  // Updates any search providers matching |potential_search_url| with the new
  // favicon location |favicon_url|.
  void UpdateProviderFavicons(const GURL& potential_search_url,
                              const GURL& favicon_url);

  // Return true if the given |url| can be made the default. This returns false
  // regardless of |url| if the default search provider is managed by policy or
  // controlled by an extension.
  bool CanMakeDefault(const TemplateURL* url) const;

  // Set the default search provider.  |url| may be null.
  // This will assert if the default search is managed; the UI should not be
  // invoking this method in that situation.
  void SetUserSelectedDefaultSearchProvider(TemplateURL* url);

  // Returns the default search provider. If the TemplateURLService hasn't been
  // loaded, the default search provider is pulled from preferences.
  //
  // NOTE: This may return null in certain circumstances such as:
  //       1.) Unit test mode
  //       2.) The default search engine is disabled by policy.
  const TemplateURL* GetDefaultSearchProvider() const;

  // Returns true if the |url| is a search results page from the default search
  // provider.
  bool IsSearchResultsPageFromDefaultSearchProvider(const GURL& url) const;

  // Returns true if the default search is managed through group policy.
  bool is_default_search_managed() const {
    return default_search_provider_source_ == DefaultSearchManager::FROM_POLICY;
  }

  // Returns true if the default search provider is controlled by an extension.
  bool IsExtensionControlledDefaultSearch() const;

  // Returns the default search specified in the prepopulated data, if it
  // exists.  If not, returns first URL in |template_urls_|, or NULL if that's
  // empty. The returned object is owned by TemplateURLService and can be
  // destroyed at any time so should be used right after the call.
  TemplateURL* FindNewDefaultSearchProvider();

  // Performs the same actions that happen when the prepopulate data version is
  // revved: all existing prepopulated entries are checked against the current
  // prepopulate data, any now-extraneous safe_for_autoreplace() entries are
  // removed, any existing engines are reset to the provided data (except for
  // user-edited names or keywords), and any new prepopulated engines are
  // added.
  //
  // After this, the default search engine is reset to the default entry in the
  // prepopulate data.
  void RepairPrepopulatedSearchEngines();

  // Observers used to listen for changes to the model.
  // TemplateURLService does NOT delete the observers when deleted.
  void AddObserver(TemplateURLServiceObserver* observer);
  void RemoveObserver(TemplateURLServiceObserver* observer);

  // Loads the keywords. This has no effect if the keywords have already been
  // loaded.
  // Observers are notified when loading completes via the method
  // OnTemplateURLServiceChanged.
  void Load();

  // Registers a callback to be called when the service has loaded.
  //
  // If the service has already loaded, this function does nothing.
  std::unique_ptr<Subscription> RegisterOnLoadedCallback(
      const base::RepeatingClosure& callback);

#if defined(UNIT_TEST)
  void set_loaded(bool value) { loaded_ = value; }

  // Turns Load() into a no-op.
  void set_disable_load(bool value) { disable_load_ = value; }
#endif

  // Whether or not the keywords have been loaded.
  bool loaded() { return loaded_; }

  // Notification that the keywords have been loaded.
  // This is invoked from WebDataService, and should not be directly
  // invoked.
  void OnWebDataServiceRequestDone(
      KeywordWebDataService::Handle h,
      std::unique_ptr<WDTypedResult> result) override;

  // Returns the locale-direction-adjusted short name for the given keyword.
  // Also sets the out param to indicate whether the keyword belongs to an
  // Omnibox extension.
  base::string16 GetKeywordShortName(
      const base::string16& keyword,
      bool* is_omnibox_api_extension_keyword) const;

  // Called by the history service when a URL is visited.
  void OnHistoryURLVisited(const URLVisitedDetails& details);

  // KeyedService implementation.
  void Shutdown() override;

  // syncer::SyncableService implementation.

  // Returns all syncable TemplateURLs from this model as SyncData. This should
  // include every search engine and no Extension keywords.
  syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override;
  // Process new search engine changes from Sync, merging them into our local
  // data. This may send notifications if local search engines are added,
  // updated or removed.
  syncer::SyncError ProcessSyncChanges(
      const base::Location& from_here,
      const syncer::SyncChangeList& change_list) override;
  // Merge initial search engine data from Sync and push any local changes up
  // to Sync. This may send notifications if local search engines are added,
  // updated or removed.
  syncer::SyncMergeResult MergeDataAndStartSyncing(
      syncer::ModelType type,
      const syncer::SyncDataList& initial_sync_data,
      std::unique_ptr<syncer::SyncChangeProcessor> sync_processor,
      std::unique_ptr<syncer::SyncErrorFactory> sync_error_factory) override;
  void StopSyncing(syncer::ModelType type) override;

  // Processes a local TemplateURL change for Sync. |turl| is the TemplateURL
  // that has been modified, and |type| is the Sync ChangeType that took place.
  // This may send a new SyncChange to the cloud. If our model has not yet been
  // associated with Sync, or if this is triggered by a Sync change, then this
  // does nothing.
  void ProcessTemplateURLChange(const base::Location& from_here,
                                const TemplateURL* turl,
                                syncer::SyncChange::SyncChangeType type);

  // Returns a SearchTermsData which can be used to call TemplateURL methods.
  const SearchTermsData& search_terms_data() const {
    return *search_terms_data_;
  }

  // Returns a SyncData with a sync representation of the search engine data
  // from |turl|.
  static syncer::SyncData CreateSyncDataFromTemplateURL(
      const TemplateURL& turl);

  // Creates a new heap-allocated TemplateURL* which is populated by overlaying
  // |sync_data| atop |existing_turl|.  |existing_turl| may be NULL; if not it
  // remains unmodified.  The caller owns the returned TemplateURL*.
  //
  // If the created TemplateURL is migrated in some way from out-of-date sync
  // data, an appropriate SyncChange is added to |change_list|.  If the sync
  // data is bad for some reason, an ACTION_DELETE change is added and the
  // function returns NULL.
  static std::unique_ptr<TemplateURL>
  CreateTemplateURLFromTemplateURLAndSyncData(
      TemplateURLServiceClient* client,
      PrefService* prefs,
      const SearchTermsData& search_terms_data,
      const TemplateURL* existing_turl,
      const syncer::SyncData& sync_data,
      syncer::SyncChangeList* change_list);

  // Returns a map mapping Sync GUIDs to pointers to syncer::SyncData.
  static SyncDataMap CreateGUIDToSyncDataMap(
      const syncer::SyncDataList& sync_data);

#if defined(UNIT_TEST)
  void set_clock(std::unique_ptr<base::Clock> clock) {
    clock_ = std::move(clock);
  }
#endif

 private:
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, TestManagedDefaultSearch);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
                           UpdateKeywordSearchTermsForURL);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
                           DontUpdateKeywordSearchForNonReplaceable);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ChangeGoogleBaseValue);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, MergeDeletesUnusedProviders);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, AddOmniboxExtensionKeyword);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ExtensionsWithSameKeywords);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
                           CheckEnginesWithSameKeywords);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, LastVisitedTimeUpdate);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
                           RepairPrepopulatedSearchEngines);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, UniquifyKeyword);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest,
                           IsLocalTemplateURLBetter);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest,
                           ResolveSyncKeywordConflict);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, PreSyncDeletes);
  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, MergeInSyncTemplateURL);
  FRIEND_TEST_ALL_PREFIXES(LocationBarModelTest, GoogleBaseURL);

  friend class InstantUnitTestBase;
  friend class Scoper;
  friend class TemplateURLServiceTestUtil;
  friend class TemplateUrlServiceAndroid;

  using GUIDToTURL = std::map<std::string, TemplateURL*>;

  // A mapping from keywords to the corresponding TemplateURLs and their
  // meaningful keyword lengths.  A keyword can appear only once here because
  // there can be only one active TemplateURL associated with a given keyword.
  using KeywordToTURLAndMeaningfulLength =
      std::map<base::string16, TURLAndMeaningfulLength>;

  // A mapping from domain names to corresponding TemplateURLs and their
  // meaningful keyword lengths.  Specifically, for a keyword that is a
  // hostname containing more than just a domain name, e.g., 'abc.def.com',
  // the keyword is added to this map under the domain key 'def.com'.  This
  // means multiple keywords from the same domain share the same key, so this
  // must be a multimap.
  using KeywordDomainToTURLAndMeaningfulLength =
      std::multimap<base::string16, TURLAndMeaningfulLength>;

  // Declaration of values to be used in an enumerated histogram to tally
  // changes to the default search provider from various entry points. In
  // particular, we use this to see what proportion of changes are from Sync
  // entry points, to help spot erroneous Sync activity.
  enum DefaultSearchChangeOrigin {
    // Various known Sync entry points.
    DSP_CHANGE_SYNC_PREF,
    DSP_CHANGE_SYNC_ADD,
    DSP_CHANGE_SYNC_DELETE,
    DSP_CHANGE_SYNC_NOT_MANAGED,
    // "Other" origins. We differentiate between Sync and not Sync so we know if
    // certain changes were intentionally from the system, or possibly some
    // unintentional change from when we were Syncing.
    DSP_CHANGE_SYNC_UNINTENTIONAL,
    // All changes that don't fall into another category; we can't reorder the
    // list for clarity as this would screw up stat collection.
    DSP_CHANGE_OTHER,
    // Changed through "Profile Reset" feature.
    DSP_CHANGE_PROFILE_RESET,
    // Changed by an extension through the Override Settings API.
    DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION,
    // New DSP during database/prepopulate data load, which was not previously
    // in the known engine set, and with no previous value in prefs.  The
    // typical time to see this is during first run.
    DSP_CHANGE_NEW_ENGINE_NO_PREFS,
    // Boundary value.
    DSP_CHANGE_MAX,
  };

  // Helper functor for FindMatchingKeywords(), for finding the range of
  // keywords which begin with a prefix.
  class LessWithPrefix;

  // Used to defer notifications until the last Scoper is destroyed by leaving
  // the scope of a code block.
  class Scoper;

  void Init(const Initializer* initializers, int num_initializers);

  // Given two engines with the same keyword, returns which should take
  // precedence.  While normal engines must all have distinct keywords,
  // extension-controlled and omnibox API engines may have the same keywords as
  // each other or as normal engines.  In these cases, omnibox API engines
  // override extension-controlled engines, which override normal engines; if
  // there is still a conflict after this, the most recently-added extension
  // wins.
  TemplateURL* BestEngineForKeyword(TemplateURL* engine1, TemplateURL* engine2);

  // Removes |template_url| from various internal maps
  // (|keyword_to_turl_and_length_|, |keyword_domain_to_turl_and_length_|,
  // |guid_to_turl_|, |provider_map_|).
  void RemoveFromMaps(const TemplateURL* template_url);

  // Adds |template_url| to various internal maps
  // (|keyword_to_turl_and_length_|, |keyword_domain_to_turl_and_length_|,
  // |guid_to_turl_|, |provider_map_|) if appropriate.  (It might not be
  // appropriate if, for instance, |template_url|'s keyword conflicts with
  // the keyword of a custom search engine already existing in the maps that
  // is not allowed to be replaced.)
  void AddToMaps(TemplateURL* template_url);

  // Helper function for removing an element from
  // |keyword_domain_to_turl_and_length_|.
  void RemoveFromDomainMap(const TemplateURL* template_url);

  // Helper fuction for adding an element to
  // |keyword_domain_to_turl_and_length_| if appropriate.
  void AddToDomainMap(TemplateURL* template_url);

  // Helper function for adding an element to |keyword_to_turl_and_length_|.
  void AddToMap(TemplateURL* template_url);

  // Sets the keywords. This is used once the keywords have been loaded.
  // This does NOT notify the delegate or the database.
  void SetTemplateURLs(std::unique_ptr<OwnedTemplateURLVector> urls);

  // Transitions to the loaded state.
  void ChangeToLoadedState();

  // Applies a DSE change and reports metrics if appropriate.
  void ApplyDefaultSearchChange(const TemplateURLData* new_dse_data,
                                DefaultSearchManager::Source source);


  // Applies a DSE change. May be called at startup or after transitioning to
  // the loaded state. Returns true if a change actually occurred.
  bool ApplyDefaultSearchChangeNoMetrics(const TemplateURLData* new_dse_data,
                                         DefaultSearchManager::Source source);

  // Returns false if there is a TemplateURL that has a search url with the
  // specified host and that TemplateURL has been manually modified.
  bool CanAddAutogeneratedKeywordForHost(const std::string& host) const;

  // Returns true if the TemplateURL is replaceable. This doesn't look at the
  // uniqueness of the keyword or host and is intended to be called after those
  // checks have been done. This returns true if the TemplateURL doesn't appear
  // in the default list and is marked as safe_for_autoreplace.
  bool CanReplace(const TemplateURL* t_url) const;

  // Like GetTemplateURLForKeyword(), but ignores extension-provided keywords.
  TemplateURL* FindNonExtensionTemplateURLForKeyword(
      const base::string16& keyword);

  // Updates the information in |existing_turl| using the information from
  // |new_values|, but the ID for |existing_turl| is retained. Returns whether
  // |existing_turl| was found in |template_urls_| and thus could be updated.
  //
  // NOTE: This should not be called with an extension keyword as there are no
  // updates needed in that case.
  bool Update(TemplateURL* existing_turl, const TemplateURL& new_values);

  // If the TemplateURL comes from a prepopulated URL available in the current
  // country, update all its fields save for the keyword, short name and id so
  // that they match the internal prepopulated URL. TemplateURLs not coming from
  // a prepopulated URL are not modified.
  static void UpdateTemplateURLIfPrepopulated(TemplateURL* existing_turl,
                                              PrefService* prefs);

  // If the TemplateURL's sync GUID matches the kSyncedDefaultSearchProviderGUID
  // preference it will be used to update the DSE in prefs.
  // OnDefaultSearchChange may be triggered as a result.
  void MaybeUpdateDSEViaPrefs(TemplateURL* synced_turl);

  // Iterates through the TemplateURLs to see if one matches the visited url.
  // For each TemplateURL whose url matches the visited url
  // SetKeywordSearchTermsForURL is invoked.
  void UpdateKeywordSearchTermsForURL(const URLVisitedDetails& details);

  // Updates the last_visited time of |url| to the current time.
  void UpdateTemplateURLVisitTime(TemplateURL* url);

  // If necessary, generates a visit for the site http:// + t_url.keyword().
  void AddTabToSearchVisit(const TemplateURL& t_url);

  // Requests the Google URL tracker to check the server if necessary.
  void RequestGoogleURLTrackerServerCheckIfNecessary();

  // Invoked when the Google base URL has changed. Updates the mapping for all
  // TemplateURLs that have a replacement term of {google:baseURL} or
  // {google:baseSuggestURL}.
  void GoogleBaseURLChanged();

  // Adds a new TemplateURL to this model.
  //
  // If |newly_adding| is false, we assume that this TemplateURL was already
  // part of the model in the past, and therefore we don't need to do things
  // like assign it an ID or notify sync.
  //
  // This function guarantees that on return the model will not have two non-
  // extension TemplateURLs with the same keyword.  If that means that it cannot
  // add the provided argument, it will return null.  Otherwise it will return
  // the raw pointer to the TemplateURL.
  //
  // Returns a raw pointer to |template_url| if the addition succeeded, or null
  // on failure.  (Many callers need still need a raw pointer to the TemplateURL
  // so they can access it later.)
  TemplateURL* Add(std::unique_ptr<TemplateURL> template_url,
                   bool newly_adding);

  // Updates |template_urls| so that the only "created by policy" entry is
  // |default_from_prefs|. |default_from_prefs| may be NULL if there is no
  // policy-defined DSE in effect.
  void UpdateProvidersCreatedByPolicy(
      OwnedTemplateURLVector* template_urls,
      const TemplateURLData* default_from_prefs);

  // Resets the sync GUID of the specified TemplateURL and persists the change
  // to the database. This does not notify observers.
  void ResetTemplateURLGUID(TemplateURL* url, const std::string& guid);

  // Attempts to generate a unique keyword for |turl| based on its original
  // keyword. If its keyword is already unique, that is returned. Otherwise, it
  // tries to return the autogenerated keyword if that is unique to the Service,
  // and finally it repeatedly appends special characters to the keyword until
  // it is unique to the Service. If |force| is true, then this will only
  // execute the special character appending functionality.
  base::string16 UniquifyKeyword(const TemplateURL& turl, bool force);

  // Returns true iff |local_turl| is considered "better" than |sync_turl| for
  // the purposes of resolving conflicts. |local_turl| must be a TemplateURL
  // known to the local model (though it may already be synced), and |sync_turl|
  // is a new TemplateURL known to Sync but not yet known to the local model.
  // The criteria for if |local_turl| is better than |sync_turl| is whether any
  // of the following are true:
  //  * |local_turl|'s last_modified timestamp is newer than sync_turl.
  //  * |local_turl| is created by policy.
  //  * |prefer_local_default| is true and |local_turl| is the local default
  //    search provider
  bool IsLocalTemplateURLBetter(const TemplateURL* local_turl,
                                const TemplateURL* sync_turl,
                                bool prefer_local_default = true) const;

  // Given two synced TemplateURLs with a conflicting keyword, one of which
  // needs to be added to or updated in the local model (|unapplied_sync_turl|)
  // and one which is already known to the local model (|applied_sync_turl|),
  // prepares the local model so that |unapplied_sync_turl| can be added to it,
  // or applied as an update to an existing TemplateURL.
  // Since both entries are known to Sync and one of their keywords will change,
  // an ACTION_UPDATE will be appended to |change_list| to reflect this change.
  // Note that |applied_sync_turl| must not be an extension keyword.
  void ResolveSyncKeywordConflict(TemplateURL* unapplied_sync_turl,
                                  TemplateURL* applied_sync_turl,
                                  syncer::SyncChangeList* change_list);

  // Adds |sync_turl| into the local model, possibly removing or updating a
  // local TemplateURL to make room for it. This expects |sync_turl| to be a new
  // entry from Sync, not currently known to the local model. |sync_data| should
  // be a SyncDataMap where the contents are entries initially known to Sync
  // during MergeDataAndStartSyncing.
  // Any necessary updates to Sync will be appended to |change_list|. This can
  // include updates on local TemplateURLs, if they are found in |sync_data|.
  // |initial_data| should be a SyncDataMap of the entries known to the local
  // model during MergeDataAndStartSyncing. If |sync_turl| replaces a local
  // entry, that entry is removed from |initial_data| to prevent it from being
  // sent up to Sync.
  // |merge_result| tracks the changes made to the local model. Added/modified/
  // deleted are updated depending on how the |sync_turl| is merged in.
  // This should only be called from MergeDataAndStartSyncing.
  void MergeInSyncTemplateURL(TemplateURL* sync_turl,
                              const SyncDataMap& sync_data,
                              syncer::SyncChangeList* change_list,
                              SyncDataMap* local_data,
                              syncer::SyncMergeResult* merge_result);

  // Goes through a vector of TemplateURLs and ensure that both the in-memory
  // and database copies have valid sync_guids. This is to fix crbug.com/102038,
  // where old entries were being pushed to Sync without a sync_guid.
  void PatchMissingSyncGUIDs(OwnedTemplateURLVector* template_urls);

  void OnSyncedDefaultSearchProviderGUIDChanged();

  // Adds to |matches| all TemplateURLs stored in |keyword_to_turl_and_length|
  // whose keywords begin with |prefix|, sorted shortest-keyword-first.  If
  // |supports_replacement_only| is true, only TemplateURLs that support
  // replacement are returned.
  template <typename Container>
  void AddMatchingKeywordsHelper(
      const Container& keyword_to_turl_and_length,
      const base::string16& prefix,
      bool supports_replacement_only,
      TURLsAndMeaningfulLengths* matches);

  // Returns the TemplateURL corresponding to |prepopulated_id|, if any.
  TemplateURL* FindPrepopulatedTemplateURL(int prepopulated_id);

  // Returns the TemplateURL associated with |extension_id|, if any.
  TemplateURL* FindTemplateURLForExtension(const std::string& extension_id,
                                           TemplateURL::Type type);

  // Finds any NORMAL_CONTROLLED_BY_EXTENSION engine that matches |data| and
  // wants to be default. Returns nullptr if not found.
  TemplateURL* FindMatchingDefaultExtensionTemplateURL(
      const TemplateURLData& data);

  // Returns whether |template_urls_| contains more than one normal engine with
  // same keyword. Used to validate state after search engines are
  // added/updated.
  bool HasDuplicateKeywords() const;

  // ---------- Browser state related members ---------------------------------
  PrefService* prefs_ = nullptr;

  std::unique_ptr<SearchTermsData> search_terms_data_ =
      std::make_unique<SearchTermsData>();

  // ---------- Dependencies on other components ------------------------------
  // Service used to store entries.
  scoped_refptr<KeywordWebDataService> web_data_service_ = nullptr;

  std::unique_ptr<TemplateURLServiceClient> client_;

  GoogleURLTracker* google_url_tracker_ = nullptr;

  // ---------- Metrics related members ---------------------------------------
  rappor::RapporServiceImpl* rappor_service_ = nullptr;

  // This closure is run when the default search provider is set to Google.
  base::RepeatingClosure dsp_change_callback_;

  PrefChangeRegistrar pref_change_registrar_;

  // Mapping from keyword to the TemplateURL.
  KeywordToTURLAndMeaningfulLength keyword_to_turl_and_length_;

  // Mapping from keyword domain to the TemplateURL.
  // Entries are only allowed here if there is a corresponding entry in
  // |keyword_to_turl_and_length_|, i.e., if a template URL doesn't have an
  // entry in |keyword_to_turl_and_length_| because it's subsumed by another
  // template URL with an identical keyword, the template URL will not have an
  // entry in this map either.  This map will also not bother including entries
  // for keywords in which the keyword is the domain name, with no subdomain
  // before the domain name.  (The ordinary |keyword_to_turl_and_length|
  // suffices for that.)
  KeywordDomainToTURLAndMeaningfulLength keyword_domain_to_turl_and_length_;

  // Mapping from Sync GUIDs to the TemplateURL.
  GUIDToTURL guid_to_turl_;

  OwnedTemplateURLVector template_urls_;

  base::ObserverList<TemplateURLServiceObserver>::Unchecked model_observers_;

  // Maps from host to set of TemplateURLs whose search url host is host.
  std::unique_ptr<SearchHostToURLsMap> provider_map_ =
      std::make_unique<SearchHostToURLsMap>();

  // Whether the keywords have been loaded.
  bool loaded_ = false;

  // Set when the web data service fails to load properly.  This prevents
  // further communication with sync or writing to prefs, so we don't persist
  // inconsistent state data anywhere.
  bool load_failed_ = false;

  // Whether Load() is disabled. True only in testing contexts.
  bool disable_load_ = false;

  // If non-zero, we're waiting on a load.
  KeywordWebDataService::Handle load_handle_ = 0;

  // All visits that occurred before we finished loading. Once loaded
  // UpdateKeywordSearchTermsForURL is invoked for each element of the vector.
  std::vector<URLVisitedDetails> visits_to_add_;

  // Once loaded, the default search provider.  This is a pointer to a
  // TemplateURL owned by |template_urls_|.
  TemplateURL* default_search_provider_ = nullptr;

  // A temporary location for the DSE until Web Data has been loaded and it can
  // be merged into |template_urls_|.
  std::unique_ptr<TemplateURL> initial_default_search_provider_;

  // Source of the default search provider.
  DefaultSearchManager::Source default_search_provider_source_;

  // ID assigned to next TemplateURL added to this model. This is an ever
  // increasing integer that is initialized from the database.
  TemplateURLID next_id_ = kInvalidTemplateURLID + 1;

  // Used to retrieve the current time, in base::Time units.
  std::unique_ptr<base::Clock> clock_ = std::make_unique<base::DefaultClock>();

  // Do we have an active association between the TemplateURLs and sync models?
  // Set in MergeDataAndStartSyncing, reset in StopSyncing. While this is not
  // set, we ignore any local search engine changes (when we start syncing we
  // will look up the most recent values anyways).
  bool models_associated_ = false;

  // Whether we're currently processing changes from the syncer. While this is
  // true, we ignore any local search engine changes, since we triggered them.
  bool processing_syncer_changes_ = false;

  // Sync's syncer::SyncChange handler. We push all our changes through this.
  std::unique_ptr<syncer::SyncChangeProcessor> sync_processor_;

  // Sync's error handler. We use it to create a sync error.
  std::unique_ptr<syncer::SyncErrorFactory> sync_error_factory_;

  // A set of sync GUIDs denoting TemplateURLs that have been removed from this
  // model or the underlying KeywordWebDataService prior to
  // MergeDataAndStartSyncing.
  // This set is used to determine what entries from the server we want to
  // ignore locally and return a delete command for.
  std::set<std::string> pre_sync_deletes_;

  // This is used to log the origin of changes to the default search provider.
  // We set this value to increasingly specific values when we know what is the
  // cause/origin of a default search change.
  DefaultSearchChangeOrigin dsp_change_origin_ = DSP_CHANGE_OTHER;

  // Stores a list of callbacks to be run after TemplateURLService has loaded.
  base::CallbackList<void(void)> on_loaded_callbacks_;

  // Helper class to manage the default search engine.
  DefaultSearchManager default_search_manager_;

  std::unique_ptr<GoogleURLTracker::Subscription>
      google_url_updated_subscription_;

  // This tracks how many Scoper handles exist. When the number of handles drops
  // to zero, a notification is made to observers if
  // |model_mutated_notification_pending_| is true.
  int outstanding_scoper_handles_ = 0;

  // Used to track if a notification is necessary due to the model being
  // mutated. The outermost Scoper handles, can be used to defer notifications,
  // but if no model mutation occurs, the deferred notification can be skipped.
  bool model_mutated_notification_pending_ = false;

  DISALLOW_COPY_AND_ASSIGN(TemplateURLService);
};

#endif  // COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_
