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

#include "autocomplete_controller_metrics.h"

#include <string>

#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "components/omnibox/browser/autocomplete_controller.h"
#include "components/omnibox/browser/autocomplete_provider.h"
#include "components/omnibox/browser/autocomplete_result.h"

AutocompleteControllerMetrics::AutocompleteControllerMetrics(
    const AutocompleteController& controller)
    : controller_(controller) {}

void AutocompleteControllerMetrics::OnStart() {
  OnStop();
  logged_finalization_metrics_ = false;
  start_time_ = base::TimeTicks::Now();
  last_change_time_ = start_time_;
  last_default_change_time_ = start_time_;
}

void AutocompleteControllerMetrics::OnNotifyChanged(
    std::vector<AutocompleteResult::MatchDedupComparator> last_result,
    std::vector<AutocompleteResult::MatchDedupComparator> new_result) {
  // Only log metrics for async requests.
  if (controller_->input().omit_asynchronous_matches())
    return;

  // If results are empty then the omnibox is likely closed, and clearing old
  // results won't be user visible. E.g., this occurs when opening a new tab
  // while the popup was open.
  if (new_result.empty())
    return;

  // Log suggestion changes.

  bool any_match_changed_or_removed = false;
  for (size_t i = 0; i < last_result.size(); ++i) {
    // Log changed or removed matches. Don't log for matches appended to the
    // bottom since that's less disruptive.
    if (i >= new_result.size() || last_result[i] != new_result[i]) {
      LogSuggestionChangeIndexMetrics(i);
      any_match_changed_or_removed = true;
    }
  }
  LogSuggestionChangeInAnyPositionMetrics(any_match_changed_or_removed);

  // Log suggestion finalization times.
  // This handles logging as soon as the final update occurs, while `OnStop()`
  // handles the case where the final update never occurs because of
  // interruptions.

  // E.g., suggestion deletion can call `OnNotifyChanged()` after the controller
  // is done and finalization metrics have been logged. They shouldn't be
  // re-logged.
  if (logged_finalization_metrics_)
    return;

  const bool any_match_changed_or_removed_or_added =
      any_match_changed_or_removed || last_result.size() != new_result.size();
  const bool default_match_changed_or_removed_or_added =
      last_result.empty() || last_result[0] != new_result[0];

  if (any_match_changed_or_removed_or_added)
    last_change_time_ = base::TimeTicks::Now();
  if (default_match_changed_or_removed_or_added) {
    DCHECK(any_match_changed_or_removed_or_added);
    last_default_change_time_ = last_change_time_;
  }
  // It's common to have multiple async updates per input. Only log the final
  // update.
  if (ControllerIdle())
    LogSuggestionFinalizationMetrics();
}

void AutocompleteControllerMetrics::OnProviderUpdate(
    const AutocompleteProvider& provider) const {
  // Only log metrics for async requests. This will likely never happen, since
  // `OnProviderUpdate()` is only called by async providers (but not necessarily
  // async'ly, see the comments in
  // `AutocompleteController::OnProviderUpdate()`).
  if (controller_->input().omit_asynchronous_matches())
    return;

  // Some async providers may produce multiple updates. Only log the final async
  // update.
  if (provider.done())
    LogProviderTimeMetrics(provider);
}

void AutocompleteControllerMetrics::OnStop() {
  // Only log metrics for async requests.
  if (controller_->input().omit_asynchronous_matches())
    return;

  // Done providers should already be logged by `OnProviderUpdate()`.
  for (const auto& provider : controller_->providers()) {
    if (!provider->done()) {
      DCHECK(!controller_->done() || !controller_->sync_pass_done());
      LogProviderTimeMetrics(*provider);
    }
  }

  // If the controller is done, `OnNotifyChanged()` should have already logged
  // finalization metrics. This case, i.e. `OnStop()` invoked even though the
  // controller is done, is possible because 1) `OnStart()` calls `OnStop()`
  // and 2) `AutocompleteController::stop_timer_` may fire after the controller
  // completes. Checking `!logged_finalization_metrics_` isn't sufficient, as
  // that would log synchronous inputs.
  if (!ControllerIdle())
    LogSuggestionFinalizationMetrics();
}

bool AutocompleteControllerMetrics::ControllerIdle() {
  return controller_->done() && controller_->expire_timer_done();
}

void AutocompleteControllerMetrics::LogSuggestionFinalizationMetrics() {
  // Should be logged once only, either when all async providers complete
  // or they're interrupted before completion.
  DCHECK(!logged_finalization_metrics_);
  logged_finalization_metrics_ = true;

  const bool done = ControllerIdle();
  LogAsyncAutocompletionTimeMetrics("Done", done, base::TimeTicks::Now());
  LogAsyncAutocompletionTimeMetrics("LastChange", done, last_change_time_);
  LogAsyncAutocompletionTimeMetrics("LastDefaultChange", done,
                                    last_default_change_time_);
}

void AutocompleteControllerMetrics::LogProviderTimeMetrics(
    const AutocompleteProvider& provider) const {
  LogAsyncAutocompletionTimeMetrics(
      std::string("Provider.") + provider.GetName(), provider.done(),
      base::TimeTicks::Now());
}

void AutocompleteControllerMetrics::LogAsyncAutocompletionTimeMetrics(
    const std::string& name,
    bool completed,
    const base::TimeTicks end_time) const {
  const auto name_prefix = "Omnibox.AsyncAutocompletionTime2." + name;
  const auto elapsed_time = end_time - start_time_;
  // These metrics are logged up to about 40 times per omnibox keystroke. But
  // use UMA functions as the names are dynamic.
  base::UmaHistogramTimes(name_prefix, elapsed_time);
  if (completed)
    base::UmaHistogramTimes(name_prefix + ".Completed", elapsed_time);
  else
    base::UmaHistogramTimes(name_prefix + ".Interrupted", elapsed_time);
}

void AutocompleteControllerMetrics::LogSuggestionChangeIndexMetrics(
    size_t change_index) const {
  std::string name = "Omnibox.MatchStability2.MatchChangeIndex";
  size_t max = AutocompleteResult::kMaxAutocompletePositionValue;
  // These metrics are logged up to about 50 times per omnibox keystroke, so use
  // UMA macros for efficiency.
  if (!controller_->sync_pass_done()) {
    UMA_HISTOGRAM_EXACT_LINEAR(name + ".CrossInput", change_index, max);
  } else {
    UMA_HISTOGRAM_EXACT_LINEAR(name + ".Async", change_index, max);
  }
  UMA_HISTOGRAM_EXACT_LINEAR(name, change_index, max);
}

void AutocompleteControllerMetrics::LogSuggestionChangeInAnyPositionMetrics(
    bool changed) const {
  std::string name = "Omnibox.MatchStability2.MatchChangeInAnyPosition";
  // These metrics are logged up to about 5 times per omnibox keystroke, so
  // use UMA macros for efficiency.
  if (!controller_->sync_pass_done()) {
    UMA_HISTOGRAM_BOOLEAN(name + ".CrossInput", changed);
  } else {
    UMA_HISTOGRAM_BOOLEAN(name + ".Async", changed);
  }
  UMA_HISTOGRAM_BOOLEAN(name, changed);
}
