// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/json/json_file_value_serializer.h"
#include "base/json/values_util.h"
#include "base/path_service.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/browsing_topics/browsing_topics_service_factory.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/optimization_guide/browser_test_util.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h"
#include "chrome/browser/optimization_guide/page_content_annotations_service_factory.h"
#include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/browsing_topics/browsing_topics_service.h"
#include "components/browsing_topics/browsing_topics_service_impl.h"
#include "components/browsing_topics/epoch_topics.h"
#include "components/browsing_topics/test_util.h"
#include "components/content_settings/browser/page_specific_content_settings.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/optimization_guide/content/browser/page_content_annotations_service.h"
#include "components/optimization_guide/content/browser/test_page_content_annotator.h"
#include "components/optimization_guide/core/test_model_info_builder.h"
#include "components/optimization_guide/core/test_optimization_guide_model_provider.h"
#include "components/privacy_sandbox/privacy_sandbox_settings.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/browsing_topics_site_data_manager.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_features.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browsing_topics_test_util.h"
#include "content/public/test/fenced_frame_test_util.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/test_navigation_observer.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/features.h"

namespace browsing_topics {

namespace {

constexpr browsing_topics::HmacKey kTestKey = {1};

constexpr base::Time kTime1 =
    base::Time::FromDeltaSinceWindowsEpoch(base::Days(1));
constexpr base::Time kTime2 =
    base::Time::FromDeltaSinceWindowsEpoch(base::Days(2));

constexpr size_t kTaxonomySize = 349;
constexpr int kTaxonomyVersion = 1;
constexpr int64_t kModelVersion = 2;
constexpr size_t kPaddedTopTopicsStartIndex = 5;
constexpr Topic kExpectedTopic1 = Topic(1);
constexpr Topic kExpectedTopic2 = Topic(10);
constexpr char kExpectedResultOrder1[] =
    "[{\"configVersion\":\"chrome.1\",\"modelVersion\":\"2\","
    "\"taxonomyVersion\":\"1\",\"topic\":1,\"version\":\"chrome.1:1:2\"};{"
    "\"configVersion\":\"chrome.1\",\"modelVersion\":\"2\","
    "\"taxonomyVersion\":\"1\",\"topic\":10,\"version\":\"chrome.1:1:2\"};]";

constexpr char kExpectedResultOrder2[] =
    "[{\"configVersion\":\"chrome.1\",\"modelVersion\":\"2\","
    "\"taxonomyVersion\":\"1\",\"topic\":10,\"version\":\"chrome.1:1:2\"};{"
    "\"configVersion\":\"chrome.1\",\"modelVersion\":\"2\","
    "\"taxonomyVersion\":\"1\",\"topic\":1,\"version\":\"chrome.1:1:2\"};]";

EpochTopics CreateTestEpochTopics(
    const std::vector<std::pair<Topic, std::set<HashedDomain>>>& topics,
    base::Time calculation_time) {
  DCHECK_EQ(topics.size(), 5u);

  std::vector<TopicAndDomains> top_topics_and_observing_domains;
  for (size_t i = 0; i < 5; ++i) {
    top_topics_and_observing_domains.emplace_back(topics[i].first,
                                                  topics[i].second);
  }

  return EpochTopics(std::move(top_topics_and_observing_domains),
                     kPaddedTopTopicsStartIndex, kTaxonomySize,
                     kTaxonomyVersion, kModelVersion, calculation_time);
}

class PortalActivationWaiter : public content::WebContentsObserver {
 public:
  explicit PortalActivationWaiter(content::WebContents* portal_contents)
      : content::WebContentsObserver(portal_contents) {}

  void Wait() {
    if (!web_contents()->IsPortal())
      return;

    base::RunLoop run_loop;
    quit_closure_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  // content::WebContentsObserver:
  void DidActivatePortal(content::WebContents* predecessor_contents,
                         base::TimeTicks activation_time) override {
    if (quit_closure_)
      std::move(quit_closure_).Run();
  }

 private:
  base::OnceClosure quit_closure_;
};

}  // namespace

// A tester class that allows waiting for the first calculation to finish.
class TesterBrowsingTopicsService : public BrowsingTopicsServiceImpl {
 public:
  TesterBrowsingTopicsService(
      const base::FilePath& profile_path,
      privacy_sandbox::PrivacySandboxSettings* privacy_sandbox_settings,
      history::HistoryService* history_service,
      content::BrowsingTopicsSiteDataManager* site_data_manager,
      optimization_guide::PageContentAnnotationsService* annotations_service,
      base::OnceClosure calculation_finish_callback)
      : BrowsingTopicsServiceImpl(profile_path,
                                  privacy_sandbox_settings,
                                  history_service,
                                  site_data_manager,
                                  annotations_service),
        calculation_finish_callback_(std::move(calculation_finish_callback)) {}

  ~TesterBrowsingTopicsService() override = default;

