// Copyright 2018 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/omnibox_pedal.h"

#include <cctype>

#include "base/strings/utf_string_conversions.h"
#include "components/omnibox/browser/omnibox_client.h"
#include "components/omnibox/browser/omnibox_edit_controller.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "ui/base/l10n/l10n_util.h"

#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS)
#include "components/omnibox/browser/vector_icons.h"  // nogncheck
#endif

OmniboxPedal::LabelStrings::LabelStrings(int id_hint,
                                         int id_hint_short,
                                         int id_suggestion_contents)
    : hint(l10n_util::GetStringUTF16(id_hint)),
      hint_short(l10n_util::GetStringUTF16(id_hint_short)),
      suggestion_contents(l10n_util::GetStringUTF16(id_suggestion_contents)) {}

// =============================================================================

OmniboxPedal::SynonymGroup::SynonymGroup(
    bool required,
    std::initializer_list<const char*> synonyms)
    : required_(required) {
  // The DCHECK logic below is quickly ensuring that the synonyms are provided
  // in descending order of string length.
#if DCHECK_IS_ON()
  size_t min_size = std::numeric_limits<std::size_t>::max();
#endif
  synonyms_.reserve(synonyms.size());
  for (const char* synonym : synonyms) {
    synonyms_.push_back(base::ASCIIToUTF16(synonym));
#if DCHECK_IS_ON()
    size_t size = synonyms_.back().size();
    DCHECK_LE(size, min_size);
    min_size = size;
#endif
  }
}

OmniboxPedal::SynonymGroup::SynonymGroup(const SynonymGroup& other) = default;

OmniboxPedal::SynonymGroup::~SynonymGroup() = default;

bool OmniboxPedal::SynonymGroup::EraseFirstMatchIn(
    base::string16& remaining) const {
  for (const auto& synonym : synonyms_) {
    const size_t pos = remaining.find(synonym);
    if (pos != base::string16::npos) {
      remaining.erase(pos, synonym.size());
      return true;
    }
  }
  return !required_;
}

// =============================================================================

OmniboxPedal::OmniboxPedal(
    LabelStrings strings,
    GURL url,
    std::initializer_list<const char*> triggers,
    std::initializer_list<const SynonymGroup> synonym_groups)
    : strings_(strings), url_(url) {
  triggers_.reserve(triggers.size());
  for (const char* trigger : triggers) {
    triggers_.insert(base::ASCIIToUTF16(trigger));
  }
  synonym_groups_.reserve(synonym_groups.size());
  for (const SynonymGroup& group : synonym_groups) {
    synonym_groups_.push_back(group);
  }
}

OmniboxPedal::~OmniboxPedal() {}

const OmniboxPedal::LabelStrings& OmniboxPedal::GetLabelStrings() const {
  return strings_;
}

bool OmniboxPedal::IsNavigation() const {
  return !url_.is_empty();
}

const GURL& OmniboxPedal::GetNavigationUrl() const {
  return url_;
}

bool OmniboxPedal::ShouldExecute(bool button_pressed) const {
  const auto mode = OmniboxFieldTrial::GetPedalSuggestionMode();
  return (mode == OmniboxFieldTrial::PedalSuggestionMode::DEDICATED) ||
         (mode == OmniboxFieldTrial::PedalSuggestionMode::IN_SUGGESTION &&
          button_pressed);
}

bool OmniboxPedal::ShouldPresentButton() const {
  return OmniboxFieldTrial::GetPedalSuggestionMode() ==
         OmniboxFieldTrial::PedalSuggestionMode::IN_SUGGESTION;
}

void OmniboxPedal::Execute(OmniboxPedal::ExecutionContext& context) const {
  DCHECK(IsNavigation());
  OpenURL(context, url_);
}

bool OmniboxPedal::IsReadyToTrigger(
    const AutocompleteProviderClient& client) const {
  return true;
}

#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS)
const gfx::VectorIcon& OmniboxPedal::GetVectorIcon() const {
  return omnibox::kPedalIcon;
}
#endif

bool OmniboxPedal::IsTriggerMatch(const base::string16& match_text) const {
  return (triggers_.find(match_text) != triggers_.end()) ||
         IsConceptMatch(match_text);
}

bool OmniboxPedal::IsConceptMatch(const base::string16& match_text) const {
  base::string16 remaining = match_text;
  for (const auto& group : synonym_groups_) {
    if (!group.EraseFirstMatchIn(remaining))
      return false;
  }
  // If any non-space is remaining, it means there is something in match_text
  // that was not covered by groups, so conservatively treat it as non-match.
  const auto is_space = [](auto c) { return std::isspace(c); };
  return std::all_of(remaining.begin(), remaining.end(), is_space);
}

void OmniboxPedal::OpenURL(OmniboxPedal::ExecutionContext& context,
                           const GURL& url) const {
  context.controller_.OnAutocompleteAccept(
      url, WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_GENERATED,
      AutocompleteMatchType::PEDAL, context.match_selection_timestamp_);
}
