// 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 "components/omnibox/browser/autocomplete_grouper_sections.h"

#include <algorithm>
#include <memory>
#include <optional>

#include "base/containers/contains.h"
#include "base/dcheck_is_on.h"
#include "base/notreached.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "components/omnibox/browser/autocomplete_grouper_groups.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_match_type.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/omnibox/common/omnibox_feature_configs.h"
#include "third_party/omnibox_proto/groups.pb.h"

namespace {
constexpr size_t kMobileMostVisitedTilesLimit = 10;
constexpr bool is_android = !!BUILDFLAG(IS_ANDROID);
constexpr size_t kMaxSuggestionsPerUnscopedExtension = 4;
constexpr size_t kMaxExtensions = 2;
}

Section::Section(size_t limit,
                 Groups groups,
                 omnibox::GroupConfigMap& group_configs,
                 omnibox::GroupConfig_SideType side_type)
    : limit_(limit),
      groups_(std::move(groups)),
      group_configs_(group_configs),
      side_type_(side_type) {
#if DCHECK_IS_ON()
  // Make sure all the `GroupId`s in the `Group`s have the same `RenderType`.
  for (const auto& group : groups_) {
    std::optional<omnibox::GroupConfig_RenderType> last_render_type;
    for (const auto& [group_id, _] : group.group_id_limits_and_counts()) {
      const auto& render_type = group_configs[group_id].render_type();
      DCHECK_EQ(last_render_type.value_or(render_type), render_type)
          << "GroupId " << group_id
          << " has different RenderType than the previous one.";
      last_render_type = render_type;
    }
  }
#endif  // DCHECK_IS_ON()
}

Section::~Section() = default;

// static
ACMatches Section::GroupMatches(PSections sections, ACMatches& matches) {
  for (auto& section : sections) {
    section->InitFromMatches(matches);
  }

  for (const auto& match : matches) {
    DCHECK(match.suggestion_group_id.has_value());
    for (const auto& section : sections) {
      if (section->Add(match))
        break;
    }
  }

  ACMatches grouped_matches = {};
  for (auto& section : sections) {
    for (auto& group : section->groups_) {
      group.GroupMatches();
      for (AutocompleteMatch* match : group.matches()) {
        grouped_matches.push_back(std::move(*match));
      }
    }
  }

  return grouped_matches;
}

Groups::iterator Section::FindGroup(const AutocompleteMatch& match) {
  // Check if match is allowed in this `Section` by its GroupId `SideType`.
  const auto& group_id = match.suggestion_group_id.value();
  if (group_configs_[group_id].side_type() != side_type_) {
    return groups_.end();
  }
  return std::ranges::find_if(
      groups_, [&](const auto& group) { return group.CanAdd(match); });
}

bool Section::Add(const AutocompleteMatch& match) {
  if (count_ >= limit_) {
    return false;
  }
  auto group_itr = FindGroup(match);
  if (group_itr == groups_.end()) {
    return false;
  }
  group_itr->Add(match);
  count_++;
  return true;
}

ZpsSection::ZpsSection(size_t limit,
                       Groups groups,
                       omnibox::GroupConfigMap& group_configs,
                       omnibox::GroupConfig_SideType side_type)
    : Section(limit, std::move(groups), group_configs, side_type) {}

void ZpsSection::InitFromMatches(ACMatches& matches) {
  // Ensure matches are sorted in the order of their potential containing
  // groups. E.g., if `groups_ = {group 1, group 2}, matches that can be added
  // to group 1 must appear before those that can only be added to group 2.
  size_t last_group_index = 0;
  for (const auto& match : matches) {
    auto group_itr = FindGroup(match);
    if (group_itr == groups_.end()) {
      continue;
    }
    size_t current_group_index = std::distance(groups_.begin(), group_itr);
    if (current_group_index < last_group_index) {
      const std::string match_type =
          AutocompleteMatchType::ToString(match.type);
      const std::string match_group_id =
          omnibox::GroupId_Name(match.suggestion_group_id.value());
      const std::string match_relevance = base::NumberToString(match.relevance);
      const std::string group_description = base::JoinString(
          [&]() {
            std::vector<std::string> transformed;
            std::ranges::transform(
                group_itr->group_id_limits_and_counts(),
                std::back_inserter(transformed), [](const auto& pair) {
                  return omnibox::GroupId_Name(pair.first) + " (" +
                         base::NumberToString(
                             static_cast<int>(pair.second.limit)) +
                         ")";
                });
            return transformed;
          }(),
          ", ");
#if DCHECK_IS_ON()
      NOTREACHED() << "Match with type " << match_type << " and group id "
                   << match_group_id << " and relevance " << match_relevance
                   << " is not sorted correctly while being added to Group "
                   << group_description;
#endif  // DCHECK_IS_ON()
    }
    last_group_index = current_group_index;
  }
}

