// Copyright 2015 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/clipboard_provider.h"

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include "base/containers/cxx20_erase.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/thread_pool.h"
#include "build/build_config.h"
#include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_provider_client.h"
#include "components/omnibox/browser/autocomplete_provider_listener.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/omnibox/browser/page_classification_functions.h"
#include "components/omnibox/browser/verbatim_match.h"
#include "components/omnibox/common/omnibox_features.h"
#include "components/open_from_clipboard/clipboard_recent_content.h"
#include "components/search_engines/template_url_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/url_formatter/url_formatter.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/metrics_proto/omnibox_focus_type.pb.h"
#include "third_party/omnibox_proto/groups.pb.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_util.h"

#if !BUILDFLAG(IS_IOS)
#include "ui/base/clipboard/clipboard.h"  // nogncheck
#endif                                    // !BUILDFLAG(IS_IOS)

namespace {
constexpr bool is_android = !!BUILDFLAG(IS_ANDROID);

const size_t kMaxClipboardSuggestionShownNumTimesSimpleSize = 20;

// Clipboard suggestion is placed either in a dedicated
// SECTION_MOBILE_CLIPBOARD, or SECTION_PERSONALIZED_ZERO_SUGGEST.
// The score for the former is irrelevant, but for the latter we need to be
// confident the suggestion shows up on top.
const int kClipboardMatchRelevanceScore = 1600;

bool IsMatchDeletionEnabled() {
  return base::FeatureList::IsEnabled(
      omnibox::kOmniboxRemoveSuggestionsFromClipboard);
}

void RecordCreatingClipboardSuggestionMetrics(
    size_t current_url_suggested_times,
    bool matches_is_empty,
    AutocompleteMatchType::Type match_type,
    const base::TimeDelta clipboard_contents_age) {
  DCHECK(match_type == AutocompleteMatchType::CLIPBOARD_URL ||
         match_type == AutocompleteMatchType::CLIPBOARD_TEXT ||
         match_type == AutocompleteMatchType::CLIPBOARD_IMAGE);

  base::UmaHistogramSparse(
      "Omnibox.ClipboardSuggestionShownNumTimes",
      std::min(current_url_suggested_times,
               kMaxClipboardSuggestionShownNumTimesSimpleSize));
  UMA_HISTOGRAM_BOOLEAN("Omnibox.ClipboardSuggestionShownWithCurrentURL",
                        !matches_is_empty);
  UMA_HISTOGRAM_LONG_TIMES_100("Omnibox.ClipboardSuggestionShownAge",
                               clipboard_contents_age);
  if (match_type == AutocompleteMatchType::CLIPBOARD_URL) {
    base::UmaHistogramSparse(
        "Omnibox.ClipboardSuggestionShownNumTimes.URL",
        std::min(current_url_suggested_times,
                 kMaxClipboardSuggestionShownNumTimesSimpleSize));
    UMA_HISTOGRAM_BOOLEAN("Omnibox.ClipboardSuggestionShownWithCurrentURL.URL",
                          !matches_is_empty);
    UMA_HISTOGRAM_LONG_TIMES_100("Omnibox.ClipboardSuggestionShownAge.URL",
                                 clipboard_contents_age);
  } else if (match_type == AutocompleteMatchType::CLIPBOARD_TEXT) {
    base::UmaHistogramSparse(
        "Omnibox.ClipboardSuggestionShownNumTimes.TEXT",
        std::min(current_url_suggested_times,
                 kMaxClipboardSuggestionShownNumTimesSimpleSize));
    UMA_HISTOGRAM_BOOLEAN("Omnibox.ClipboardSuggestionShownWithCurrentURL.TEXT",
                          !matches_is_empty);
    UMA_HISTOGRAM_LONG_TIMES_100("Omnibox.ClipboardSuggestionShownAge.TEXT",
                                 clipboard_contents_age);
  } else if (match_type == AutocompleteMatchType::CLIPBOARD_IMAGE) {
    base::UmaHistogramSparse(
        "Omnibox.ClipboardSuggestionShownNumTimes.IMAGE",
        std::min(current_url_suggested_times,
                 kMaxClipboardSuggestionShownNumTimesSimpleSize));
    UMA_HISTOGRAM_BOOLEAN(
        "Omnibox.ClipboardSuggestionShownWithCurrentURL.IMAGE",
        !matches_is_empty);
    UMA_HISTOGRAM_LONG_TIMES_100("Omnibox.ClipboardSuggestionShownAge.IMAGE",
                                 clipboard_contents_age);
  }
}

void RecordDeletingClipboardSuggestionMetrics(
    AutocompleteMatchType::Type match_type,
    const base::TimeDelta clipboard_contents_age) {
  base::RecordAction(
      base::UserMetricsAction("Omnibox.ClipboardSuggestionRemoved"));

  UMA_HISTOGRAM_LONG_TIMES_100("Omnibox.ClipboardSuggestionRemovedAge",
                               clipboard_contents_age);
  if (match_type == AutocompleteMatchType::CLIPBOARD_URL) {
    UMA_HISTOGRAM_LONG_TIMES_100("Omnibox.ClipboardSuggestionRemovedAge.URL",
                                 clipboard_contents_age);
  } else if (match_type == AutocompleteMatchType::CLIPBOARD_TEXT) {
    UMA_HISTOGRAM_LONG_TIMES_100("Omnibox.ClipboardSuggestionRemovedAge.TEXT",
                                 clipboard_contents_age);
  } else if (match_type == AutocompleteMatchType::CLIPBOARD_IMAGE) {
    UMA_HISTOGRAM_LONG_TIMES_100("Omnibox.ClipboardSuggestionRemovedAge.IMAGE",
                                 clipboard_contents_age);
  }
}
}  // namespace

