// Copyright 2023 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/fake_autocomplete_controller.h"

#include <memory>
#include <string>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/task_environment.h"
#include "components/omnibox/browser/autocomplete_controller.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_match_type.h"
#include "components/omnibox/browser/fake_autocomplete_controller.h"
#include "components/omnibox/browser/fake_autocomplete_provider.h"
#include "components/omnibox/browser/fake_autocomplete_provider_client.h"
#include "components/omnibox/browser/omnibox_prefs.h"
#include "components/omnibox/browser/test_scheme_classifier.h"
#include "components/prefs/pref_registry_simple.h"
#include "testing/gtest/include/gtest/gtest.h"

void FakeAutocompleteControllerObserver::OnResultChanged(
    AutocompleteController* controller,
    bool default_match_changed) {
  on_result_changed_call_count_++;
  last_default_match_changed = default_match_changed;
}

void FakeAutocompleteControllerObserver::OnAutocompleteStopTimerTriggered(
    const AutocompleteInput& input) {
  on_autocomplete_stop_timer_stopped_call_count++;
}

FakeAutocompleteController::FakeAutocompleteController(
    raw_ptr<base::test::SingleThreadTaskEnvironment> task_environment)
    : AutocompleteController(std::make_unique<FakeAutocompleteProviderClient>(),
                             0),
      task_environment_(task_environment) {
  omnibox::RegisterProfilePrefs(static_cast<PrefRegistrySimple*>(
      static_cast<FakeAutocompleteProviderClient*>(
          autocomplete_provider_client())
          ->GetPrefs()
          ->DeprecatedGetPrefRegistry()));

  providers_.push_back(base::MakeRefCounted<FakeAutocompleteProvider>(
      AutocompleteProvider::Type::TYPE_BOOKMARK));
  providers_.push_back(base::MakeRefCounted<FakeAutocompleteProvider>(
      AutocompleteProvider::Type::TYPE_BUILTIN));
  providers_.push_back(base::MakeRefCounted<FakeAutocompleteProvider>(
      AutocompleteProvider::Type::TYPE_HISTORY_QUICK));
  providers_.push_back(base::MakeRefCounted<FakeAutocompleteProvider>(
      AutocompleteProvider::Type::TYPE_KEYWORD));
  providers_.push_back(base::MakeRefCounted<FakeAutocompleteProvider>(
      AutocompleteProvider::Type::TYPE_SEARCH));
  providers_.push_back(base::MakeRefCounted<FakeAutocompleteProvider>(
      AutocompleteProvider::Type::TYPE_HISTORY_URL));
  providers_.push_back(base::MakeRefCounted<FakeAutocompleteProvider>(
      AutocompleteProvider::Type::TYPE_DOCUMENT));
  providers_.push_back(base::MakeRefCounted<FakeAutocompleteProvider>(
      AutocompleteProvider::Type::TYPE_HISTORY_CLUSTER_PROVIDER));

  observer_ = std::make_unique<FakeAutocompleteControllerObserver>();
  AddObserver(observer_.get());
}

FakeAutocompleteController::~FakeAutocompleteController() = default;

// static
AutocompleteInput FakeAutocompleteController::CreateInput(
    std::u16string text,
    bool omit_async,
    bool prevent_inline_autocomplete) {
  AutocompleteInput input(text, 0, metrics::OmniboxEventProto::OTHER,
                          TestSchemeClassifier());
  input.set_omit_asynchronous_matches(omit_async);
  input.set_prevent_inline_autocomplete(prevent_inline_autocomplete);
  return input;
}