ZpsSectionWithLocalHistory::ZpsSectionWithLocalHistory(
    size_t limit,
    Groups groups,
    omnibox::GroupConfigMap& group_configs)
    : ZpsSection(limit, std::move(groups), group_configs) {}

void ZpsSectionWithLocalHistory::InitFromMatches(ACMatches& matches) {
  // Sort matches in the order of their potential containing groups. E.g., if
  // `groups_ = {group 1, group 2}, this sorts all matches that can be added to
  // group 1 before those that can only be added to group 2.
  std::ranges::stable_sort(matches, std::less<int>{}, [&](const auto& match) {
    // Don't have to handle `FindGroup()` returning `groups_.end()` since
    // those matches won't be added to the section anyways.
    return std::distance(groups_.begin(), FindGroup(match));
  });
  ZpsSection::InitFromMatches(matches);
}

// Number of matches that fit in the visible section of the screen.
// This number includes the Default match, shown in the top section.
// The default match needs to be kept separate, because it should not be
// moved when we group suggestions by Search vs URL.
// TODO(b/328617350): plumb the value via AutocompleteInput.
/* static */ size_t AndroidNonZPSSection::num_visible_matches_{6};

AndroidNonZPSSection::AndroidNonZPSSection(
    bool show_only_search_suggestions,
    omnibox::GroupConfigMap& group_configs)
    : Section(15,
              {
                  // Default match Group, not part of the Grouping.
                  Group(1,
                        {
                            {omnibox::GROUP_SEARCH, 1},
                            {omnibox::GROUP_OTHER_NAVS, 1},
                        },
                        /*is_zps=*/false),
                  // Top Group / above the keyboard.
                  Group(num_visible_matches_ - 1,
                        {
                            {omnibox::GROUP_SEARCH, 14},
                            {omnibox::GROUP_OTHER_NAVS,
                             show_only_search_suggestions ? 0 : 14},
                        },
                        /*is_zps=*/false),
                  // Dedicated Group for rich answer card just above the fold.
                  Group(1,
                        {
                            {omnibox::GROUP_MOBILE_RICH_ANSWER, 0},
                        },
                        /*is_zps=*/false),
                  // Bottom Group, up to the Section limit.
                  Group(14,
                        {
                            {omnibox::GROUP_SEARCH, 14},
                            {omnibox::GROUP_OTHER_NAVS,
                             show_only_search_suggestions ? 0 : 14},
                        },
                        /*is_zps=*/false),
              },
              group_configs) {}

void AndroidNonZPSSection::InitFromMatches(ACMatches& matches) {
  auto rich_answer_match = std::ranges::find_if(
      matches,
      [&](const auto& match) { return match.answer_template.has_value(); });
  bool has_rich_answer = rich_answer_match != matches.end();
  if (!has_rich_answer) {
    return;
  }

  auto& above_keyboard_group = groups_[1];
  above_keyboard_group.set_limit(above_keyboard_group.limit() - 1);
}

AndroidHubZPSSection::AndroidHubZPSSection(
    omnibox::GroupConfigMap& group_configs)
    : Section(5,
              {
                  Group(5,
                        {
                            {omnibox::GROUP_MOBILE_OPEN_TABS, 5},
                        }),
              },
              group_configs) {}

AndroidHubNonZPSSection::AndroidHubNonZPSSection(
    omnibox::GroupConfigMap& group_configs)
    : Section(
          35,
          {
              // Reserve most of the spots for open tabs.
              Group(20,
                    {
                        {omnibox::GROUP_MOBILE_OPEN_TABS, 20},
                    },
                    /*is_zps=*/false),
              Group(5,
                    {
                        {omnibox::GROUP_MOBILE_BOOKMARKS, 5},
                    },
                    /*is_zps=*/false),
              // LINT.IfChange(HubHistorySectionSlots)
              Group(5,
                    {
                        {omnibox::GROUP_MOBILE_HISTORY, 5},
                    },
                    /*is_zps=*/false),
              // LINT.ThenChange(//components/omnibox/browser/history_quick_provider.cc:HubHistoryMaxMatches)
              // Fallback to search suggestions at the bottom of the results.
              Group(5,
                    {
                        {omnibox::GROUP_SEARCH, 5},
                    },
                    /*is_zps=*/false),
          },
          group_configs) {}

