// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_OMNIBOX_BROWSER_REMOTE_SUGGESTIONS_SERVICE_H_
#define COMPONENTS_OMNIBOX_BROWSER_REMOTE_SUGGESTIONS_SERVICE_H_

#include <map>
#include <memory>
#include <optional>
#include <string>

#include "base/functional/callback_forward.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
#include "base/types/optional_ref.h"
#include "base/unguessable_token.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/enterprise_search_aggregator_suggestions_service.h"
#include "components/search_engines/template_url.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"

class DocumentSuggestionsService;
class EnterpriseSearchAggregatorSuggestionsService;

using EnterpriseSearchAggregatorSuggestionType =
    AutocompleteMatch::EnterpriseSearchAggregatorType;

namespace network {
class SharedURLLoaderFactory;
class SimpleURLLoader;
struct ResourceRequest;
}  // namespace network

// The types of requests for remote suggestions.
// These values are written to logs. New enum values can be added, but existing
// enums must never be renumbered or deleted and reused.
// Must be kept in sync with RemoteRequestType enum and variant.
// LINT.IfChange(RemoteRequestType)
enum class RemoteRequestType {
  // Search suggestion requests.
  kSearch = 0,
  // Search suggestion warm-up requests.
  kSearchWarmup = 1,
  // Search suggestion requests to obtain images.
  kImages = 2,
  // Zero-prefix suggestion requests.
  kZeroSuggest = 3,
  // Zero-prefix suggestion prefetching requests.
  kZeroSuggestPrefetch = 4,
  // Document suggestion requests.
  kDocumentSuggest = 5,
  // Suggestion deletion requests.
  kDeletion = 6,
  // Enterprise Search Aggregator suggestion requests.
  kEnterpriseSearchAggregatorSuggest = 7,
  kMaxValue = kEnterpriseSearchAggregatorSuggest,
};
// LINT.ThenChange(
//     //tools/metrics/histograms/metadata/omnibox/enums.xml:RemoteRequestType,
//     //tools/metrics/histograms/metadata/omnibox/histograms.xml:RemoteRequestType
// )

// The event types recorded by the providers for remote suggestions. Each event
// must be logged at most once from when the provider is started until it is
// stopped.
// These values are written to logs. New enum values can be added, but existing
// enums must never be renumbered or deleted and reused.
enum class RemoteRequestEvent {
  // Cached response was synchronously converted to displayed matches.
  // Recorded for non-prefetch requests only.
  kCachedResponseConvertedToMatches = 0,
  // Request was sent.
  kRequestSent = 1,
  // Request was invalidated.
  kRequestInvalidated = 2,
  // Response was received asynchronously.
  kResponseReceived = 3,
  // Response was cached.
  kResponseCached = 4,
  // Response ended up being converted to displayed matches. This may happen due
  // to an empty displayed result set or an empty remote result set.
  // Recorded for non-prefetch requests only.
  kResponseConvertedToMatches = 5,
  kMaxValue = kResponseConvertedToMatches,
};

// A service to fetch suggestions from a search provider's suggest endpoint.
// Used by ZeroSuggestProvider, SearchProvider, DocumentProvider, and
// ImageService.
//
// This service is always sent the user's authentication state, so the
// suggestions always can be personalized. This service is also sometimes sent
// the user's current URL, so the suggestions are sometimes also contextual.
class RemoteSuggestionsService : public KeyedService {
 public:
  class Observer : public base::CheckedObserver {
   public:
    // Called when the request has been created. `request_id` identifies the
    // request. `request` is deleted after this call once the transfer starts.
    virtual void OnRequestCreated(const base::UnguessableToken& request_id,
                                  const network::ResourceRequest* request) {}
    // Called when the transfer has started. `request_id` identifies the
    // request. `request_body` is the HTTP POST upload body, if applicable.
    virtual void OnRequestStarted(const base::UnguessableToken& request_id,
                                  network::SimpleURLLoader* loader,
                                  const std::string& request_body) {}
    // Called when the transfer is done. `request_id` identifies the request.
    // `response_code` is the response status code. A status code of 200
    // indicates that the request has succeeded and `response_body` is
    // populated.
    virtual void OnRequestCompleted(
        const base::UnguessableToken& request_id,
        const int response_code,
        const std::unique_ptr<std::string>& response_body) {}
  };