ClipboardProvider::ClipboardProvider(AutocompleteProviderClient* client,
                                     AutocompleteProviderListener* listener,
                                     ClipboardRecentContent* clipboard_content)
    : AutocompleteProvider(AutocompleteProvider::TYPE_CLIPBOARD),
      client_(client),
      clipboard_content_(clipboard_content),
      current_url_suggested_times_(0) {
  DCHECK(clipboard_content_);
  AddListener(listener);
}

ClipboardProvider::~ClipboardProvider() {}

void ClipboardProvider::Start(const AutocompleteInput& input,
                              bool minimal_changes) {
  matches_.clear();

  // If the user started typing, do not offer clipboard based match.
  if (input.focus_type() == metrics::OmniboxFocusType::INTERACTION_DEFAULT)
    return;

  // Image matched was kicked off asynchronously, so proceed when that ends.
  if (!input.omit_asynchronous_matches() && CreateImageMatch(input))
    return;

  bool read_clipboard_content = false;
  bool read_clipboard_url;
  absl::optional<AutocompleteMatch> optional_match =
      CreateURLMatch(input, &read_clipboard_url);
  read_clipboard_content |= read_clipboard_url;
  if (!optional_match) {
    bool read_clipboard_text;
    optional_match = CreateTextMatch(input, &read_clipboard_text);
    read_clipboard_content |= read_clipboard_text;
  }

  if (optional_match) {
    AddCreatedMatchWithTracking(input, std::move(optional_match).value(),
                                clipboard_content_->GetClipboardContentAge());
    return;
  }

  // If there was clipboard content, but no match, don't proceed. There was
  // some other reason for not creating a match (e.g. copied URL but the URL was
  // the same as the current URL).
  if (read_clipboard_content) {
    return;
  }

  done_ = true;

#if !BUILDFLAG(IS_IOS)
  // kSuppressClipboardSuggestionAfterFirstUsed is enabled only for platforms
  // that don't access the clipboard contents until clicked. On those platforms,
  // we store a timestamp identifying the clipboard contents when the suggestion
  // is clicked. If we see this timestamp subsequently, we suppress showing a
  // suggestion. If the timestamp of the clipboard content changes, we start
  // showing the suggestion again.
  if (most_recently_used_clipboard_suggestion_timestamp_ != base::Time() &&
      most_recently_used_clipboard_suggestion_timestamp_ ==
          ui::Clipboard::GetForCurrentThread()->GetLastModifiedTime() &&
      base::FeatureList::IsEnabled(
          omnibox::kSuppressClipboardSuggestionAfterFirstUsed)) {
    done_ = true;
    return;
  }
#endif  // !BUILDFLAG(IS_IOS)

  // On iOS and Android, accessing the clipboard contents shows a notification
  // to the user. To avoid this, all the methods above will not check the
  // contents and will return false/absl::nullopt. Instead, check the existence
  // of content without accessing the actual content and create blank matches.
  if (!input.omit_asynchronous_matches()) {
    // Image matched was kicked off asynchronously, so proceed when that ends.
    CheckClipboardContent(input);
  }
}