void AndroidNTPZpsSection::InitFromMatches(ACMatches& matches) {
  bool mia_suggestions_detected =
      std::ranges::any_of(matches, [&](const auto& match) {
        return match.suggestion_group_id.value_or(omnibox::GROUP_INVALID) ==
               omnibox::GROUP_MIA_RECOMMENDATIONS;
      });

  if (omnibox_feature_configs::MiaZPS::Get()
          .suppress_psuggest_backfill_with_mia &&
      mia_suggestions_detected) {
    // Hacky and delicate, but follows a pattern found in other sections of this
    // file.
    const_cast<Group::LimitAndCount&>(
        groups_[1].group_id_limits_and_counts().at(
            omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST))
        .limit = 0;
  }

  ZpsSectionWithLocalHistory::InitFromMatches(matches);
}

AndroidNTPZpsSection::AndroidNTPZpsSection(
    omnibox::GroupConfigMap& group_configs,
    bool mia_enabled)
    : ZpsSectionWithLocalHistory(
          30,
          {
              Group(1,
                    {
                        {omnibox::GROUP_MOBILE_CLIPBOARD, 1},
                    }),
              Group(OmniboxFieldTrial::kOmniboxNumNtpZpsRecentSearches.Get(),
                    {
                        {
                            omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST_WITH_MIA,
                            mia_enabled
                                ? OmniboxFieldTrial::
                                      kOmniboxNumNtpZpsRecentSearches.Get()
                                : 0,
                        },
                        {
                            omnibox::GROUP_MIA_RECOMMENDATIONS,
                            mia_enabled
                                ? OmniboxFieldTrial::
                                      kOmniboxNumNtpZpsRecentSearches.Get()
                                : 0,
                        },
                        {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST,
                         OmniboxFieldTrial::kOmniboxNumNtpZpsRecentSearches
                             .Get()},
                    }),
              Group(OmniboxFieldTrial::kOmniboxNumNtpZpsTrendingSearches.Get(),
                    {
                        {omnibox::GROUP_TRENDS,
                         OmniboxFieldTrial::kOmniboxNumNtpZpsTrendingSearches
                             .Get()},
                    }),
          },
          group_configs) {}

AndroidSRPZpsSection::AndroidSRPZpsSection(
    omnibox::GroupConfigMap& group_configs)
    : ZpsSection(
          15,
          {
              Group(1,
                    {
                        {omnibox::GROUP_MOBILE_SEARCH_READY_OMNIBOX, 1},
                    }),
              Group(1,
                    {
                        {omnibox::GROUP_MOBILE_CLIPBOARD, 1},
                    }),
              Group(OmniboxFieldTrial::kOmniboxNumSrpZpsRelatedSearches.Get(),
                    {
                        {omnibox::GROUP_PREVIOUS_SEARCH_RELATED,
                         OmniboxFieldTrial::kOmniboxNumSrpZpsRelatedSearches
                             .Get()},
                    }),
              Group(OmniboxFieldTrial::kOmniboxNumSrpZpsRecentSearches.Get(),
                    {
                        {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST,
                         OmniboxFieldTrial::kOmniboxNumSrpZpsRecentSearches
                             .Get()},
                    }),
          },
          group_configs) {}