  // Called when the transfer has started asynchronously, e.g., after obtaining
  // an OAuth token.
  using StartCallback = base::OnceCallback<void(
      std::unique_ptr<network::SimpleURLLoader> loader)>;
  // Called when the transfer is done. `response_code` is the response status
  // code. A status code of 200 indicates that the request has succeeded and
  // `response_body` is populated.
  using CompletionCallback =
      base::OnceCallback<void(const network::SimpleURLLoader* source,
                              const int response_code,
                              std::unique_ptr<std::string> response_body)>;
  // Same as `StartCallback` but for requests that are associated with a
  // `request_index`.
  using IndexedStartCallback = base::RepeatingCallback<void(
      const int request_index,
      std::unique_ptr<network::SimpleURLLoader> loader)>;
  // Same as `CompletionCallback` but for requests that are associated with a
  // `request_index`.
  using IndexedCompletionCallback =
      base::RepeatingCallback<void(const int request_index,
                                   const network::SimpleURLLoader* source,
                                   const int response_code,
                                   std::unique_ptr<std::string> response_body)>;

  class Delegate {
   public:
    Delegate();
    virtual ~Delegate();
    Delegate(const Delegate&) = delete;
    Delegate& operator=(const Delegate&) = delete;

    // Called when the transfer is done. Delegates invocation of
    // `completion_callback`
    virtual void OnRequestCompleted(const network::SimpleURLLoader* source,
                                    const int response_code,
                                    std::unique_ptr<std::string> response_body,
                                    CompletionCallback completion_callback) = 0;

    virtual void OnIndexedRequestCompleted(
        const int request_index,
        const network::SimpleURLLoader* source,
        const int response_code,
        std::unique_ptr<std::string> response_body,
        IndexedCompletionCallback completion_callback) = 0;

   protected:
    base::WeakPtrFactory<Delegate> weak_ptr_factory_{this};
  };