  TesterBrowsingTopicsService(const TesterBrowsingTopicsService&) = delete;
  TesterBrowsingTopicsService& operator=(const TesterBrowsingTopicsService&) =
      delete;
  TesterBrowsingTopicsService(TesterBrowsingTopicsService&&) = delete;
  TesterBrowsingTopicsService& operator=(TesterBrowsingTopicsService&&) =
      delete;

  const BrowsingTopicsState& browsing_topics_state() override {
    return BrowsingTopicsServiceImpl::browsing_topics_state();
  }

  void OnCalculateBrowsingTopicsCompleted(EpochTopics epoch_topics) override {
    BrowsingTopicsServiceImpl::OnCalculateBrowsingTopicsCompleted(
        std::move(epoch_topics));

    if (calculation_finish_callback_)
      std::move(calculation_finish_callback_).Run();
  }

 private:
  base::OnceClosure calculation_finish_callback_;
};

class BrowsingTopicsBrowserTestBase : public InProcessBrowserTest {
 public:
  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
    https_server_.AddDefaultHandlers(GetChromeTestDataDir());

    content::SetupCrossSiteRedirector(&https_server_);
    ASSERT_TRUE(https_server_.Start());

    content::SetupCrossSiteRedirector(embedded_test_server());
    ASSERT_TRUE(embedded_test_server()->Start());
  }

  ~BrowsingTopicsBrowserTestBase() override = default;

  std::string InvokeTopicsAPI(const content::ToRenderFrameHost& adapter) {
    return EvalJs(adapter, R"(
      if (!(document.browsingTopics instanceof Function)) {
        'not a function';
      } else {
        document.browsingTopics()
        .then(topics => {
          let result = "[";
          for (const topic of topics) {
            result += JSON.stringify(topic, Object.keys(topic).sort()) + ";"
          }
          result += "]";
          return result;
        })
        .catch(error => error.message);
      }
    )")
        .ExtractString();
  }

  content::WebContents* web_contents() {
    return browser()->tab_strip_model()->GetActiveWebContents();
  }

 protected:
  net::EmbeddedTestServer https_server_{
      net::test_server::EmbeddedTestServer::TYPE_HTTPS};
};

class BrowsingTopicsDisabledBrowserTest : public BrowsingTopicsBrowserTestBase {
 public:
  BrowsingTopicsDisabledBrowserTest() {
    scoped_feature_list_.InitWithFeatures(
        /*enabled_features=*/{},
        /*disabled_features=*/{blink::features::kBrowsingTopics});
  }

 protected:
  base::test::ScopedFeatureList scoped_feature_list_;
};

IN_PROC_BROWSER_TEST_F(BrowsingTopicsDisabledBrowserTest,
                       NoBrowsingTopicsService) {
  EXPECT_FALSE(
      BrowsingTopicsServiceFactory::GetForProfile(browser()->profile()));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsDisabledBrowserTest, NoTopicsAPI) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/empty_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  EXPECT_EQ("not a function", InvokeTopicsAPI(web_contents()));
}

class BrowsingTopicsBrowserTest : public BrowsingTopicsBrowserTestBase {
 public:
  BrowsingTopicsBrowserTest()
      : prerender_helper_(
            base::BindRepeating(&BrowsingTopicsBrowserTest::web_contents,
                                base::Unretained(this))) {
    scoped_feature_list_.InitWithFeatures(
        /*enabled_features=*/
        {blink::features::kBrowsingTopics,
         blink::features::kBrowsingTopicsBypassIPIsPubliclyRoutableCheck,
         features::kPrivacySandboxAdsAPIsOverride, blink::features::kPortals},
        /*disabled_features=*/{});
  }

  ~BrowsingTopicsBrowserTest() override = default;

  void SetUpOnMainThread() override {
    prerender_helper_.SetUp(&https_server_);

    BrowsingTopicsBrowserTestBase::SetUpOnMainThread();

    for (auto& profile_and_calculation_finish_waiter :
         calculation_finish_waiters_) {
      profile_and_calculation_finish_waiter.second->Run();
    }
  }

  // BrowserTestBase::SetUpInProcessBrowserTestFixture
  void SetUpInProcessBrowserTestFixture() override {
    subscription_ =
        BrowserContextDependencyManager::GetInstance()
            ->RegisterCreateServicesCallbackForTesting(base::BindRepeating(
                &BrowsingTopicsBrowserTest::OnWillCreateBrowserContextServices,
                base::Unretained(this)));
  }

 protected:
  void ExpectResultTopicsEqual(
      const std::vector<TopicAndDomains>& result,
      std::vector<std::pair<Topic, std::set<HashedDomain>>> expected) {
    DCHECK_EQ(expected.size(), 5u);
    EXPECT_EQ(result.size(), 5u);

    for (int i = 0; i < 5; ++i) {
      EXPECT_EQ(result[i].topic(), expected[i].first);
      EXPECT_EQ(result[i].hashed_domains(), expected[i].second);
    }
  }

  HashedDomain GetHashedDomain(const std::string& domain) {
    return HashContextDomainForStorage(kTestKey, domain);
  }