AndroidWebZpsSection::AndroidWebZpsSection(
    omnibox::GroupConfigMap& group_configs)
    : ZpsSectionWithMVTiles(
          15,  // Excludes MV tile count (calculated at runtime).
          {
              Group(1,
                    {
                        {omnibox::GROUP_MOBILE_SEARCH_READY_OMNIBOX, 1},
                    }),
              Group(1,
                    {
                        {omnibox::GROUP_MOBILE_CLIPBOARD, 1},
                    }),
              Group(OmniboxFieldTrial::kOmniboxNumWebZpsMostVisitedUrls.Get(),
                    {
                        {omnibox::GROUP_MOBILE_MOST_VISITED,
                         OmniboxFieldTrial::kOmniboxNumWebZpsMostVisitedUrls
                             .Get()},
                    }),
              Group(OmniboxFieldTrial::kOmniboxNumWebZpsRelatedSearches.Get(),
                    {
                        {omnibox::GROUP_VISITED_DOC_RELATED,
                         OmniboxFieldTrial::kOmniboxNumWebZpsRelatedSearches
                             .Get()},
                    }),
              Group(OmniboxFieldTrial::kOmniboxNumWebZpsRecentSearches.Get(),
                    {
                        {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST,
                         OmniboxFieldTrial::kOmniboxNumWebZpsRecentSearches
                             .Get()},
                    }),
          },
          group_configs) {}

DesktopNTPZpsSection::DesktopNTPZpsSection(
    omnibox::GroupConfigMap& group_configs,
    size_t limit,
    bool mia_enabled)
    : ZpsSectionWithLocalHistory(
          limit,
          {
              Group(
                  8,
                  {
                      {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST_WITH_MIA,
                       mia_enabled ? 8 : 0},
                      {omnibox::GROUP_MIA_RECOMMENDATIONS, mia_enabled ? 8 : 0},
                      {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST, 8},
                  }),
              Group(8,
                    {
                        {omnibox::GROUP_TRENDS, 8},
                    }),
              Group(5,
                    {
                        {omnibox::GROUP_CONTEXTUAL_SEARCH, 5},
                    }),
          },
          group_configs) {}

DesktopNTPZpsIPHSection::DesktopNTPZpsIPHSection(
    omnibox::GroupConfigMap& group_configs)
    : ZpsSection(1,
                 {
                     Group(1,
                           {
                               {omnibox::GROUP_ZERO_SUGGEST_IN_PRODUCT_HELP, 1},
                           }),
                 },
                 group_configs) {}

DesktopZpsUnscopedExtensionSection::DesktopZpsUnscopedExtensionSection(
    omnibox::GroupConfigMap& group_configs)
    : ZpsSection(kMaxSuggestionsPerUnscopedExtension * kMaxExtensions,
                 {
                     Group(kMaxSuggestionsPerUnscopedExtension,
                           {
                               {omnibox::GROUP_UNSCOPED_EXTENSION_1,
                                kMaxSuggestionsPerUnscopedExtension},
                           }),
                     Group(kMaxSuggestionsPerUnscopedExtension,
                           {
                               {omnibox::GROUP_UNSCOPED_EXTENSION_2,
                                kMaxSuggestionsPerUnscopedExtension},
                           }),
                 },
                 group_configs) {}

DesktopSecondaryNTPZpsSection::DesktopSecondaryNTPZpsSection(
    omnibox::GroupConfigMap& group_configs)
    : ZpsSection(
          (omnibox_feature_configs::RealboxContextualAndTrendingSuggestions::
               Get()
                   .enabled)
              ? omnibox_feature_configs::
                    RealboxContextualAndTrendingSuggestions::Get()
                        .total_limit
              : 3,
          {
              Group(
                  3,
                  {
                      {omnibox::GROUP_PREVIOUS_SEARCH_RELATED_ENTITY_CHIPS, 3},
                  }),
              Group(
                  (omnibox_feature_configs::
                       RealboxContextualAndTrendingSuggestions::Get()
                           .enabled)
                      ? omnibox_feature_configs::
                            RealboxContextualAndTrendingSuggestions::Get()
                                .contextual_suggestions_limit
                      : 0,
                  {
                      {omnibox::GROUP_PREVIOUS_SEARCH_RELATED,
                       (omnibox_feature_configs::
                            RealboxContextualAndTrendingSuggestions::Get()
                                .enabled)
                           ? omnibox_feature_configs::
                                 RealboxContextualAndTrendingSuggestions::Get()
                                     .contextual_suggestions_limit
                           : 0},
                  }),
              Group(
                  (omnibox_feature_configs::
                       RealboxContextualAndTrendingSuggestions::Get()
                           .enabled)
                      ? omnibox_feature_configs::
                            RealboxContextualAndTrendingSuggestions::Get()
                                .trending_suggestions_limit
                      : 0,
                  {
                      {omnibox::GROUP_TRENDS,
                       (omnibox_feature_configs::
                            RealboxContextualAndTrendingSuggestions::Get()
                                .enabled)
                           ? omnibox_feature_configs::
                                 RealboxContextualAndTrendingSuggestions::Get()
                                     .trending_suggestions_limit
                           : 0},
                  }),
          },
          group_configs,
          omnibox::GroupConfig_SideType_SECONDARY) {}