void ClipboardProvider::Stop(bool clear_cached_results,
                             bool due_to_user_inactivity) {
  AutocompleteProvider::Stop(clear_cached_results, due_to_user_inactivity);

  callback_weak_ptr_factory_.InvalidateWeakPtrs();
}

void ClipboardProvider::DeleteMatch(const AutocompleteMatch& match) {
  RecordDeletingClipboardSuggestionMetrics(
      match.type, clipboard_content_->GetClipboardContentAge());
  clipboard_content_->ClearClipboardContent();

  const auto pred = [&match](const AutocompleteMatch& i) {
    return i.contents == match.contents && i.type == match.type;
  };
  base::EraseIf(matches_, pred);
}

void ClipboardProvider::AddProviderInfo(ProvidersInfo* provider_info) const {
  // If a URL wasn't suggested on this most recent focus event, don't bother
  // setting |times_returned_results_in_session|, as in effect this URL has
  // never been suggested during the current session.  (For the purpose of
  // this provider, we define a session as intervals between when a URL
  // clipboard suggestion changes.)
  if (current_url_suggested_times_ == 0)
    return;
  provider_info->push_back(metrics::OmniboxEventProto_ProviderInfo());
  metrics::OmniboxEventProto_ProviderInfo& new_entry = provider_info->back();
  new_entry.set_provider(AsOmniboxEventProviderType());
  new_entry.set_provider_done(done_);
  new_entry.set_times_returned_results_in_session(current_url_suggested_times_);
}

void ClipboardProvider::AddCreatedMatchWithTracking(
    const AutocompleteInput& input,
    AutocompleteMatch match,
    const base::TimeDelta clipboard_contents_age) {
  // Record the number of times the currently-offered URL has been suggested.
  // This only works over this run of Chrome; if the URL was in the clipboard
  // on a previous run, those offerings will not be counted.
  if (match.destination_url == current_url_suggested_) {
    current_url_suggested_times_++;
  } else {
    current_url_suggested_ = match.destination_url;
    current_url_suggested_times_ = 1;
  }

  RecordCreatingClipboardSuggestionMetrics(current_url_suggested_times_,
                                           matches_.empty(), match.type,
                                           clipboard_contents_age);

  if (is_android &&
      OmniboxFieldTrial::kOmniboxModernizeVisualUpdateMergeClipboardOnNTP
          .Get() &&
      omnibox::IsNTPPage(input.current_page_classification())) {
    // Assign the Clipboard to the PZPS group on NTP pages to improve the use
    // of the suggest space.
    match.suggestion_group_id = omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST;
  } else {
    // Leave the clipboard in its dedicated section otherwise.
    match.suggestion_group_id = omnibox::GROUP_MOBILE_CLIPBOARD;
  }

  matches_.push_back(match);
}

bool ClipboardProvider::TemplateURLSupportsTextSearch() {
  TemplateURLService* url_service = client_->GetTemplateURLService();
  const TemplateURL* default_url = url_service->GetDefaultSearchProvider();
  if (!default_url)
    return false;

  DCHECK(!default_url->url().empty());
  DCHECK(default_url->url_ref().IsValid(url_service->search_terms_data()));
  return true;
}

bool ClipboardProvider::TemplateURLSupportsImageSearch() {
  TemplateURLService* url_service = client_->GetTemplateURLService();
  const TemplateURL* default_url = url_service->GetDefaultSearchProvider();

  return default_url && !default_url->image_url().empty() &&
         default_url->image_url_ref().IsValid(url_service->search_terms_data());
}

