// 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_controller_config.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>(),
                             AutocompleteControllerConfig{}),
      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;
}