  void CreateBrowsingTopicsStateFile(
      const base::FilePath& profile_path,
      const std::vector<EpochTopics>& epochs,
      base::Time next_scheduled_calculation_time) {
    base::Value::List epochs_list;
    for (const EpochTopics& epoch : epochs) {
      epochs_list.Append(epoch.ToDictValue());
    }

    base::Value::Dict dict;
    dict.Set("epochs", std::move(epochs_list));
    dict.Set("next_scheduled_calculation_time",
             base::TimeToValue(next_scheduled_calculation_time));
    dict.Set("hex_encoded_hmac_key", base::HexEncode(kTestKey));
    dict.Set("config_version", 1);

    JSONFileValueSerializer(
        profile_path.Append(FILE_PATH_LITERAL("BrowsingTopicsState")))
        .Serialize(dict);
  }

  content::BrowsingTopicsSiteDataManager* browsing_topics_site_data_manager() {
    return browser()
        ->profile()
        ->GetDefaultStoragePartition()
        ->GetBrowsingTopicsSiteDataManager();
  }

  TesterBrowsingTopicsService* browsing_topics_service() {
    return static_cast<TesterBrowsingTopicsService*>(
        BrowsingTopicsServiceFactory::GetForProfile(browser()->profile()));
  }

  const BrowsingTopicsState& browsing_topics_state() {
    return browsing_topics_service()->browsing_topics_state();
  }

  content::test::PrerenderTestHelper& prerender_helper() {
    return prerender_helper_;
  }

  std::vector<optimization_guide::WeightedIdentifier> TopicsAndWeight(
      const std::vector<int32_t>& topics,
      double weight) {
    std::vector<optimization_guide::WeightedIdentifier> result;
    for (int32_t topic : topics) {
      result.emplace_back(topic, weight);
    }

    return result;
  }

  void OnWillCreateBrowserContextServices(content::BrowserContext* context) {
    PageContentAnnotationsServiceFactory::GetInstance()->SetTestingFactory(
        context,
        base::BindRepeating(
            &BrowsingTopicsBrowserTest::CreatePageContentAnnotationsService,
            base::Unretained(this)));

    browsing_topics::BrowsingTopicsServiceFactory::GetInstance()
        ->SetTestingFactory(
            context,
            base::BindRepeating(
                &BrowsingTopicsBrowserTest::CreateBrowsingTopicsService,
                base::Unretained(this)));
  }

  std::unique_ptr<KeyedService> CreatePageContentAnnotationsService(
      content::BrowserContext* context) {
    Profile* profile = Profile::FromBrowserContext(context);

    history::HistoryService* history_service =
        HistoryServiceFactory::GetForProfile(
            profile, ServiceAccessType::IMPLICIT_ACCESS);

    DCHECK(!base::Contains(optimization_guide_model_providers_, profile));
    optimization_guide_model_providers_.emplace(
        profile, std::make_unique<
                     optimization_guide::TestOptimizationGuideModelProvider>());

    auto page_content_annotations_service =
        std::make_unique<optimization_guide::PageContentAnnotationsService>(
            "en-US", optimization_guide_model_providers_.at(profile).get(),
            history_service, nullptr, base::FilePath(), nullptr, nullptr);

    page_content_annotations_service->OverridePageContentAnnotatorForTesting(
        &test_page_content_annotator_);

    return page_content_annotations_service;
  }

  void InitializePreexistingState(
      history::HistoryService* history_service,
      content::BrowsingTopicsSiteDataManager* site_data_manager,
      const base::FilePath& profile_path) {
    // Configure the (mock) model.
    test_page_content_annotator_.UsePageTopics(
        *optimization_guide::TestModelInfoBuilder().SetVersion(1).Build(),
        {{"foo6.com", TopicsAndWeight({1, 2, 3, 4, 5, 6}, 0.1)},
         {"foo5.com", TopicsAndWeight({2, 3, 4, 5, 6}, 0.1)},
         {"foo4.com", TopicsAndWeight({3, 4, 5, 6}, 0.1)},
         {"foo3.com", TopicsAndWeight({4, 5, 6}, 0.1)},
         {"foo2.com", TopicsAndWeight({5, 6}, 0.1)},
         {"foo1.com", TopicsAndWeight({6}, 0.1)}});

    // Add some initial history.
    history::HistoryAddPageArgs add_page_args;
    add_page_args.time = base::Time::Now();
    add_page_args.context_id = reinterpret_cast<history::ContextID>(1);
    add_page_args.nav_entry_id = 1;

    // Note: foo6.com isn't in the initial history.
    for (int i = 1; i <= 5; ++i) {
      add_page_args.url =
          GURL(base::StrCat({"https://foo", base::NumberToString(i), ".com"}));
      history_service->AddPage(add_page_args);
      history_service->SetBrowsingTopicsAllowed(add_page_args.context_id,
                                                add_page_args.nav_entry_id,
                                                add_page_args.url);
    }

    // Add some API usage contexts data.
    site_data_manager->OnBrowsingTopicsApiUsed(
        HashMainFrameHostForStorage("foo1.com"), {HashedDomain(1)},
        base::Time::Now());

    // Initialize the `BrowsingTopicsState`.
    std::vector<EpochTopics> preexisting_epochs;
    preexisting_epochs.push_back(
        CreateTestEpochTopics({{Topic(1), {GetHashedDomain("a.test")}},
                               {Topic(2), {GetHashedDomain("a.test")}},
                               {Topic(3), {GetHashedDomain("a.test")}},
                               {Topic(4), {GetHashedDomain("a.test")}},
                               {Topic(5), {GetHashedDomain("a.test")}}},
                              kTime1));
    preexisting_epochs.push_back(
        CreateTestEpochTopics({{Topic(6), {GetHashedDomain("a.test")}},
                               {Topic(7), {GetHashedDomain("a.test")}},
                               {Topic(8), {GetHashedDomain("a.test")}},
                               {Topic(9), {GetHashedDomain("a.test")}},
                               {Topic(10), {GetHashedDomain("a.test")}}},
                              kTime2));

    CreateBrowsingTopicsStateFile(
        profile_path, std::move(preexisting_epochs),
        /*next_scheduled_calculation_time=*/base::Time::Now() - base::Days(1));
  }