std::vector<std::string> FakeAutocompleteController::SimulateAutocompletePass(
    bool sync,
    bool done,
    std::vector<AutocompleteMatch> matches,
    AutocompleteInput input) {
  GetFakeProvider().matches_ = matches;
  GetFakeProvider().done_ = done;
  AutocompleteController::UpdateType expected_last_update_type =
      AutocompleteController::UpdateType::kNone;
  EXPECT_EQ(observer_->on_result_changed_call_count_, 0);
  if (sync) {
    Start(input);
    expected_last_update_type =
        done ? AutocompleteController::UpdateType::kSyncPassOnly
             : AutocompleteController::UpdateType::kSyncPass;
  } else {
    OnProviderUpdate(true, &GetFakeProvider());
    expected_last_update_type =
        done ? AutocompleteController::UpdateType::kLastAsyncPass
             : AutocompleteController::UpdateType::kAsyncPass;
  }

  ExpectOnResultChanged(sync || done ? 0 : 200, expected_last_update_type);

  return GetResultContents(true);
}

std::vector<std::string>
FakeAutocompleteController::SimulateCleanAutocompletePass(
    std::vector<AutocompleteMatch> matches) {
  internal_result_.ClearMatches();
  return SimulateAutocompletePass(true, true, matches);
}

std::vector<std::string> FakeAutocompleteController::SimulateExpirePass() {
  EXPECT_EQ(observer_->on_result_changed_call_count_, 0);
  UpdateResult(AutocompleteController::UpdateType::kExpirePass);
  ExpectOnResultChanged(200, AutocompleteController::UpdateType::kExpirePass);
  return GetResultContents(true);
}

std::vector<std::string> FakeAutocompleteController::GetResultContents(
    bool published) {
  std::vector<std::string> names;
  auto& result = published ? published_result_ : internal_result_;
  for (const auto& match : result)
    names.push_back(base::UTF16ToUTF8(match.contents));
  return names;
}

void FakeAutocompleteController::ExpectOnResultChanged(
    int delay_ms,
    AutocompleteController::UpdateType last_update_type) {
  std::string debug =
      "delay_ms: " + base::NumberToString(delay_ms) + ", last_update_type: " +
      AutocompleteController::UpdateTypeToDebugString(last_update_type);
  if (delay_ms) {
    task_environment_->FastForwardBy(base::Milliseconds(delay_ms - 1));
    EXPECT_EQ(observer_->on_result_changed_call_count_, 0) << debug;
    task_environment_->FastForwardBy(base::Milliseconds(1));
    EXPECT_EQ(observer_->on_result_changed_call_count_, 1) << debug;
  } else {
    EXPECT_EQ(observer_->on_result_changed_call_count_, 1) << debug;
  }
  EXPECT_EQ(last_update_type_, last_update_type) << debug;
  observer_->on_result_changed_call_count_ = 0;
}

void FakeAutocompleteController::ExpectStopAfter(int delay_ms,
                                                 bool explicit_stop) {
  if (delay_ms) {
    task_environment_->FastForwardBy(base::Milliseconds(delay_ms - 1));
    EXPECT_NE(last_update_type_, AutocompleteController::UpdateType::kStop)
        << delay_ms;
    EXPECT_EQ(observer_->on_autocomplete_stop_timer_stopped_call_count, 0)
        << delay_ms;
    task_environment_->FastForwardBy(base::Milliseconds(1));
  }
  EXPECT_EQ(last_update_type_, AutocompleteController::UpdateType::kStop)
      << delay_ms;
  EXPECT_EQ(observer_->on_autocomplete_stop_timer_stopped_call_count,
            explicit_stop ? 0 : 1)
      << delay_ms;
  // Any expected notifications should be verified with
  // `ExpectOnResultChanged()` and not slip through polluting subsequent
  // tests.
  EXPECT_EQ(observer_->on_result_changed_call_count_, 0) << delay_ms;
  observer_->on_autocomplete_stop_timer_stopped_call_count = 0;
}

void FakeAutocompleteController::ExpectNoNotificationOrStop() {
  // Cache the `last_update_type_` and override, so that we can verify no new
  // stop updates happen even if the last update was a stop.
  auto last_update_type = last_update_type_;
  last_update_type_ = AutocompleteController::UpdateType::kNone;

  task_environment_->FastForwardBy(base::Milliseconds(10000));
  EXPECT_EQ(observer_->on_result_changed_call_count_, 0);
  EXPECT_NE(last_update_type_, AutocompleteController::UpdateType::kStop);

  last_update_type_ = last_update_type;
}