DesktopSRPZpsSection::DesktopSRPZpsSection(
    omnibox::GroupConfigMap& group_configs,
    size_t max_suggestions,
    size_t search_limit,
    size_t url_limit,
    size_t contextual_action_limit)
    : ZpsSection(
          max_suggestions,
          {
              Group(
                  search_limit,
                  {
                      {omnibox::GROUP_PREVIOUS_SEARCH_RELATED, search_limit},
                      {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST, search_limit},
                  }),
              Group(url_limit,
                    {
                        {omnibox::GROUP_MOST_VISITED, url_limit},
                    }),
#if 1
              Group(contextual_action_limit,
                    {
                        {omnibox::GROUP_CONTEXTUAL_SEARCH_ACTION,
                         contextual_action_limit},
                    }),
#endif
          },
          group_configs) {
}

DesktopWebURLZpsSection::DesktopWebURLZpsSection(
    omnibox::GroupConfigMap& group_configs,
    size_t limit)
    : ZpsSection(limit,
                 {
                     Group(limit,
                           {
                               {omnibox::GROUP_MOST_VISITED, limit},
                           }),
                 },
                 group_configs) {}

DesktopWebSearchZpsSection::DesktopWebSearchZpsSection(
    omnibox::GroupConfigMap& group_configs,
    size_t limit,
    size_t contextual_action_limit,
    size_t contextual_search_limit)
    : Section(limit,
              {
                  Group(limit,
                        {
                            {omnibox::GROUP_VISITED_DOC_RELATED, limit},
                            {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST, limit},
                        }),
                  Group(contextual_action_limit,
                        {
                            {omnibox::GROUP_CONTEXTUAL_SEARCH_ACTION,
                             contextual_action_limit},
                        }),
                  Group(contextual_search_limit,
                        {
                            {omnibox::GROUP_CONTEXTUAL_SEARCH,
                             contextual_search_limit},
                        }),
              },
              group_configs) {}

DesktopWebSearchZpsContextualOnlySection::
    DesktopWebSearchZpsContextualOnlySection(
        omnibox::GroupConfigMap& group_configs,
        size_t contextual_action_limit,
        size_t contextual_search_limit)
    : Section(contextual_action_limit + contextual_search_limit,
              {
                  Group(contextual_action_limit,
                        {
                            {omnibox::GROUP_CONTEXTUAL_SEARCH_ACTION,
                             contextual_action_limit},
                        }),
                  Group(contextual_search_limit,
                        {
                            {omnibox::GROUP_CONTEXTUAL_SEARCH,
                             contextual_search_limit},
                        }),
              },
              group_configs) {}

DesktopLensContextualZpsSection::DesktopLensContextualZpsSection(
    omnibox::GroupConfigMap& group_configs)
    : ZpsSection(5,
                 {
                     Group(5,
                           {
                               {omnibox::GROUP_CONTEXTUAL_SEARCH, 5},
                           }),
                 },
                 group_configs) {}

DesktopLensMultimodalZpsSection::DesktopLensMultimodalZpsSection(
    omnibox::GroupConfigMap& group_configs)
    : ZpsSection(8,
                 {
                     Group(8,
                           {
                               {omnibox::GROUP_MULTIMODAL, 8},
                           }),
                 },
                 group_configs) {}

AndroidComposeboxZpsSection::AndroidComposeboxZpsSection(
    omnibox::GroupConfigMap& group_configs,
    size_t max_suggestions,
    size_t max_aim_suggestions,
    size_t max_contextual_suggestions)
    : ZpsSection(max_suggestions,
                 {
                     Group(max_suggestions,
                           {
                               {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST,
                                max_aim_suggestions},
                               {omnibox::GROUP_MIA_RECOMMENDATIONS,
                                max_aim_suggestions},
                           }),
                     Group(max_suggestions,
                           {
                               {omnibox::GROUP_AI_MODE_ZERO_SUGGEST_CANNED,
                                max_aim_suggestions},
                           }),
                     Group(max_suggestions,
                           {
                               {omnibox::GROUP_CONTEXTUAL_SEARCH,
                                max_contextual_suggestions},
                           }),
                 },
                 group_configs) {}