  std::unique_ptr<KeyedService> CreateBrowsingTopicsService(
      content::BrowserContext* context) {
    Profile* profile = Profile::FromBrowserContext(context);

    privacy_sandbox::PrivacySandboxSettings* privacy_sandbox_settings =
        PrivacySandboxSettingsFactory::GetForProfile(profile);

    history::HistoryService* history_service =
        HistoryServiceFactory::GetForProfile(
            profile, ServiceAccessType::IMPLICIT_ACCESS);

    content::BrowsingTopicsSiteDataManager* site_data_manager =
        context->GetDefaultStoragePartition()
            ->GetBrowsingTopicsSiteDataManager();

    optimization_guide::PageContentAnnotationsService* annotations_service =
        PageContentAnnotationsServiceFactory::GetForProfile(profile);

    InitializePreexistingState(history_service, site_data_manager,
                               profile->GetPath());

    DCHECK(!base::Contains(calculation_finish_waiters_, profile));
    calculation_finish_waiters_.emplace(profile,
                                        std::make_unique<base::RunLoop>());

    if (!ukm_recorder_)
      ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();

    return std::make_unique<TesterBrowsingTopicsService>(
        profile->GetPath(), privacy_sandbox_settings, history_service,
        site_data_manager, annotations_service,
        calculation_finish_waiters_.at(profile)->QuitClosure());
  }

  content::test::FencedFrameTestHelper fenced_frame_test_helper_;

  content::test::PrerenderTestHelper prerender_helper_;

  base::test::ScopedFeatureList scoped_feature_list_;

  std::map<
      Profile*,
      std::unique_ptr<optimization_guide::TestOptimizationGuideModelProvider>>
      optimization_guide_model_providers_;

  std::map<Profile*, std::unique_ptr<base::RunLoop>>
      calculation_finish_waiters_;

  optimization_guide::TestPageContentAnnotator test_page_content_annotator_;

  std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_;

