// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include <numeric>
#include <vector>

#include "base/metrics/field_trial_params.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/bookmarks/browser/titled_url_node.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_match_classification.h"
#include "components/omnibox/browser/history_provider.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/omnibox/browser/url_prefix.h"
#include "components/omnibox/common/omnibox_features.h"
#include "components/url_formatter/url_formatter.h"

namespace {

// Concatenates |ancestors| in reverse order and using '/' as the delimiter.
base::string16 ConcatAncestorsTitles(
    std::vector<base::StringPiece16> ancestors) {
  return ancestors.empty()
             ? base::string16()
             : std::accumulate(std::next(ancestors.rbegin()), ancestors.rend(),
                               base::string16(*ancestors.rbegin()),
                               [](base::string16& a, base::StringPiece16& b) {
                                 return a + base::UTF8ToUTF16("/") +
                                        base::string16(b);
                               });
}

}  // namespace

namespace bookmarks {

AutocompleteMatch TitledUrlMatchToAutocompleteMatch(
    const TitledUrlMatch& titled_url_match,
    AutocompleteMatchType::Type type,
    int relevance,
    AutocompleteProvider* provider,
    const AutocompleteSchemeClassifier& scheme_classifier,
    const AutocompleteInput& input,
    const base::string16& fixed_up_input_text) {
  const base::string16 title = titled_url_match.node->GetTitledUrlNodeTitle();
  const GURL& url = titled_url_match.node->GetTitledUrlNodeUrl();
  const base::string16 path = ConcatAncestorsTitles(
      titled_url_match.node->GetTitledUrlNodeAncestorTitles());

  // The AutocompleteMatch we construct is non-deletable because the only way to
  // support this would be to delete the underlying object that created the
  // titled_url_match. E.g., for the bookmark provider this would mean deleting
  // the underlying bookmark, which is unlikely to be what the user intends.
  AutocompleteMatch match(provider, relevance, false, type);
  match.destination_url = url;
  match.RecordAdditionalInfo("Title", title);
  match.RecordAdditionalInfo("URL", url.spec());
  match.RecordAdditionalInfo("Path", path);

  bool match_in_scheme = false;
  bool match_in_subdomain = false;
  AutocompleteMatch::GetMatchComponents(url,
                                        titled_url_match.url_match_positions,
                                        &match_in_scheme, &match_in_subdomain);
  auto format_types = AutocompleteMatch::GetFormatTypes(
      input.parts().scheme.len > 0 || match_in_scheme, match_in_subdomain);
  const base::string16 formatted_url = url_formatter::FormatUrl(
      url, format_types, net::UnescapeRule::SPACES, nullptr, nullptr, nullptr);

  if (base::GetFieldTrialParamByFeatureAsBool(
          omnibox::kBookmarkPaths,
          OmniboxFieldTrial::kBookmarkPathsUiReplaceUrl, false)) {
    match.contents = path;
  } else if (base::GetFieldTrialParamByFeatureAsBool(
                 omnibox::kBookmarkPaths,
                 OmniboxFieldTrial::kBookmarkPathsUiDynamicReplaceUrl, false)) {
    match.contents = !titled_url_match.has_ancestor_match &&
                             !titled_url_match.url_match_positions.empty()
                         ? formatted_url
                         : path;
  } else {
    match.contents = formatted_url;
  }

  // Bookmark classification diverges from relevance scoring. Specifically,
  // 1) All occurrences of the input contribute to relevance; e.g. for the input
  // 'pre', the bookmark 'pre prefix' will be scored higher than 'pre suffix'.
  // For classification though, if the input is a prefix of the suggestion text,
  // only the prefix will be bolded; e.g. the 1st bookmark will display '[pre]
  // prefix' as opposed to '[pre] [pre]fix'. This divergence allows consistency
  // with other providers' and google.com's bolding.
  // 2) Non-complete-word matches less than 3 characters long do not contribute
  // to relevance; e.g. for the input 'a pr', the bookmark 'a pr prefix' will be
  // scored the same as 'a pr suffix'. For classification though, both
  // occurrences will be bolded, 'a [pr] [pr]efix'.
  auto contents_terms = FindTermMatches(input.text(), match.contents);
  match.contents_class = ClassifyTermMatches(
      contents_terms, match.contents.length(),
      ACMatchClassification::MATCH | ACMatchClassification::URL,
      ACMatchClassification::URL);

  if (base::GetFieldTrialParamByFeatureAsBool(
          omnibox::kBookmarkPaths,
          OmniboxFieldTrial::kBookmarkPathsUiReplaceTitle, false)) {
    match.description = path + base::UTF8ToUTF16("/") + title;
  } else if (base::GetFieldTrialParamByFeatureAsBool(
                 omnibox::kBookmarkPaths,
                 OmniboxFieldTrial::kBookmarkPathsUiAppendAfterTitle, false)) {
    match.description = title + base::UTF8ToUTF16(" : ") + path;
  } else {
    match.description = title;
  }

  base::TrimWhitespace(match.description, base::TRIM_LEADING,
                       &match.description);
  auto description_terms = FindTermMatches(input.text(), match.description);
  match.description_class = ClassifyTermMatches(
      description_terms, match.description.length(),
      ACMatchClassification::MATCH, ACMatchClassification::NONE);

  // The inline_autocomplete_offset should be adjusted based on the formatting
  // applied to |fill_into_edit|.
  size_t inline_autocomplete_offset = URLPrefix::GetInlineAutocompleteOffset(
      input.text(), fixed_up_input_text, false, base::UTF8ToUTF16(url.spec()));
  auto fill_into_edit_format_types = url_formatter::kFormatUrlOmitDefaults;
  if (match_in_scheme)
    fill_into_edit_format_types &= ~url_formatter::kFormatUrlOmitHTTP;
  match.fill_into_edit =
      AutocompleteInput::FormattedStringWithEquivalentMeaning(
          url,
          url_formatter::FormatUrl(url, fill_into_edit_format_types,
                                   net::UnescapeRule::SPACES, nullptr, nullptr,
                                   &inline_autocomplete_offset),
          scheme_classifier, &inline_autocomplete_offset);

  if (match.TryRichAutocompletion(match.contents, match.description, input)) {
    // If rich autocompletion applies, we skip trying the alternatives below.
  } else if (inline_autocomplete_offset != base::string16::npos) {
    match.inline_autocompletion =
        match.fill_into_edit.substr(inline_autocomplete_offset);
    match.SetAllowedToBeDefault(input);
  }

  return match;
}

}  // namespace bookmarks