DesktopComposeboxZpsSection::DesktopComposeboxZpsSection(
    omnibox::GroupConfigMap& group_configs,
    size_t max_suggestions,
    size_t max_aim_suggestions,
    size_t max_contextual_suggestions)
    : ZpsSection(max_suggestions,
                 {
                     Group(max_suggestions,
                           {
                               {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST,
                                max_aim_suggestions},
                               {omnibox::GROUP_MIA_RECOMMENDATIONS,
                                max_aim_suggestions},
                           }),
                     Group(max_suggestions,
                           {
                               {omnibox::GROUP_AI_MODE_ZERO_SUGGEST_CANNED,
                                max_aim_suggestions},
                           }),
                     Group(max_suggestions,
                           {
                               {omnibox::GROUP_CONTEXTUAL_SEARCH,
                                max_contextual_suggestions},
                           }),
                 },
                 group_configs) {}

ToolbeltSection::ToolbeltSection(omnibox::GroupConfigMap& group_configs)
    : ZpsSection(1,
                 {
                     Group(1,
                           {
                               {omnibox::GROUP_SEARCH_TOOLBELT, 1},
                           }),
                 },
                 group_configs) {}

DesktopNonZpsSection::DesktopNonZpsSection(
    omnibox::GroupConfigMap& group_configs)
    : Section(10,
              {
                  Group(1,
                        {
                            {omnibox::GROUP_STARTER_PACK, 1},
                            {omnibox::GROUP_SEARCH, 1},
                            {omnibox::GROUP_OTHER_NAVS, 1},
                        },
                        /*is_zps=*/false,
                        /*is_default=*/true),
                  Group(9,
                        {
                            {omnibox::GROUP_STARTER_PACK, 9},
                        },
                        /*is_zps=*/false),
                  Group(9,
                        {
                            {omnibox::GROUP_SEARCH, 9},
                            {omnibox::GROUP_HISTORY_CLUSTER, 1},
                        },
                        /*is_zps=*/false),
                  Group(7,
                        {
                            {omnibox::GROUP_OTHER_NAVS, 7},
                        },
                        /*is_zps=*/false),
              },
              group_configs) {}

void DesktopNonZpsSection::InitFromMatches(ACMatches& matches) {
  auto& default_group = groups_[0];
  auto& search_group = groups_[2];
  auto& nav_group = groups_[3];

  // Determine if `matches` contains any searches.
  bool has_search = std::ranges::any_of(
      matches, [&](const auto& match) { return search_group.CanAdd(match); });

  // Determine if the default match will be a search.
  auto default_match = std::ranges::find_if(
      matches, [&](const auto& match) { return default_group.CanAdd(match); });
  bool default_is_search =
      default_match != matches.end() && search_group.CanAdd(*default_match);

  // Find the 1st nav's index.
  size_t first_nav_index = std::distance(
      matches.begin(), std::ranges::find_if(matches, [&](const auto& match) {
        return nav_group.CanAdd(match);
      }));

  // Show at most 8 suggestions if doing so includes navs; otherwise show 9 or
  // 10, if doing so doesn't include navs.
  limit_ = std::clamp<size_t>(first_nav_index, 8, 10);

  // Show at least 1 search, either in the default group or the search group.
  if (has_search && !default_is_search) {
    DCHECK_GE(limit_, 2U);
    nav_group.set_limit(limit_ - 2);
  }
}

ZpsSectionWithMVTiles::ZpsSectionWithMVTiles(
    size_t limit,
    Groups groups,
    omnibox::GroupConfigMap& group_configs)
    : ZpsSection(limit, std::move(groups), group_configs) {}

