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

#include "chrome/browser/ui/omnibox/omnibox_controller.h"

#include <memory>
#include <optional>
#include <string>

#include "base/functional/bind.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
#include "chrome/browser/ui/omnibox/omnibox_next_features.h"
#include "chrome/browser/ui/omnibox/omnibox_popup_view.h"
#include "components/omnibox/browser/autocomplete_classifier.h"
#include "components/omnibox/browser/autocomplete_controller_config.h"
#include "components/omnibox/browser/autocomplete_controller_emitter.h"
#include "components/omnibox/browser/autocomplete_enums.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_match_type.h"
#include "components/omnibox/browser/omnibox_client.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/omnibox/browser/omnibox_popup_selection.h"
#include "components/omnibox/browser/page_classification_functions.h"
#include "components/search_engines/template_url_starter_pack_data.h"
#include "ui/gfx/geometry/rect.h"

OmniboxController::OmniboxController(
    OmniboxView* view,
    std::unique_ptr<OmniboxClient> client,
    std::optional<base::TimeDelta> autocomplete_stop_timer_duration)
    : client_(std::move(client)),
      edit_model_(std::make_unique<OmniboxEditModel>(
          /*omnibox_controller=*/this,
          view)) {
  AutocompleteControllerConfig autocomplete_controller_config{
      .provider_types = AutocompleteClassifier::DefaultOmniboxProviders()};
  if (base::FeatureList::IsEnabled(omnibox::kWebUIOmniboxPopup)) {
    autocomplete_controller_config.show_iph_matches = false;
  }
  if (autocomplete_stop_timer_duration.has_value()) {
    autocomplete_controller_config.stop_timer_duration =
        autocomplete_stop_timer_duration.value();
  }
  autocomplete_controller_ = std::make_unique<AutocompleteController>(
      client_->CreateAutocompleteProviderClient(),
      autocomplete_controller_config);

  // Directly observe omnibox's `AutocompleteController` instance - i.e., when
  // `view` is provided in the constructor. In the case of realbox - i.e., when
  // `view` is not provided in the constructor - `RealboxHandler` directly
  // observes the `AutocompleteController` instance itself.
  if (view) {
    autocomplete_controller_->AddObserver(this);
  }

  // Register the `AutocompleteController` with `AutocompleteControllerEmitter`.
  if (auto* emitter = client_->GetAutocompleteControllerEmitter()) {
    autocomplete_controller_->AddObserver(emitter);
  }
}

constexpr bool is_ios = !!BUILDFLAG(IS_IOS);

OmniboxController::~OmniboxController() = default;

void OmniboxController::StartAutocomplete(
    const AutocompleteInput& input) const {
  TRACE_EVENT0("omnibox", "OmniboxController::StartAutocomplete");
  ClearPopupKeywordMode();

  // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as
  // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it.
  autocomplete_controller_->Start(input);
}

void OmniboxController::StopAutocomplete(bool clear_result) const {
  TRACE_EVENT0("omnibox", "OmniboxController::StopAutocomplete");
  autocomplete_controller_->Stop(clear_result
                                     ? AutocompleteStopReason::kClobbered
                                     : AutocompleteStopReason::kInteraction);
}

void OmniboxController::StartZeroSuggestPrefetch() {
  TRACE_EVENT0("omnibox", "OmniboxController::StartZeroSuggestPrefetch");
  client_->MaybePrewarmForDefaultSearchEngine();

  auto page_classification =
      client_->GetPageClassification(/*is_prefetch=*/true);

  GURL current_url = client_->GetURL();
  std::u16string text = base::UTF8ToUTF16(current_url.spec());

  if (omnibox::IsNTPPage(page_classification) || !is_ios) {
    text.clear();
  }

  AutocompleteInput input(text, page_classification,
                          client_->GetSchemeClassifier());
  input.set_current_url(current_url);
  input.set_current_title(client_->GetTitle());
  input.set_focus_type(metrics::OmniboxFocusType::INTERACTION_FOCUS);
  autocomplete_controller_->StartPrefetch(input);
}

void OmniboxController::OnResultChanged(AutocompleteController* controller,
                                        bool default_match_changed) {
  TRACE_EVENT0("omnibox", "OmniboxController::OnResultChanged");
  DCHECK(controller == autocomplete_controller_.get());

  const bool popup_was_open = edit_model_->PopupIsOpen();
  if (!edit_model_->PopupInAiMode()) {
    if (default_match_changed) {
      // The default match has changed, we need to let the OmniboxEditModel know
      // about new inline autocomplete text (blue highlight).
      if (autocomplete_controller_->result().default_match()) {
        edit_model_->OnCurrentMatchChanged();
      } else {
        edit_model_->OnPopupResultChanged();
        edit_model_->OnPopupDataChanged(
            std::u16string(),
            /*is_temporary_text=*/false, std::u16string(), std::u16string(),
            std::u16string(), false, std::u16string(), AutocompleteMatch());
      }
    } else {
      edit_model_->OnPopupResultChanged();
    }
  }

  const bool popup_is_open = edit_model_->PopupIsOpen();
  if (popup_was_open != popup_is_open) {
    client_->OnPopupVisibilityChanged(popup_is_open);
  }

  if (popup_was_open && !popup_is_open) {
    // Accept the temporary text as the user text, because it makes little sense
    // to have temporary text when the popup is closed.
    edit_model_->AcceptTemporaryTextAsUserText();
    // Closing the popup can change the default suggestion. This usually occurs
    // when it's unclear whether the input represents a search or URL; e.g.,
    // 'a.com/b c' or when title autocompleting. Clear the additional text to
    // avoid suggesting the omnibox contains a URL suggestion when that may no
    // longer be the case; i.e. when the default suggestion changed from a URL
    // to a search suggestion upon closing the popup.
    edit_model_->ClearAdditionalText();
  }

  // Note: The client outlives |this|, so bind a weak pointer to the callback
  // passed in to eliminate the potential for crashes on shutdown.
  // `should_preload` is set to `controller->done()` as prerender may only want
  // to start preloading a result after all Autocomplete results are ready.
  client_->OnResultChanged(
      autocomplete_controller_->result(), default_match_changed,
      /*should_preload=*/controller->done(),
      base::BindRepeating(&OmniboxController::SetRichSuggestionBitmap,
                          weak_ptr_factory_.GetWeakPtr()));
}

void OmniboxController::ClearPopupKeywordMode() const {
  TRACE_EVENT0("omnibox", "OmniboxController::ClearPopupKeywordMode");
  if (edit_model_->PopupIsOpen()) {
    OmniboxPopupSelection selection = edit_model_->GetPopupSelection();
    if (selection.state == OmniboxPopupSelection::KEYWORD_MODE) {
      selection.state = OmniboxPopupSelection::NORMAL;
      edit_model_->SetPopupSelection(selection);
    }
  }
}

bool OmniboxController::IsSuggestionHidden(
    const AutocompleteMatch& match) const {
  if (OmniboxFieldTrial::IsStarterPackExpansionEnabled() &&
      match.from_keyword) {
    const TemplateURL* turl =
        match.GetTemplateURL(client_->GetTemplateURLService());
    if (turl &&
        turl->starter_pack_id() == template_url_starter_pack_data::kGemini) {
      return true;
    }
  }
  return false;
}

void OmniboxController::SetRichSuggestionBitmap(int result_index,
                                                const GURL& icon_url,
                                                const SkBitmap& bitmap) {
  if (!icon_url.is_empty()) {
    edit_model_->SetIconBitmap(icon_url, bitmap);
  } else {
    edit_model_->SetPopupRichSuggestionBitmap(result_index, bitmap);
  }
}
