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

#include <memory>
#include <string>

#include "base/functional/bind.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
#include "components/omnibox/browser/autocomplete_classifier.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_edit_model.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/omnibox/browser/omnibox_popup_selection.h"
#include "components/omnibox/browser/omnibox_popup_view.h"
#include "components/omnibox/browser/page_classification_functions.h"
#include "components/omnibox/common/omnibox_feature_configs.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,
    base::TimeDelta autocomplete_stop_timer_duration)
    : client_(std::move(client)),
      autocomplete_controller_(std::make_unique<AutocompleteController>(
          client_->CreateAutocompleteProviderClient(),
          AutocompleteClassifier::DefaultOmniboxProviders(),
          autocomplete_stop_timer_duration)),
      edit_model_(std::make_unique<OmniboxEditModel>(
          /*omnibox_controller=*/this,
          view)) {
  // 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 (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);
    }
  }
}

std::u16string OmniboxController::GetHeaderForSuggestionGroup(
    omnibox::GroupId suggestion_group_id) const {
  return autocomplete_controller_->result().GetHeaderForSuggestionGroup(
      suggestion_group_id);
}

bool OmniboxController::IsSuggestionHidden(
    const AutocompleteMatch& match) const {
  if (OmniboxFieldTrial::IsStarterPackExpansionEnabled() &&
      match.from_keyword) {
    const TemplateURL* turl =
        match.GetTemplateURL(client_->GetTemplateURLService(), false);
    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);
  }
}