void ClipboardProvider::CheckClipboardContent(const AutocompleteInput& input) {
  std::set<ClipboardContentType> desired_types;
  desired_types.insert(ClipboardContentType::URL);

  if (TemplateURLSupportsTextSearch()) {
    desired_types.insert(ClipboardContentType::Text);
  }

  if (TemplateURLSupportsImageSearch()) {
    desired_types.insert(ClipboardContentType::Image);
  }

  done_ = false;

  // We want to get the age here because the contents of the clipboard could
  // change after this point. We want the age of the contents we actually use,
  // not the age of whatever's on the clipboard when the histogram is created
  // (i.e when the match is created).
  base::TimeDelta clipboard_contents_age =
      clipboard_content_->GetClipboardContentAge();
  clipboard_content_->HasRecentContentFromClipboard(
      desired_types,
      base::BindOnce(&ClipboardProvider::OnReceiveClipboardContent,
                     callback_weak_ptr_factory_.GetWeakPtr(), input,
                     clipboard_contents_age));
}

void ClipboardProvider::OnReceiveClipboardContent(
    const AutocompleteInput& input,
    base::TimeDelta clipboard_contents_age,
    std::set<ClipboardContentType> matched_types) {
  if (TemplateURLSupportsImageSearch() &&
      matched_types.find(ClipboardContentType::Image) != matched_types.end()) {
    // The image content will be added in later. If the image is large, encoding
    // the image may take some time, so just be wary whenever that step happens
    // (e.g OmniboxView::OpenMatch).
    AutocompleteMatch match = NewBlankImageMatch();
    AddCreatedMatchWithTracking(input, std::move(match),
                                clipboard_contents_age);
    NotifyListeners(true);
  } else if (matched_types.find(ClipboardContentType::URL) !=
             matched_types.end()) {
    AutocompleteMatch match = NewBlankURLMatch();
    AddCreatedMatchWithTracking(input, std::move(match),
                                clipboard_contents_age);
    NotifyListeners(true);
  } else if (TemplateURLSupportsTextSearch() &&
             matched_types.find(ClipboardContentType::Text) !=
                 matched_types.end()) {
    AutocompleteMatch match = NewBlankTextMatch();
    AddCreatedMatchWithTracking(input, std::move(match),
                                clipboard_contents_age);
    NotifyListeners(true);
  }
  done_ = true;
}

absl::optional<AutocompleteMatch> ClipboardProvider::CreateURLMatch(
    const AutocompleteInput& input,
    bool* read_clipboard_content) {
  *read_clipboard_content = false;
  if (base::FeatureList::IsEnabled(
          omnibox::kClipboardSuggestionContentHidden)) {
    return absl::nullopt;
  }
  // The clipboard does not contain a URL worth suggesting.
  absl::optional<GURL> optional_gurl =
      clipboard_content_->GetRecentURLFromClipboard();
  if (!optional_gurl)
    return absl::nullopt;

  *read_clipboard_content = true;
  GURL url = std::move(optional_gurl).value();

  // The URL on the page is the same as the URL in the clipboard.  Don't
  // bother suggesting it.
  if (url == input.current_url())
    return absl::nullopt;

  return NewClipboardURLMatch(url);
}

absl::optional<AutocompleteMatch> ClipboardProvider::CreateTextMatch(
    const AutocompleteInput& input,
    bool* read_clipboard_content) {
  *read_clipboard_content = false;
  if (base::FeatureList::IsEnabled(
          omnibox::kClipboardSuggestionContentHidden)) {
    return absl::nullopt;
  }

  if (!TemplateURLSupportsTextSearch()) {
    return absl::nullopt;
  }

  absl::optional<std::u16string> optional_text =
      clipboard_content_->GetRecentTextFromClipboard();
  if (!optional_text)
    return absl::nullopt;

  *read_clipboard_content = true;
  std::u16string text = std::move(optional_text).value();

  // The clipboard can contain the empty string, which shouldn't be suggested.
  if (text.empty())
    return absl::nullopt;

  // The text in the clipboard is a url. We don't want to prompt the user to
  // search for a url.
  if (GURL(text).is_valid())
    return absl::nullopt;

  return NewClipboardTextMatch(text);
}