void ZpsSectionWithMVTiles::InitFromMatches(ACMatches& matches) {
  size_t tile_count = std::count_if(
      matches.begin(), matches.end(), [](const AutocompleteMatch& m) {
        return m.suggestion_group_id.value_or(omnibox::GROUP_INVALID) ==
               omnibox::GROUP_MOBILE_MOST_VISITED;
      });
  const size_t max_most_visited_tiles =
      is_android ? OmniboxFieldTrial::kOmniboxNumWebZpsMostVisitedUrls.Get()
                 : kMobileMostVisitedTilesLimit;
  // In the event we find more MV tiles than we can accommodate, trim the limit.
  limit_ += std::min(tile_count, max_most_visited_tiles);
  // Note that the horizontal render group takes a single slot in vertical list:
  // we therefore count it as an individual item, meaning this list:
  //     [ URL_WHAT_YOU_TYPED    ]
  //     [ [MV] [MV] [MV] [MV]   ]
  //     [ SEARCH_SUGGEST        ]
  // has 3 elements built from 6 AutocompleteMatch objects.
  limit_ -= (tile_count ? 1 : 0);
  ZpsSection::InitFromMatches(matches);
}

void IOSNTPZpsSection::InitFromMatches(ACMatches& matches) {
  bool mia_suggestions_detected =
      std::ranges::any_of(matches, [&](const auto& match) {
        return match.suggestion_group_id.value_or(omnibox::GROUP_INVALID) ==
               omnibox::GROUP_MIA_RECOMMENDATIONS;
      });

  if (omnibox_feature_configs::MiaZPS::Get()
          .suppress_psuggest_backfill_with_mia &&
      mia_suggestions_detected) {
    // Hacky and delicate, but follows a pattern found in other sections of this
    // file.
    const_cast<Group::LimitAndCount&>(
        groups_[1].group_id_limits_and_counts().at(
            omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST))
        .limit = 0;
  }

  ZpsSectionWithLocalHistory::InitFromMatches(matches);
}

IOSNTPZpsSection::IOSNTPZpsSection(omnibox::GroupConfigMap& group_configs,
                                   bool mia_enabled)
    : ZpsSectionWithLocalHistory(
          26,
          {
              Group(1,
                    {
                        {omnibox::GROUP_MOBILE_CLIPBOARD, 1},
                    }),
              Group(20,
                    {
                        {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST_WITH_MIA,
                         mia_enabled ? 20 : 0},
                        {omnibox::GROUP_MIA_RECOMMENDATIONS,
                         mia_enabled ? 20 : 0},
                        {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST, 20},
                    }),
              Group(5,
                    {
                        {omnibox::GROUP_TRENDS, 5},
                    }),
          },
          group_configs) {}

IOSSRPZpsSection::IOSSRPZpsSection(omnibox::GroupConfigMap& group_configs)
    : ZpsSectionWithMVTiles(
          20,
          {
              Group(1,
                    {
                        {omnibox::GROUP_MOBILE_SEARCH_READY_OMNIBOX, 1},
                    }),
              Group(1,
                    {
                        {omnibox::GROUP_MOBILE_CLIPBOARD, 1},
                    }),
              Group(kMobileMostVisitedTilesLimit,
                    {
                        {omnibox::GROUP_MOBILE_MOST_VISITED,
                         kMobileMostVisitedTilesLimit},
                    }),
              Group(8,
                    {
                        {omnibox::GROUP_PREVIOUS_SEARCH_RELATED, 8},
                    }),
              Group(20,
                    {
                        {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST, 20},
                    }),
          },
          group_configs) {}

IOSWebZpsSection::IOSWebZpsSection(omnibox::GroupConfigMap& group_configs)
    : ZpsSectionWithMVTiles(
          20,
          {
              Group(1,
                    {
                        {omnibox::GROUP_MOBILE_SEARCH_READY_OMNIBOX, 1},
                    }),
              Group(1,
                    {
                        {omnibox::GROUP_MOBILE_CLIPBOARD, 1},
                    }),
              Group(kMobileMostVisitedTilesLimit,
                    {
                        {omnibox::GROUP_MOBILE_MOST_VISITED,
                         kMobileMostVisitedTilesLimit},
                    }),
              Group(8,
                    {
                        {omnibox::GROUP_VISITED_DOC_RELATED, 8},
                    }),
              Group(20,
                    {
                        {omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST, 20},
                    }),
          },
          group_configs) {}

IOSLensMultimodalZpsSection::IOSLensMultimodalZpsSection(
    omnibox::GroupConfigMap& group_configs)
    : ZpsSection(10,
                 {
                     Group(10,
                           {
                               {omnibox::GROUP_MULTIMODAL, 10},
                           }),
                 },
                 group_configs) {}