  RemoteSuggestionsService(
      DocumentSuggestionsService* document_suggestions_service,
      EnterpriseSearchAggregatorSuggestionsService*
          enterprise_search_aggregator_suggestions_service,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
  ~RemoteSuggestionsService() override;
  RemoteSuggestionsService(const RemoteSuggestionsService&) = delete;
  RemoteSuggestionsService& operator=(const RemoteSuggestionsService&) = delete;

  // Helper to set the time request of type `request_type` has started in
  // `time_request_sent_`.
  void SetTimeRequestSent(RemoteRequestType request_type, base::TimeTicks time);

  // Returns the suggest endpoint URL for `template_url`.
  // `search_terms_args` is used to build the endpoint URL.
  // `search_terms_data` is used to build the endpoint URL.
  static GURL EndpointUrl(
      const TemplateURL& template_url,
      const TemplateURLRef::SearchTermsArgs& search_terms_args,
      const SearchTermsData& search_terms_data);

  // Creates and returns a loader for remote suggestions for `template_url`.
  // It uses a number of signals to create the loader, including field trial
  // parameters.
  //
  // `template_url` must not be nullptr.
  // `search_terms_args` is used to build the endpoint URL.
  // `search_terms_data` is used to build the endpoint URL.
  // `completion_callback` will be invoked when the transfer is done.
  std::unique_ptr<network::SimpleURLLoader> StartSuggestionsRequest(
      RemoteRequestType request_type,
      bool is_off_the_record,
      const TemplateURL* template_url,
      TemplateURLRef::SearchTermsArgs search_terms_args,
      const SearchTermsData& search_terms_data,
      CompletionCallback completion_callback);

  // Creates and returns a loader for remote zero-prefix suggestions for
  // `template_url`. It uses a number of signals to create the loader, including
  // field trial parameters.
  //
  // `template_url` must not be nullptr.
  // `search_terms_args` is used to build the endpoint URL.
  // `search_terms_data` is used to build the endpoint URL.
  // `completion_callback` will be invoked when the transfer is done.
  //
  // When `timeout` is not empty, its value is set in `SimpleURLLoadaer` used
  // internally. When the timeout occurs, a nullptr is passed to the callback:
  // https://source.chromium.org/chromium/chromium/src/+/main:services/network/public/cpp/simple_url_loader.cc;l=758-764;drc=128f35b3fb019f2fa67e1e798e113ed95f766096
  std::unique_ptr<network::SimpleURLLoader> StartZeroPrefixSuggestionsRequest(
      RemoteRequestType request_type,
      bool is_off_the_record,
      const TemplateURL* template_url,
      TemplateURLRef::SearchTermsArgs search_terms_args,
      const SearchTermsData& search_terms_data,
      CompletionCallback completion_callback,
      base::optional_ref<const base::TimeDelta> timeout = std::nullopt);

  // Creates and starts a document suggestion request for `query` asynchronously
  // after obtaining an OAuth2 token for the signed-in users.
  void CreateDocumentSuggestionsRequest(
      const std::u16string& query,
      bool is_off_the_record,
      metrics::OmniboxEventProto::PageClassification page_classification,
      StartCallback start_callback,
      CompletionCallback completion_callback);

  // Stops creating the request. Already created requests aren't affected.
  void StopCreatingDocumentSuggestionsRequest();

  // Creates and starts an enterprise search aggregator suggestion request using
  //  `suggest_url` and `response_body` asynchronously after obtaining an OAuth2
  //  token for signed-in enterprise users.
  void CreateEnterpriseSearchAggregatorSuggestionsRequest(
      const std::u16string& query,
      const GURL& suggest_url,
      metrics::OmniboxEventProto::PageClassification page_classification,
      std::vector<int> callback_indexes,
      std::vector<std::vector<int>> suggestion_types,
      IndexedStartCallback start_callback,
      IndexedCompletionCallback completion_callback);

  // Stops creating the request. Already created requests aren't affected.
  void StopCreatingEnterpriseSearchAggregatorSuggestionsRequest();

  // Creates and returns a loader to delete personalized suggestions.
  //
  // `deletion_url` must be a valid URL.
  // `completion_callback` will be invoked when the transfer is done.
  std::unique_ptr<network::SimpleURLLoader> StartDeletionRequest(
      const std::string& deletion_url,
      bool is_off_the_record,
      CompletionCallback completion_callback);

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  void SetDelegate(base::WeakPtr<Delegate> delegate);

  // Exposed for testing.
  void set_url_loader_factory_for_testing(
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);

 private:
  // Called when the request has been created, before the transfer has started.
  // Notifies `observers_`.
  void OnRequestCreated(const base::UnguessableToken& request_id,
                        network::ResourceRequest* request);
  // Called when the transfer has started. Notifies `observers_`.
  void OnRequestStarted(
      const base::UnguessableToken& request_id,
      RemoteRequestType request_type,
      metrics::OmniboxEventProto::PageClassification page_classification,
      network::SimpleURLLoader* loader,
      const std::string& request_body);
  // Called when the transfer has started asynchronously, e.g., after obtaining
  // an OAuth token. Notifies `observers_` and calls `start_callback` to
  // transfer the ownership of `loader` to the caller.
  void OnRequestStartedAsync(
      const base::UnguessableToken& request_id,
      RemoteRequestType request_type,
      metrics::OmniboxEventProto::PageClassification page_classification,
      StartCallback start_callback,
      std::unique_ptr<network::SimpleURLLoader> loader,
      const std::string& request_body);
  void OnIndexedRequestStartedAsync(
      const base::UnguessableToken& request_id,
      RemoteRequestType request_type,
      metrics::OmniboxEventProto::PageClassification page_classification,
      IndexedStartCallback start_callback,
      int request_index,
      std::unique_ptr<network::SimpleURLLoader> loader,
      const std::string& request_body);
  // Called when the transfer is done. Notifies `observers_` and calls
  // `completion_callback` passing the response to the caller.
  void OnRequestCompleted(
      const base::UnguessableToken& request_id,
      RemoteRequestType request_type,
      base::ElapsedTimer request_timer,
      metrics::OmniboxEventProto::PageClassification page_classification,
      CompletionCallback completion_callback,
      const network::SimpleURLLoader* source,
      std::unique_ptr<std::string> response_body);

  void OnIndexedRequestCompleted(
      const base::UnguessableToken& request_id,
      RemoteRequestType request_type,
      metrics::OmniboxEventProto::PageClassification page_classification,
      base::TimeTicks start_time,
      IndexedCompletionCallback completion_callback,
      const network::SimpleURLLoader* source,
      int request_index,
      std::unique_ptr<std::string> response_body);

  // May be nullptr in OTR profiles. Otherwise guaranteed to outlive this due to
  // the factories' dependency.
  raw_ptr<DocumentSuggestionsService> document_suggestions_service_;
  // May be nullptr in OTR profiles. Otherwise guaranteed to outlive this due to
  // the factories' dependency.
  raw_ptr<EnterpriseSearchAggregatorSuggestionsService>
      enterprise_search_aggregator_suggestions_service_;
  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
  // Time request sent for each RemoteRequestType. Used for histogram logging.
  std::map<RemoteRequestType, base::TimeTicks> time_request_sent_;
  // Observers being notified of request start and completion events.
  base::ObserverList<Observer> observers_;
  // Delegate to which invocation of completion callback is delegated.
  base::WeakPtr<Delegate> delegate_;
  // Used to bind `OnURLLoadComplete` to the network loader's callback as the
  // loader is no longer owned by `this` once returned.
  base::WeakPtrFactory<RemoteSuggestionsService> weak_ptr_factory_{this};
};

#endif  // COMPONENTS_OMNIBOX_BROWSER_REMOTE_SUGGESTIONS_SERVICE_H_
