// Copyright 2022 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_AUTOCOMPLETE_CONTROLLER_METRICS_H_
#define COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_CONTROLLER_METRICS_H_

#include <string>

#include "base/memory/raw_ptr.h"
#include "components/omnibox/browser/autocomplete_result.h"

class AutocompleteController;
class AutocompleteProvider;

// Used to track and log timing metrics for `AutocompleteController`. Logs 3
// sets of metrics:
// 1) How long until each async provider completes.
//    - Does not track intermediate updates if an async provider updates results
//      multiple times.
//    - Does not track sync providers (i.e., providers that don't use
//      `AutocompleteProvider::NotifyListeners()` to notify the
//      `AutocompleteController`.
//    - Tracks async providers completing syncly (i.e., providers that invoke
//      `AutocompleteProvider::NotifyListeners()` syncly; see the comment in
//      `AutocompleteController::OnProviderUpdate()`).
// 2) How long until the suggestions finalize.
//    - Does not track sync requests (i.e.,
//      `AutocompleteInput::omit_asynchronous_matches()` set to true).
//    - Does track async requests that complete syncly.
//    - Tracks suggestion additions, changes, and removals.
// 3) How many suggestions change during updates.
//    - Does not track sync request.
//    - Tracks both sync and async updates.
//    - Does not track suggestion removals.
//    - Tracks suggestion additions and changes.
class AutocompleteControllerMetrics {
 public:
  explicit AutocompleteControllerMetrics(
      const AutocompleteController& controller);

  // Called when `AutocompleteController::Start()` is called. Will 1) log
  // suggestion finalization metrics for the previous request if it hasn't
  // already (i.e. if it hasn't completed and is being interrupted), and 2)
  // reset state to track the new request. Should be called before
  // `AutocompleteController::done()`,
  // `::expire_timer_done()`, or `AutocompleteProvider::done()` have been
  // updated for the new request.
  void OnStart();

  // Called when `AutocompleteController::UpdateResult()` is called. Will log
  // metrics on how many suggestions changed with this update. If the controller
  // is done, will also log suggestion finalization metrics; otherwise, future
  // calls to `OnProviderUpdate()`, `OnStop()`, or `OnStart()` will log
  // suggestion finalization metrics.
  void OnUpdateResult(
      std::vector<AutocompleteResult::MatchDedupComparator> last_result,
      std::vector<AutocompleteResult::MatchDedupComparator> new_result);

  // Called when `AutocompleteController::OnProviderUpdate()` is called. If the
  // provider is done, will log how long it took; otherwise, future calls to
  // `OnProviderUpdate()`, `OnStop()`, or `OnStart()` will log how long the
  // provider took.
  void OnProviderUpdate(const AutocompleteProvider& provider) const;

  // Called when either `AutocompleteController::StopHelper()` or `OnStart()`
  // are called; i.e., when the ongoing request, if incomplete, will be
  // interrupted, e.g., because the input was updated, the popup was closed, or
  // the `AutocompleteController::stop_timer_` expired. Should be called before
  // `AutocompleteController::done()`, `::expire_timer_done()`, or
  // `AutocompleteProvider::done()` have been updated.
  void OnStop();

 private:
  friend class AutocompleteControllerMetricsTest;

  // Checks `controller_` `done()`, `expire_timer_done()` and `in_start()` to
  // determine whether the controller is absolutely done; i.e., there won't be
  // any changes to results until the next user action. Just checking `done()`
  // isn't sufficient, as the expiring copied matches can change the results.
  // Just checking `done()` and `expire_timer_done()` isn't sufficient, as
  // they'll both be true during the sync pass, and all async providers complete
  // during the sync pass, there won't be a followup async update to trigger
  // logging metrics.
  bool ControllerIdle();

  // Logs
  // 'Omnibox.AsyncAutocompletionTime.[Done|LastChange|LastDefaultChange]'.
  // Additionally logs either '*.Completed' or '*.Interrupted' for each of the
  // 3 depending on whether the controller completed or was interrupted.
  void LogSuggestionFinalizationMetrics();

  // Logs 'Omnibox.AsyncAutocompletionTime.Provider.<provider name>'.
  // Additionally logs either '*.Completed' or '*.Interrupted' depending
  // whether the provider completed or was interrupted.
  void LogProviderTimeMetrics(const AutocompleteProvider& provider) const;

  // Helper for the above 2 logging methods. Logs
  // 'Omnibox.AsyncAutocompletionTime.<name>'. Additionally logs either
  // '*.Completed' or '*.Interrupted' depending on `completed`.
  void LogAsyncAutocompletionTimeMetrics(const std::string& name,
                                         bool completed,
                                         const base::TimeTicks end_time) const;

  // Logs 'Omnibox.MatchStability.MatchChangeIndex'. Additionally logs
  // '*.CrossInput' or '*.Async' depending on `controller_.in_start()`.
  void LogSuggestionChangeIndexMetrics(size_t change_index) const;

  // Logs 'Omnibox.MatchStability.MatchChangeInAnyPosition'. Additionally logs
  // '*.CrossInput' or '*.Async' depending on `controller_.in_start()`.
  void LogSuggestionChangeInAnyPositionMetrics(bool changed) const;

  const AutocompleteController& controller_;

  // When `OnStart()` was last invoked. Used for measuring latency. Valid even
  // if `controller_.in_start_` is false.
  base::TimeTicks start_time_;
  // When `OnProviderUpdate()` was last invoked and detected any change to the
  // suggestions.
  base::TimeTicks last_change_time_;
  // When `OnProviderUpdate()` was last invoked and detected a change to the
  // default suggestion.
  base::TimeTicks last_default_change_time_;
  // Whether `LogSuggestionFinalizationMetrics()` has been invoked for the
  // current request.
  bool logged_finalization_metrics_ = true;
};

#endif  // COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_CONTROLLER_METRICS_H_
