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

#include "components/omnibox/browser/omnibox_logging_utils.h"

#include "base/metrics/histogram_functions.h"
#include "base/strings/strcat.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_result.h"
#include "components/omnibox/browser/omnibox_metrics_provider.h"
#include "url/gurl.h"

namespace {

// This function provides a logging implementation that aligns with the original
// definition of the `DEPRECATED_UMA_HISTOGRAM_MEDIUM_TIMES()` macro, which is
// currently being used to log the `FocusToOpenTimeAnyPopupState3` Omnibox
// metric.
void LogHistogramMediumTimes(const std::string& histogram_name,
                             base::TimeDelta elapsed) {
  base::UmaHistogramCustomTimes(histogram_name, elapsed, base::Milliseconds(10),
                                base::Minutes(3), 50);
}

// Find the number of IPv4 parts if the user inputs a URL with an IP address
// host. Returns 0 if the user does not manually types the full IP address.
size_t CountNumberOfIPv4Parts(const std::u16string& text,
                              const GURL& url,
                              size_t completed_length) {
  if (!url.HostIsIPAddress() || !url.SchemeIsHTTPOrHTTPS() ||
      completed_length > 0) {
    return 0;
  }

  url::Parsed parsed = url::ParseStandardURL(text);
  if (!parsed.host.is_valid()) {
    return 0;
  }

  size_t parts = 1;
  bool potential_part = false;
  for (int i = parsed.host.begin; i < parsed.host.end(); i++) {
    if (text[i] == '.') {
      potential_part = true;
    }
    if (potential_part && text[i] >= '0' && text[i] <= '9') {
      parts++;
      potential_part = false;
    }
  }
  return parts;
}

}  // namespace

namespace omnibox {

void LogFocusToOpenTime(
    base::TimeDelta elapsed,
    bool is_zero_prefix,
    ::metrics::OmniboxEventProto::PageClassification page_classification,
    const AutocompleteMatch& match,
    size_t action_index) {
  LogHistogramMediumTimes("Omnibox.FocusToOpenTimeAnyPopupState3", elapsed);

  std::string summarized_result_type;
  switch (OmniboxMetricsProvider::GetClientSummarizedResultType(
      match.GetOmniboxEventResultType(action_index))) {
    case ClientSummarizedResultType::kSearch:
      summarized_result_type = "SEARCH";
      break;
    case ClientSummarizedResultType::kUrl:
      summarized_result_type = "URL";
      break;
    default:
      summarized_result_type = "OTHER";
      break;
  }

  LogHistogramMediumTimes(
      base::StrCat(
          {"Omnibox.FocusToOpenTimeAnyPopupState3.BySummarizedResultType.",
           summarized_result_type}),
      elapsed);

  const std::string page_context =
      ::metrics::OmniboxEventProto::PageClassification_Name(
          page_classification);
  LogHistogramMediumTimes(
      base::StrCat({"Omnibox.FocusToOpenTimeAnyPopupState3.ByPageContext.",
                    page_context}),
      elapsed);

  LogHistogramMediumTimes(
      base::StrCat(
          {"Omnibox.FocusToOpenTimeAnyPopupState3.BySummarizedResultType.",
           summarized_result_type, ".ByPageContext.", page_context}),
      elapsed);

  if (is_zero_prefix) {
    LogHistogramMediumTimes("Omnibox.FocusToOpenTimeAnyPopupState3.ZeroSuggest",
                            elapsed);
    LogHistogramMediumTimes(
        base::StrCat({"Omnibox.FocusToOpenTimeAnyPopupState3.ZeroSuggest."
                      "BySummarizedResultType.",
                      summarized_result_type}),
        elapsed);
    LogHistogramMediumTimes(
        base::StrCat(
            {"Omnibox.FocusToOpenTimeAnyPopupState3.ZeroSuggest.ByPageContext.",
             page_context}),
        elapsed);
    LogHistogramMediumTimes(
        base::StrCat({"Omnibox.FocusToOpenTimeAnyPopupState3.ZeroSuggest."
                      "BySummarizedResultType.",
                      summarized_result_type, ".ByPageContext.", page_context}),
        elapsed);
  } else {
    LogHistogramMediumTimes(
        "Omnibox.FocusToOpenTimeAnyPopupState3.TypedSuggest", elapsed);
    LogHistogramMediumTimes(
        base::StrCat({"Omnibox.FocusToOpenTimeAnyPopupState3.TypedSuggest."
                      "BySummarizedResultType.",
                      summarized_result_type}),
        elapsed);
    LogHistogramMediumTimes(
        base::StrCat({"Omnibox.FocusToOpenTimeAnyPopupState3.TypedSuggest."
                      "ByPageContext.",
                      page_context}),
        elapsed);
    LogHistogramMediumTimes(
        base::StrCat({"Omnibox.FocusToOpenTimeAnyPopupState3.TypedSuggest."
                      "BySummarizedResultType.",
                      summarized_result_type, ".ByPageContext.", page_context}),
        elapsed);
  }
}

void RecordActionShownForAllActions(const AutocompleteResult& result,
                                    OmniboxPopupSelection executed_selection) {
  // Record the presence of all actions in the result set.
  for (size_t line_index = 0; line_index < result.size(); ++line_index) {
    const AutocompleteMatch& match = result.match_at(line_index);
    // Record the presence of the takeover action on this line, if any.
    if (match.takeover_action) {
      match.takeover_action->RecordActionShown(
          line_index,
          /*executed=*/line_index == executed_selection.line &&
              executed_selection.state == OmniboxPopupSelection::NORMAL);
    }
    for (size_t action_index = 0; action_index < match.actions.size();
         ++action_index) {
      match.actions[action_index]->RecordActionShown(
          line_index, /*executed=*/line_index == executed_selection.line &&
                          action_index == executed_selection.action_index &&
                          executed_selection.state ==
                              OmniboxPopupSelection::FOCUSED_BUTTON_ACTION);
    }
  }
}

void LogIPv4PartsCount(const std::u16string& user_text,
                       const GURL& destination_url,
                       size_t completed_length) {
  size_t ipv4_parts_count =
      CountNumberOfIPv4Parts(user_text, destination_url, completed_length);
  // The histogram is collected to decide if shortened IPv4 addresses
  // like 127.1 should be deprecated.
  // Only valid IP addresses manually inputted by the user will be counted.
  if (ipv4_parts_count > 0) {
    base::UmaHistogramCounts100("Omnibox.IPv4AddressPartsCount",
                                ipv4_parts_count);
  }
}

}  // namespace omnibox
