// Copyright (c) 2011 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.
//
// This file contains the Search autocomplete provider.  This provider is
// responsible for all non-keyword autocomplete entries that start with
// "Search <engine> for ...", including searching for the current input string,
// search history, and search suggestions.  An instance of it gets created and
// managed by the autocomplete controller.
//
// For more information on the autocomplete system in general, including how
// the autocomplete controller and autocomplete providers work, see
// chrome/browser/autocomplete.h.

#ifndef CHROME_BROWSER_AUTOCOMPLETE_SEARCH_PROVIDER_H_
#define CHROME_BROWSER_AUTOCOMPLETE_SEARCH_PROVIDER_H_
#pragma once

#include <map>
#include <string>
#include <vector>

#include "base/memory/scoped_ptr.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_match.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_id.h"
#include "chrome/common/net/url_fetcher.h"

class Profile;
class Value;

// Autocomplete provider for searches and suggestions from a search engine.
//
// After construction, the autocomplete controller repeatedly calls Start()
// with some user input, each time expecting to receive a small set of the best
// matches (either synchronously or asynchronously).
//
// Initially the provider creates a match that searches for the current input
// text.  It also starts a task to query the Suggest servers.  When that data
// comes back, the provider creates and returns matches for the best
// suggestions.
class SearchProvider : public AutocompleteProvider,
                       public URLFetcher::Delegate {
 public:
  SearchProvider(ACProviderListener* listener, Profile* profile);

#if defined(UNIT_TEST)
  static void set_query_suggest_immediately(bool value) {
    query_suggest_immediately_ = value;
  }
#endif

  // Marks the instant query as done. If |input_text| is non-empty this changes
  // the 'search what you typed' results text to |input_text| + |suggest_text|.
  // |input_text| is the text the user input into the edit. |input_text| differs
  // from |input_.text()| if the input contained whitespace.
  //
  // This method also marks the search provider as no longer needing to wait for
  // the instant result.
  void FinalizeInstantQuery(const string16& input_text,
                            const string16& suggest_text);

  // AutocompleteProvider
  virtual void Start(const AutocompleteInput& input,
                     bool minimal_changes);
  virtual void Stop();

  // URLFetcher::Delegate
  virtual void OnURLFetchComplete(const URLFetcher* source,
                                  const GURL& url,
                                  const net::URLRequestStatus& status,
                                  int response_code,
                                  const ResponseCookies& cookies,
                                  const std::string& data);

  // ID used in creating URLFetcher for default provider's suggest results.
  static const int kDefaultProviderURLFetcherID;

  // ID used in creating URLFetcher for keyword provider's suggest results.
  static const int kKeywordProviderURLFetcherID;

 private:
  ~SearchProvider();

  // Manages the providers (TemplateURLs) used by SearchProvider. Two providers
  // may be used:
  // . The default provider. This corresponds to the user's default search
  //   engine. This is always used, except for the rare case of no default
  //   engine.
  // . The keyword provider. This is used if the user has typed in a keyword.
  class Providers {
   public:
    Providers() : default_provider_(NULL), keyword_provider_(NULL) {}

    // Returns true if the specified providers match the two providers managed
    // by this class.
    bool equals(const TemplateURL* default_provider,
                const TemplateURL* keyword_provider) {
      return (default_provider == default_provider_ &&
              keyword_provider == keyword_provider_);
    }

    // Resets the providers.
    void Set(const TemplateURL* default_provider,
             const TemplateURL* keyword_provider);

    const TemplateURL& default_provider() const {
      DCHECK(valid_default_provider());
      return cached_default_provider_;
    }

    const TemplateURL& keyword_provider() const {
      DCHECK(valid_keyword_provider());
      return cached_keyword_provider_;
    }

    // Returns true of the keyword provider is valid.
    bool valid_keyword_provider() const { return !!keyword_provider_; }

    // Returns true if the keyword provider is valid and has a valid suggest
    // url.
    bool valid_suggest_for_keyword_provider() const {
      return keyword_provider_ && cached_keyword_provider_.suggestions_url();
    }

    // Returns true of the default provider is valid.
    bool valid_default_provider() const { return !!default_provider_; }

    // Returns true if the default provider is valid and has a valid suggest
    // url.
    bool valid_suggest_for_default_provider() const {
      return default_provider_ && cached_default_provider_.suggestions_url();
    }

    // Returns true if |from_keyword_provider| is true, or
    // the keyword provider is not valid.
    bool is_primary_provider(bool from_keyword_provider) const {
      return from_keyword_provider || !valid_keyword_provider();
    }

   private:
    // Cached across the life of a query so we behave consistently even if the
    // user changes their default while the query is running.
    TemplateURL cached_default_provider_;
    TemplateURL cached_keyword_provider_;

    // TODO(pkasting): http://b/1162970  We shouldn't need these.
    const TemplateURL* default_provider_;
    const TemplateURL* keyword_provider_;
  };

  struct NavigationResult {
    NavigationResult(const GURL& url, const string16& site_name)
        : url(url),
          site_name(site_name) {
    }

    // The URL.
    GURL url;

    // Name for the site.
    string16 site_name;
  };

  typedef std::vector<string16> SuggestResults;
  typedef std::vector<NavigationResult> NavigationResults;
  typedef std::vector<history::KeywordSearchTermVisit> HistoryResults;
  typedef std::map<string16, AutocompleteMatch> MatchMap;

  // Called when timer_ expires.
  void Run();

  // Runs the history query, if necessary. The history query is synchronous.
  // This does not update |done_|.
  void DoHistoryQuery(bool minimal_changes);

  // Determines whether an asynchronous subcomponent query should run for the
  // current input.  If so, starts it if necessary; otherwise stops it.
  // NOTE: This function does not update |done_|.  Callers must do so.
  void StartOrStopSuggestQuery(bool minimal_changes);

  // Returns true when the current query can be sent to the Suggest service.
  // This will be false e.g. when Suggest is disabled, the query contains
  // potentially private data, etc.
  bool IsQuerySuitableForSuggest() const;

  // Stops the suggest query.
  // NOTE: This does not update |done_|.  Callers must do so.
  void StopSuggest();

  // Creates a URLFetcher requesting suggest results for the specified
  // TemplateURL. Ownership of the returned URLFetchet passes to the caller.
  URLFetcher* CreateSuggestFetcher(int id,
                                   const TemplateURL& provider,
                                   const string16& text);

  // Parses the results from the Suggest server and stores up to kMaxMatches of
  // them in server_results_.  Returns whether parsing succeeded.
  bool ParseSuggestResults(Value* root_val,
                           bool is_keyword,
                           const string16& input_text,
                           SuggestResults* suggest_results);

  // Converts the parsed server results in server_results_ to a set of
  // AutocompleteMatches and adds them to |matches_|.  This also sets |done_|
  // correctly.
  void ConvertResultsToAutocompleteMatches();

  // Converts the first navigation result in |navigation_results| to an
  // AutocompleteMatch and adds it to |matches_|.
  void AddNavigationResultsToMatches(
    const NavigationResults& navigation_results,
    bool is_keyword);

  // Adds a match for each result in |results| to |map|. |is_keyword| indicates
  // whether the results correspond to the keyword provider or default provider.
  void AddHistoryResultsToMap(const HistoryResults& results,
                              bool is_keyword,
                              int did_not_accept_suggestion,
                              MatchMap* map);

  // Adds a match for each result in |suggest_results| to |map|. |is_keyword|
  // indicates whether the results correspond to the keyword provider or default
  // provider.
  void AddSuggestResultsToMap(const SuggestResults& suggest_results,
                              bool is_keyword,
                              int did_not_accept_suggestion,
                              MatchMap* map);

  // Determines the relevance for a particular match.  We use different scoring
  // algorithms for the different types of matches.
  int CalculateRelevanceForWhatYouTyped() const;
  // |time| is the time at which this query was last seen. |is_keyword| is true
  // if the search is from the keyword provider. |looks_like_url| is true if the
  // search term would be treated as a URL if typed into the omnibox.
  int CalculateRelevanceForHistory(const base::Time& time,
                                   bool looks_like_url,
                                   bool is_keyword) const;
  // |result_number| is the index of the suggestion in the result set from the
  // server; the best suggestion is suggestion number 0.  |is_keyword| is true
  // if the search is from the keyword provider.
  int CalculateRelevanceForSuggestion(size_t num_results,
                                      size_t result_number,
                                      bool is_keyword) const;
  // |result_number| is same as above. |is_keyword| is true if the navigation
  // result was suggested by the keyword provider.
  int CalculateRelevanceForNavigation(size_t num_results,
                                      size_t result_number,
                                      bool is_keyword) const;

  // Creates an AutocompleteMatch for "Search <engine> for |query_string|" with
  // the supplied relevance.  Adds this match to |map|; if such a match already
  // exists, whichever one has lower relevance is eliminated.
  void AddMatchToMap(const string16& query_string,
                     const string16& input_text,
                     int relevance,
                     AutocompleteMatch::Type type,
                     int accepted_suggestion,
                     bool is_keyword,
                     bool prevent_inline_autocomplete,
                     MatchMap* map);

  // Returns an AutocompleteMatch for a navigational suggestion.
  AutocompleteMatch NavigationToMatch(const NavigationResult& query_string,
                                      int relevance,
                                      bool is_keyword);

  // Updates the value of |done_| from the internal state.
  void UpdateDone();

  // Updates the description/description_class of the first search match.
  void UpdateFirstSearchMatchDescription();

  // Should we query for suggest results immediately? This is normally false,
  // but may be set to true during testing.
  static bool query_suggest_immediately_;

  // Maintains the TemplateURLs used.
  Providers providers_;

  // The user's input.
  AutocompleteInput input_;

  // Input text when searching against the keyword provider.
  string16 keyword_input_text_;

  // Searches in the user's history that begin with the input text.
  HistoryResults keyword_history_results_;
  HistoryResults default_history_results_;

  // Number of suggest results that haven't yet arrived. If greater than 0 it
  // indicates either |timer_| or one of the URLFetchers is still running.
  int suggest_results_pending_;

  // A timer to start a query to the suggest server after the user has stopped
  // typing for long enough.
  base::OneShotTimer<SearchProvider> timer_;

  // The fetcher that retrieves suggest results for the keyword from the server.
  scoped_ptr<URLFetcher> keyword_fetcher_;

  // The fetcher that retrieves suggest results for the default engine from the
  // server.
  scoped_ptr<URLFetcher> default_fetcher_;

  // Suggestions returned by the Suggest server for the input text.
  SuggestResults keyword_suggest_results_;
  SuggestResults default_suggest_results_;

  // Navigational suggestions returned by the server.
  NavigationResults keyword_navigation_results_;
  NavigationResults default_navigation_results_;

  // Whether suggest_results_ is valid.
  bool have_suggest_results_;

  // Has FinalizeInstantQuery been invoked since the last |Start|?
  bool instant_finalized_;

  // The |suggest_text| parameter passed to FinalizeInstantQuery.
  string16 default_provider_suggest_text_;

  DISALLOW_COPY_AND_ASSIGN(SearchProvider);
};

#endif  // CHROME_BROWSER_AUTOCOMPLETE_SEARCH_PROVIDER_H_