bool ClipboardProvider::CreateImageMatch(const AutocompleteInput& input) {
  if (base::FeatureList::IsEnabled(
          omnibox::kClipboardSuggestionContentHidden)) {
    return false;
  }

  if (!clipboard_content_->HasRecentImageFromClipboard()) {
    return false;
  }

  if (!TemplateURLSupportsImageSearch()) {
    return false;
  }

  done_ = false;

  // We want to get the age here because the contents of the clipboard could
  // change after this point. We want the age of the image we actually use, not
  // the age of whatever's on the clipboard when the histogram is created (i.e
  // when the match is created).
  base::TimeDelta clipboard_contents_age =
      clipboard_content_->GetClipboardContentAge();
  clipboard_content_->GetRecentImageFromClipboard(base::BindOnce(
      &ClipboardProvider::CreateImageMatchCallback,
      callback_weak_ptr_factory_.GetWeakPtr(), input, clipboard_contents_age));
  return true;
}

void ClipboardProvider::CreateImageMatchCallback(
    const AutocompleteInput& input,
    const base::TimeDelta clipboard_contents_age,
    absl::optional<gfx::Image> optional_image) {
  NewClipboardImageMatch(
      optional_image, base::BindOnce(&ClipboardProvider::AddImageMatchCallback,
                                     callback_weak_ptr_factory_.GetWeakPtr(),
                                     input, clipboard_contents_age));
}

void ClipboardProvider::AddImageMatchCallback(
    const AutocompleteInput& input,
    const base::TimeDelta clipboard_contents_age,
    absl::optional<AutocompleteMatch> match) {
  if (!match) {
    return;
  }
  AddCreatedMatchWithTracking(input, std::move(match).value(),
                              clipboard_contents_age);
  NotifyListeners(true);
  done_ = true;
}

AutocompleteMatch ClipboardProvider::NewBlankURLMatch() {
  AutocompleteMatch match(this, kClipboardMatchRelevanceScore,
                          IsMatchDeletionEnabled(),
                          AutocompleteMatchType::CLIPBOARD_URL);

  match.description.assign(l10n_util::GetStringUTF16(IDS_LINK_FROM_CLIPBOARD));
  if (!match.description.empty())
    match.description_class.push_back({0, ACMatchClassification::NONE});
  return match;
}

AutocompleteMatch ClipboardProvider::NewClipboardURLMatch(GURL url) {
  DCHECK(url.is_valid());

  AutocompleteMatch match = NewBlankURLMatch();

  UpdateClipboardURLContent(url, &match);

  return match;
}

AutocompleteMatch ClipboardProvider::NewBlankTextMatch() {
  AutocompleteMatch match(this, kClipboardMatchRelevanceScore,
                          IsMatchDeletionEnabled(),
                          AutocompleteMatchType::CLIPBOARD_TEXT);
  // Any path leading here should first verify whether
  // TemplateUrlSupportsTextSearch().
  TemplateURLService* url_service = client_->GetTemplateURLService();
  const TemplateURL* default_url = url_service->GetDefaultSearchProvider();
  DCHECK(!!default_url);
  match.keyword = default_url->keyword();

  match.description.assign(l10n_util::GetStringUTF16(IDS_TEXT_FROM_CLIPBOARD));
  if (!match.description.empty())
    match.description_class.push_back({0, ACMatchClassification::NONE});

  match.transition = ui::PAGE_TRANSITION_GENERATED;
  return match;
}

absl::optional<AutocompleteMatch> ClipboardProvider::NewClipboardTextMatch(
    std::u16string text) {
  AutocompleteMatch match = NewBlankTextMatch();

  if (!UpdateClipboardTextContent(text, &match))
    return absl::nullopt;

  return match;
}

AutocompleteMatch ClipboardProvider::NewBlankImageMatch() {
  AutocompleteMatch match(this, kClipboardMatchRelevanceScore,
                          IsMatchDeletionEnabled(),
                          AutocompleteMatchType::CLIPBOARD_IMAGE);
  // Any path leading here should first verify whether
  // TemplateUrlSupportsImageSearch().
  TemplateURLService* url_service = client_->GetTemplateURLService();
  const TemplateURL* default_url = url_service->GetDefaultSearchProvider();
  DCHECK(!!default_url);
  match.keyword = default_url->keyword();

  match.description.assign(l10n_util::GetStringUTF16(IDS_IMAGE_FROM_CLIPBOARD));
  if (!match.description.empty())
    match.description_class.push_back({0, ACMatchClassification::NONE});

  // This will end up being something like "Search for Copied Image." This may
  // seem strange to use for |fill_into_edit|, but it is because iOS requires
  // some text in the text field for the Enter key to work when using keyboard
  // navigation.
  match.fill_into_edit = match.description;
  match.transition = ui::PAGE_TRANSITION_GENERATED;

  return match;
}

