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

#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::OnUpdateResult(
    std::vector<AutocompleteResult::MatchDedupComparator> last_result,
    std::vector<AutocompleteResult::MatchDedupComparator> new_result) {
  // 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]) {
      LogSuggestionChangedMetrics(i);
      any_match_changed_or_removed = true;
    }
  }
  LogAnySuggestionChangedMetrics(any_match_changed_or_removed);

  // Log suggestion finalization times.

  // Only log suggestion finalization metrics for async requests. This handles
  // logging as soon as the final update occurs, while `OnStop()` handles the
  // case where the final update never occurs because of interruptions.
  // TODO(manukh): Consider adding this filter to the above metrics as well.
  if (controller_.input().omit_asynchronous_matches())
    return;
  // E.g., suggestion deletion can call `OnUpdateResult()` 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 {
  // Some async providers may produce multiple updates. Only log the final async
  // update.
  if (provider.done())
    LogProviderTimeMetrics(provider);
}

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

  // If the controller is done, `OnUpdateResult()` 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.AsyncAutocompletionTime." + 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::LogSuggestionChangedMetrics(
    size_t change_index) const {
  // These metrics are logged up to about 50 times per omnibox keystroke, so use
  // UMA macros for efficiency.
  if (controller_.in_start()) {
    UMA_HISTOGRAM_EXACT_LINEAR(
        "Omnibox.CrossInputMatchStability.MatchChange", change_index,
        AutocompleteResult::kMaxAutocompletePositionValue);
  } else {
    UMA_HISTOGRAM_EXACT_LINEAR(
        "Omnibox.MatchStability.AsyncMatchChange2", change_index,
        AutocompleteResult::kMaxAutocompletePositionValue);
  }
}

void AutocompleteControllerMetrics::LogAnySuggestionChangedMetrics(
    bool changed) const {
  // These metrics are logged up to about 5 times per omnibox keystroke, so use
  // UMA macros for efficiency.
  if (controller_.in_start()) {
    UMA_HISTOGRAM_BOOLEAN(
        "Omnibox.CrossInputMatchStability.MatchChangedInAnyPosition", changed);
  } else {
    UMA_HISTOGRAM_BOOLEAN(
        "Omnibox.MatchStability.AsyncMatchChangedInAnyPosition", changed);
  }
}