  base::CallbackListSubscription subscription_;
};

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, HasBrowsingTopicsService) {
  EXPECT_TRUE(browsing_topics_service());
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, NoServiceInIncognitoMode) {
  CreateIncognitoBrowser(browser()->profile());

  EXPECT_TRUE(browser()->profile()->HasPrimaryOTRProfile());

  Profile* incognito_profile =
      browser()->profile()->GetPrimaryOTRProfile(/*create_if_needed=*/false);
  EXPECT_TRUE(incognito_profile);

  BrowsingTopicsService* incognito_browsing_topics_service =
      BrowsingTopicsServiceFactory::GetForProfile(incognito_profile);
  EXPECT_FALSE(incognito_browsing_topics_service);
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, BrowsingTopicsStateOnStart) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/empty_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  base::Time now = base::Time::Now();

  EXPECT_EQ(browsing_topics_state().epochs().size(), 3u);
  EXPECT_EQ(browsing_topics_state().epochs()[0].calculation_time(), kTime1);
  EXPECT_EQ(browsing_topics_state().epochs()[1].calculation_time(), kTime2);
  EXPECT_GT(browsing_topics_state().epochs()[2].calculation_time(),
            now - base::Minutes(1));
  EXPECT_LT(browsing_topics_state().epochs()[2].calculation_time(), now);

  ExpectResultTopicsEqual(
      browsing_topics_state().epochs()[0].top_topics_and_observing_domains(),
      {{Topic(1), {GetHashedDomain("a.test")}},
       {Topic(2), {GetHashedDomain("a.test")}},
       {Topic(3), {GetHashedDomain("a.test")}},
       {Topic(4), {GetHashedDomain("a.test")}},
       {Topic(5), {GetHashedDomain("a.test")}}});

  ExpectResultTopicsEqual(
      browsing_topics_state().epochs()[1].top_topics_and_observing_domains(),
      {{Topic(6), {GetHashedDomain("a.test")}},
       {Topic(7), {GetHashedDomain("a.test")}},
       {Topic(8), {GetHashedDomain("a.test")}},
       {Topic(9), {GetHashedDomain("a.test")}},
       {Topic(10), {GetHashedDomain("a.test")}}});

  ExpectResultTopicsEqual(
      browsing_topics_state().epochs()[2].top_topics_and_observing_domains(),
      {{Topic(6), {HashedDomain(1)}},
       {Topic(5), {}},
       {Topic(4), {}},
       {Topic(3), {}},
       {Topic(2), {}}});

  EXPECT_GT(browsing_topics_state().next_scheduled_calculation_time(),
            now + base::Days(7) - base::Minutes(1));
  EXPECT_LT(browsing_topics_state().next_scheduled_calculation_time(),
            now + base::Days(7));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, CalculationResultUkm) {
  auto entries = ukm_recorder_->GetEntriesByName(
      ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::kEntryName);

  // The number of entries should equal the number of profiles, which could be
  // greater than 1 on some platform.
  EXPECT_EQ(optimization_guide_model_providers_.size(), entries.size());

  for (auto* entry : entries) {
    ukm_recorder_->ExpectEntryMetric(
        entry,
        ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
            kTopTopic0Name,
        6);
    ukm_recorder_->ExpectEntryMetric(
        entry,
        ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
            kTopTopic1Name,
        5);
    ukm_recorder_->ExpectEntryMetric(
        entry,
        ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
            kTopTopic2Name,
        4);
    ukm_recorder_->ExpectEntryMetric(
        entry,
        ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
            kTopTopic3Name,
        3);
    ukm_recorder_->ExpectEntryMetric(
        entry,
        ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
            kTopTopic4Name,
        2);
    ukm_recorder_->ExpectEntryMetric(
        entry,
        ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
            kTaxonomyVersionName,
        1);
    ukm_recorder_->ExpectEntryMetric(
        entry,
        ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
            kModelVersionName,
        1);
    ukm_recorder_->ExpectEntryMetric(
        entry,
        ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
            kPaddedTopicsStartIndexName,
        5);
  }
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, ApiResultUkm) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  InvokeTopicsAPI(web_contents());

  auto entries = ukm_recorder_->GetEntriesByName(
      ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
          kEntryName);
  EXPECT_EQ(1u, entries.size());

  ukm_recorder_->ExpectEntrySourceHasUrl(entries.back(), main_frame_url);

  const int64_t* topic0_metric = ukm_recorder_->GetEntryMetric(
      entries.back(),
      ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
          kReturnedTopic0Name);
  const int64_t* topic1_metric = ukm_recorder_->GetEntryMetric(
      entries.back(),
      ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
          kReturnedTopic1Name);

  EXPECT_TRUE(topic0_metric);
  EXPECT_TRUE(topic1_metric);

  EXPECT_TRUE((*topic0_metric == kExpectedTopic1.value() &&
               *topic1_metric == kExpectedTopic2.value()) ||
              (*topic0_metric == kExpectedTopic2.value() &&
               *topic1_metric == kExpectedTopic1.value()));

  ukm_recorder_->ExpectEntryMetric(
      entries.back(),
      ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
          kReturnedTopic0IsTrueTopTopicName,
      true);
  ukm_recorder_->ExpectEntryMetric(
      entries.back(),
      ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
          kReturnedTopic0ModelVersionName,
      2);
  ukm_recorder_->ExpectEntryMetric(
      entries.back(),
      ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
          kReturnedTopic0TaxonomyVersionName,
      1);

  ukm_recorder_->ExpectEntryMetric(
      entries.back(),
      ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
          kReturnedTopic1IsTrueTopTopicName,
      true);
  ukm_recorder_->ExpectEntryMetric(
      entries.back(),
      ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
          kReturnedTopic1ModelVersionName,
      2);
  ukm_recorder_->ExpectEntryMetric(
      entries.back(),
      ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
          kReturnedTopic1TaxonomyVersionName,
      1);

  EXPECT_FALSE(ukm_recorder_->GetEntryMetric(
      entries.back(),
      ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
          kReturnedTopic2Name));
  EXPECT_FALSE(ukm_recorder_->GetEntryMetric(
      entries.back(),
      ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
          kEmptyReasonName));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, PageLoadUkm) {
  // The test assumes pages gets deleted after navigation, triggering metrics
  // recording. Disable back/forward cache to ensure that pages don't get
  // preserved in the cache.
  content::DisableBackForwardCacheForTesting(
      web_contents(), content::BackForwardCache::TEST_REQUIRES_NO_CACHING);

  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  InvokeTopicsAPI(web_contents());

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

  auto entries = ukm_recorder_->GetEntriesByName(
      ukm::builders::BrowsingTopics_PageLoad::kEntryName);
  EXPECT_EQ(1u, entries.size());

  ukm_recorder_->ExpectEntrySourceHasUrl(entries.back(), main_frame_url);

  ukm_recorder_->ExpectEntryMetric(entries.back(),
                                   ukm::builders::BrowsingTopics_PageLoad::
                                       kTopicsRequestingContextDomainsCountName,
                                   1);
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, GetTopicsForSiteForDisplay) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/empty_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  std::vector<privacy_sandbox::CanonicalTopic> result =
      browsing_topics_service()->GetTopicsForSiteForDisplay(
          web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());

  // Epoch switch time has not arrived. So expect one topic from each of the
  // first two epochs.
  EXPECT_EQ(result.size(), 2u);
  EXPECT_EQ(result[0].topic_id(), Topic(1));
  EXPECT_EQ(result[0].taxonomy_version(), 1);
  EXPECT_EQ(result[1].topic_id(), Topic(10));
  EXPECT_EQ(result[1].taxonomy_version(), 1);
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, GetTopTopicsForDisplay) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/empty_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  std::vector<privacy_sandbox::CanonicalTopic> result =
      browsing_topics_service()->GetTopTopicsForDisplay();

  EXPECT_EQ(result.size(), 15u);
  EXPECT_EQ(result[0].topic_id(), Topic(1));
  EXPECT_EQ(result[1].topic_id(), Topic(2));
  EXPECT_EQ(result[2].topic_id(), Topic(3));
  EXPECT_EQ(result[3].topic_id(), Topic(4));
  EXPECT_EQ(result[4].topic_id(), Topic(5));
  EXPECT_EQ(result[5].topic_id(), Topic(6));
  EXPECT_EQ(result[6].topic_id(), Topic(7));
  EXPECT_EQ(result[7].topic_id(), Topic(8));
  EXPECT_EQ(result[8].topic_id(), Topic(9));
  EXPECT_EQ(result[9].topic_id(), Topic(10));
  EXPECT_EQ(result[10].topic_id(), Topic(6));
  EXPECT_EQ(result[11].topic_id(), Topic(5));
  EXPECT_EQ(result[12].topic_id(), Topic(4));
  EXPECT_EQ(result[13].topic_id(), Topic(3));
  EXPECT_EQ(result[14].topic_id(), Topic(2));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
                       TopicsAPI_ContextDomainNotFiltered_FromMainFrame) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  std::string result = InvokeTopicsAPI(web_contents());

  EXPECT_TRUE(result == kExpectedResultOrder1 ||
              result == kExpectedResultOrder2);

  // Ensure access has been reported to the Page Specific Content Settings.
  auto* pscs = content_settings::PageSpecificContentSettings::GetForPage(
      web_contents()->GetPrimaryPage());
  EXPECT_TRUE(pscs->HasAccessedTopics());
  auto topics = pscs->GetAccessedTopics();
  ASSERT_EQ(2u, topics.size());

  // No ordering is enforced by the PSCS.
  ASSERT_NE(topics[0].topic_id(), topics[1].topic_id());
  ASSERT_TRUE(topics[0].topic_id() == kExpectedTopic1 ||
              topics[0].topic_id() == kExpectedTopic2);
  ASSERT_TRUE(topics[1].topic_id() == kExpectedTopic1 ||
              topics[1].topic_id() == kExpectedTopic2);
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
                       TopicsAPI_ContextDomainNotFiltered_FromSubframe) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  GURL subframe_url =
      https_server_.GetURL("a.test", "/browsing_topics/empty_page.html");

  ASSERT_TRUE(content::NavigateIframeToURL(web_contents(),
                                           /*iframe_id=*/"frame",
                                           subframe_url));

  std::string result = InvokeTopicsAPI(
      content::ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0));

  EXPECT_TRUE(result == kExpectedResultOrder1 ||
              result == kExpectedResultOrder2);
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
                       TopicsAPI_ContextDomainFiltered) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  GURL subframe_url =
      https_server_.GetURL("b.test", "/browsing_topics/empty_page.html");

  ASSERT_TRUE(content::NavigateIframeToURL(web_contents(),
                                           /*iframe_id=*/"frame",
                                           subframe_url));

  // b.test has yet to call the API so it shouldn't receive a topic.
  EXPECT_EQ("[]", InvokeTopicsAPI(content::ChildFrameAt(
                      web_contents()->GetPrimaryMainFrame(), 0)));
  auto* pscs = content_settings::PageSpecificContentSettings::GetForPage(
      web_contents()->GetPrimaryPage());
  EXPECT_FALSE(pscs->HasAccessedTopics());
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
                       TopicsAPI_ContextDomainTracked) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  GURL subframe_url =
      https_server_.GetURL("b.test", "/browsing_topics/empty_page.html");

  ASSERT_TRUE(content::NavigateIframeToURL(web_contents(),
                                           /*iframe_id=*/"frame",
                                           subframe_url));

  // The usage is not tracked before the API call. The returned entry was from
  // the pre-existing storage.
  std::vector<ApiUsageContext> api_usage_contexts =
      content::GetBrowsingTopicsApiUsage(browsing_topics_site_data_manager());
  EXPECT_EQ(api_usage_contexts.size(), 1u);

  EXPECT_EQ("[]", InvokeTopicsAPI(content::ChildFrameAt(
                      web_contents()->GetPrimaryMainFrame(), 0)));

  api_usage_contexts =
      content::GetBrowsingTopicsApiUsage(browsing_topics_site_data_manager());

  // The usage is tracked after the API call.
  EXPECT_EQ(api_usage_contexts.size(), 2u);
  EXPECT_EQ(api_usage_contexts[0].hashed_main_frame_host,
            HashMainFrameHostForStorage("foo1.com"));
  EXPECT_EQ(api_usage_contexts[0].hashed_context_domain, HashedDomain(1));

  EXPECT_EQ(
      api_usage_contexts[1].hashed_main_frame_host,
      HashMainFrameHostForStorage(https_server_.GetURL("a.test", "/").host()));
  EXPECT_EQ(api_usage_contexts[1].hashed_context_domain,
            GetHashedDomain("b.test"));
}