void ClipboardProvider::NewClipboardImageMatch(
    absl::optional<gfx::Image> optional_image,
    ClipboardImageMatchCallback callback) {
  // ImageSkia::ToImageSkia should only be called if the gfx::Image is
  // non-empty. It is unclear when the clipboard returns a non-optional but
  // empty image. See crbug.com/1136759 for more details.
  if (!optional_image || optional_image.value().IsEmpty()) {
    std::move(callback).Run(absl::nullopt);
    return;
  }
  gfx::ImageSkia image_skia = *optional_image.value().ToImageSkia();
  image_skia.MakeThreadSafe();
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE,
      base::BindOnce(&ClipboardProvider::EncodeClipboardImage, image_skia),
      base::BindOnce(&ClipboardProvider::ConstructImageMatchCallback,
                     callback_weak_ptr_factory_.GetWeakPtr(),
                     std::move(callback)));
}

void ClipboardProvider::UpdateClipboardMatchWithContent(
    AutocompleteMatch* match,
    ClipboardMatchCallback callback) {
  DCHECK(match);
  if (match->type == AutocompleteMatchType::CLIPBOARD_URL) {
    clipboard_content_->GetRecentURLFromClipboard(base::BindOnce(
        &ClipboardProvider::OnReceiveURLForMatchWithContent,
        callback_weak_ptr_factory_.GetWeakPtr(), std::move(callback), match));
    return;
  } else if (match->type == AutocompleteMatchType::CLIPBOARD_TEXT) {
    clipboard_content_->GetRecentTextFromClipboard(base::BindOnce(
        &ClipboardProvider::OnReceiveTextForMatchWithContent,
        callback_weak_ptr_factory_.GetWeakPtr(), std::move(callback), match));
    return;
  } else if (match->type == AutocompleteMatchType::CLIPBOARD_IMAGE) {
    clipboard_content_->GetRecentImageFromClipboard(base::BindOnce(
        &ClipboardProvider::OnReceiveImageForMatchWithContent,
        callback_weak_ptr_factory_.GetWeakPtr(), std::move(callback), match));
    return;
  }
}

scoped_refptr<base::RefCountedMemory> ClipboardProvider::EncodeClipboardImage(
    gfx::ImageSkia image_skia) {
  gfx::Image resized_image =
      gfx::ResizedImageForSearchByImage(gfx::Image(image_skia));
  return resized_image.As1xPNGBytes();
}

void ClipboardProvider::ConstructImageMatchCallback(
    ClipboardImageMatchCallback callback,
    scoped_refptr<base::RefCountedMemory> image_bytes) {
  TemplateURLService* url_service = client_->GetTemplateURLService();
  const TemplateURL* default_url = url_service->GetDefaultSearchProvider();
  DCHECK(default_url);

  AutocompleteMatch match = NewBlankImageMatch();

  match.search_terms_args =
      std::make_unique<TemplateURLRef::SearchTermsArgs>(u"");
  match.search_terms_args->image_thumbnail_content.assign(
      image_bytes->front_as<char>(), image_bytes->size());
  TemplateURLRef::PostContent post_content;
  GURL result(default_url->image_url_ref().ReplaceSearchTerms(
      *match.search_terms_args.get(), url_service->search_terms_data(),
      &post_content));

  if (!base::FeatureList::IsEnabled(omnibox::kImageSearchSuggestionThumbnail)) {
    // If Omnibox image suggestion do not need thumbnail, release memory.
    match.search_terms_args.reset();
  }
  match.destination_url = result;
  match.post_content =
      std::make_unique<TemplateURLRef::PostContent>(post_content);

  std::move(callback).Run(match);
}