IN_PROC_BROWSER_TEST_F(
    BrowsingTopicsBrowserTest,
    EmptyPage_PermissionsPolicyBrowsingTopicsNone_TopicsAPI) {
  GURL main_frame_url = https_server_.GetURL(
      "a.test", "/browsing_topics/empty_page_browsing_topics_none.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  EXPECT_EQ(
      "The \"browsing-topics\" Permissions Policy denied the use of "
      "document.browsingTopics().",
      InvokeTopicsAPI(web_contents()));
}

IN_PROC_BROWSER_TEST_F(
    BrowsingTopicsBrowserTest,
    EmptyPage_PermissionsPolicyInterestCohortNone_TopicsAPI) {
  GURL main_frame_url = https_server_.GetURL(
      "a.test", "/browsing_topics/empty_page_interest_cohort_none.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  EXPECT_EQ(
      "The \"interest-cohort\" Permissions Policy denied the use of "
      "document.browsingTopics().",
      InvokeTopicsAPI(web_contents()));
}

IN_PROC_BROWSER_TEST_F(
    BrowsingTopicsBrowserTest,
    OneIframePage_SubframePermissionsPolicyBrowsingTopicsNone_TopicsAPI) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  GURL subframe_url = https_server_.GetURL(
      "a.test", "/browsing_topics/empty_page_browsing_topics_none.html");

  ASSERT_TRUE(content::NavigateIframeToURL(web_contents(),
                                           /*iframe_id=*/"frame",
                                           subframe_url));

  std::string result = InvokeTopicsAPI(web_contents());
  EXPECT_TRUE(result == kExpectedResultOrder1 ||
              result == kExpectedResultOrder2);

  EXPECT_EQ(
      "The \"browsing-topics\" Permissions Policy denied the use of "
      "document.browsingTopics().",
      InvokeTopicsAPI(
          content::ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0)));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
                       PermissionsPolicyAllowCertainOrigin_TopicsAPI) {
  base::StringPairs port_replacement;
  port_replacement.push_back(
      std::make_pair("{{PORT}}", base::NumberToString(https_server_.port())));

  GURL main_frame_url = https_server_.GetURL(
      "a.test", net::test_server::GetFilePathWithReplacements(
                    "/browsing_topics/"
                    "one_iframe_page_browsing_topics_allow_certain_origin.html",
                    port_replacement));

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  std::string result = InvokeTopicsAPI(web_contents());
  EXPECT_TRUE(result == kExpectedResultOrder1 ||
              result == kExpectedResultOrder2);

  GURL subframe_url =
      https_server_.GetURL("c.test", "/browsing_topics/empty_page.html");

  ASSERT_TRUE(content::NavigateIframeToURL(web_contents(),
                                           /*iframe_id=*/"frame",
                                           subframe_url));
  EXPECT_EQ("[]", InvokeTopicsAPI(content::ChildFrameAt(
                      web_contents()->GetPrimaryMainFrame(), 0)));

  subframe_url =
      https_server_.GetURL("b.test", "/browsing_topics/empty_page.html");

  ASSERT_TRUE(content::NavigateIframeToURL(web_contents(),
                                           /*iframe_id=*/"frame",
                                           subframe_url));

  EXPECT_EQ(
      "The \"browsing-topics\" Permissions Policy denied the use of "
      "document.browsingTopics().",
      InvokeTopicsAPI(
          content::ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0)));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
                       TopicsAPINotAllowedInInsecureContext) {
  GURL main_frame_url = embedded_test_server()->GetURL(
      "a.test", "/browsing_topics/one_iframe_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  // Navigate the iframe to a https site.
  GURL subframe_url = https_server_.GetURL("b.test", "/empty_page.html");
  content::NavigateIframeToURL(web_contents(),
                               /*iframe_id=*/"frame", subframe_url);

  // Both the main frame and the subframe are insecure context because the main
  // frame is loaded over HTTP. Expect that the API isn't available in either
  // frame.
  EXPECT_EQ("not a function", InvokeTopicsAPI(web_contents()));
  EXPECT_EQ("not a function", InvokeTopicsAPI(content::ChildFrameAt(
                                  web_contents()->GetPrimaryMainFrame(), 0)));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
                       TopicsAPINotAllowedInDetachedDocument) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  EXPECT_EQ(
      "Failed to execute 'browsingTopics' on 'Document': A browsing "
      "context is required when calling document.browsingTopics().",
      EvalJs(web_contents(), R"(
      const iframe = document.getElementById('frame');
      const childDocument = iframe.contentWindow.document;
      iframe.remove();

      childDocument.browsingTopics()
        .then(topics => "success")
        .catch(error => error.message);
    )"));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
                       TopicsAPINotAllowedInOpaqueOriginDocument) {
  GURL main_frame_url = https_server_.GetURL(
      "a.test", "/browsing_topics/one_sandboxed_iframe_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  EXPECT_EQ(
      "document.browsingTopics() is not allowed in an opaque origin context.",
      InvokeTopicsAPI(
          content::ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0)));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
                       TopicsAPINotAllowedInFencedFrame) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  GURL fenced_frame_url =
      https_server_.GetURL("b.test", "/fenced_frames/title1.html");

  content::RenderFrameHostWrapper fenced_frame_rfh_wrapper(
      fenced_frame_test_helper_.CreateFencedFrame(
          web_contents()->GetPrimaryMainFrame(), fenced_frame_url));

  EXPECT_EQ("document.browsingTopics() is not allowed in a fenced frame.",
            InvokeTopicsAPI(fenced_frame_rfh_wrapper.get()));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
                       TopicsAPINotAllowedInPrerenderedPage) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  GURL prerender_url =
      https_server_.GetURL("a.test", "/browsing_topics/empty_page.html");

  int host_id = prerender_helper().AddPrerender(prerender_url);

  content::RenderFrameHost* prerender_host =
      prerender_helper().GetPrerenderedMainFrameHost(host_id);
  EXPECT_EQ(
      "document.browsingTopics() is not allowed when the page is being "
      "prerendered.",
      InvokeTopicsAPI(prerender_host));

  // Activate the prerendered page. The API call should succeed.
  content::test::PrerenderHostObserver prerender_observer(*web_contents(),
                                                          prerender_url);
  prerender_helper().NavigatePrimaryPage(prerender_url);
  prerender_observer.WaitForActivation();

  std::string result = InvokeTopicsAPI(web_contents());

  EXPECT_TRUE(result == kExpectedResultOrder1 ||
              result == kExpectedResultOrder2);
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, TopicsAPINotAllowedInPortal) {
  GURL main_frame_url =
      https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  GURL portal_url =
      https_server_.GetURL("a.test", "/browsing_topics/empty_page.html");

  ASSERT_EQ(true, content::EvalJs(web_contents()->GetPrimaryMainFrame(),
                                  content::JsReplace(R"(
                          new Promise((resolve) => {
                            let portal = document.createElement('portal');
                            portal.src = $1;
                            portal.onload = () => { resolve(true); }
                            document.body.appendChild(portal);
                          });
                          )",
                                                     portal_url)));

  std::vector<content::WebContents*> inner_web_contents =
      web_contents()->GetInnerWebContents();
  EXPECT_EQ(1u, inner_web_contents.size());
  content::WebContents* portal_contents = inner_web_contents[0];

  EXPECT_EQ(
      "document.browsingTopics() is only allowed in the outermost page and "
      "when the page is active.",
      InvokeTopicsAPI(portal_contents));

  // Activate the portal. The API call should succeed.
  PortalActivationWaiter activation_waiter(portal_contents);
  content::ExecuteScriptAsync(web_contents()->GetPrimaryMainFrame(),
                              "document.querySelector('portal').activate();");
  activation_waiter.Wait();

  EXPECT_EQ(portal_contents, web_contents());

  std::string result = InvokeTopicsAPI(web_contents());

  EXPECT_TRUE(result == kExpectedResultOrder1 ||
              result == kExpectedResultOrder2);
}

// Regression test for crbug/1339735.
IN_PROC_BROWSER_TEST_F(
    BrowsingTopicsBrowserTest,
    TopicsAPIInvokedInMainFrameUnloadHandler_NoRendererCrash) {
  GURL main_frame_url = https_server_.GetURL(
      "a.test", "/browsing_topics/get_topics_during_unload.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

  // A renderer crash won't always be captured if the renderer is also shutting
  // down naturally around the same time. Thus, we create a new page in the same
  // renderer process to keep the renderer process alive when the page navigates
  // away later.
  content::TestNavigationObserver popup_observer(main_frame_url);
  popup_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(
      ExecuteScript(web_contents()->GetPrimaryMainFrame(),
                    content::JsReplace("window.open($1)", main_frame_url)));
  popup_observer.Wait();

  GURL new_url =
      https_server_.GetURL("b.test", "/browsing_topics/empty_page.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), new_url));
}

}  // namespace browsing_topics