void ClipboardProvider::OnReceiveURLForMatchWithContent(
    ClipboardMatchCallback callback,
    AutocompleteMatch* match,
    absl::optional<GURL> optional_gurl) {
  if (!optional_gurl)
    return;

  GURL url = std::move(optional_gurl).value();
  UpdateClipboardURLContent(url, match);

  UpdateMostRecentlyUsedClipboardSuggestionTimestamp();
  std::move(callback).Run();
}

void ClipboardProvider::OnReceiveTextForMatchWithContent(
    ClipboardMatchCallback callback,
    AutocompleteMatch* match,
    absl::optional<std::u16string> optional_text) {
  if (!optional_text)
    return;

  std::u16string text = std::move(optional_text).value();
  if (!UpdateClipboardTextContent(text, match))
    return;

  UpdateMostRecentlyUsedClipboardSuggestionTimestamp();
  std::move(callback).Run();
}

void ClipboardProvider::OnReceiveImageForMatchWithContent(
    ClipboardMatchCallback callback,
    AutocompleteMatch* match,
    absl::optional<gfx::Image> optional_image) {
  if (!optional_image)
    return;

  UpdateMostRecentlyUsedClipboardSuggestionTimestamp();
  gfx::Image image = std::move(optional_image).value();
  NewClipboardImageMatch(
      image,
      base::BindOnce(&ClipboardProvider::OnReceiveImageMatchForMatchWithContent,
                     callback_weak_ptr_factory_.GetWeakPtr(),
                     std::move(callback), match));
}

void ClipboardProvider::OnReceiveImageMatchForMatchWithContent(
    ClipboardMatchCallback callback,
    AutocompleteMatch* match,
    absl::optional<AutocompleteMatch> optional_match) {
  DCHECK(match);
  if (!optional_match)
    return;

  match->destination_url = std::move(optional_match->destination_url);
  match->post_content = std::move(optional_match->post_content);
  match->search_terms_args = std::move(optional_match->search_terms_args);

  std::move(callback).Run();
}

void ClipboardProvider::UpdateClipboardURLContent(const GURL& url,
                                                  AutocompleteMatch* match) {
  DCHECK(url.is_valid());
  DCHECK(match);

  match->destination_url = url;

  // Because the user did not type a related input to get this clipboard
  // suggestion, preserve the subdomain so the user has extra context.
  auto format_types = AutocompleteMatch::GetFormatTypes(false, true);
  match->contents.assign(url_formatter::FormatUrl(url, format_types,
                                                  base::UnescapeRule::SPACES,
                                                  nullptr, nullptr, nullptr));
  if (!match->contents.empty())
    match->contents_class.push_back({0, ACMatchClassification::URL});
  match->fill_into_edit =
      AutocompleteInput::FormattedStringWithEquivalentMeaning(
          url, match->contents, client_->GetSchemeClassifier(), nullptr);
}

bool ClipboardProvider::UpdateClipboardTextContent(const std::u16string& text,
                                                   AutocompleteMatch* match) {
  DCHECK(match);

  // The text in the clipboard is a url. We don't want to prompt the user to
  // search for a url.
  if (GURL(text).is_valid())
    return false;

  match->fill_into_edit = text;

  TemplateURLService* url_service = client_->GetTemplateURLService();
  const TemplateURL* default_url = url_service->GetDefaultSearchProvider();
  if (!default_url)
    return false;

  DCHECK(!default_url->url().empty());
  DCHECK(default_url->url_ref().IsValid(url_service->search_terms_data()));
  TemplateURLRef::SearchTermsArgs search_args(text);
  GURL result(default_url->url_ref().ReplaceSearchTerms(
      search_args, url_service->search_terms_data()));

  match->destination_url = result;
  match->contents.assign(AutocompleteMatch::SanitizeString(text));
  if (!match->contents.empty())
    match->contents_class.push_back({0, ACMatchClassification::NONE});

  match->keyword = default_url->keyword();

  return true;
}

void ClipboardProvider::UpdateMostRecentlyUsedClipboardSuggestionTimestamp() {
#if !BUILDFLAG(IS_IOS)
  most_recently_used_clipboard_suggestion_timestamp_ =
      ui::Clipboard::GetForCurrentThread()->GetLastModifiedTime();
#endif  // !BUILDFLAG(IS_IOS)
}
