// 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 "content/browser/browsing_topics/header_util.h"

#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/web_contents_tester.h"
#include "content/test/test_render_view_host.h"
#include "services/network/public/mojom/parsed_headers.mojom.h"

namespace content {

namespace {

blink::mojom::EpochTopicPtr CreateMojomTopic(int topic,
                                             const std::string& model_version) {
  auto mojom_topic = blink::mojom::EpochTopic::New();
  mojom_topic->topic = topic;
  mojom_topic->config_version = "chrome.1";
  mojom_topic->taxonomy_version = "1";
  mojom_topic->model_version = model_version;
  mojom_topic->version = base::StrCat({mojom_topic->config_version, ":",
                                       mojom_topic->taxonomy_version, ":",
                                       mojom_topic->model_version});
  return mojom_topic;
}

class TopicsInterceptingContentBrowserClient : public ContentBrowserClient {
 public:
  bool HandleTopicsWebApi(
      const url::Origin& context_origin,
      content::RenderFrameHost* main_frame,
      browsing_topics::ApiCallerSource caller_source,
      bool get_topics,
      bool observe,
      std::vector<blink::mojom::EpochTopicPtr>& topics) override {
    handle_topics_web_api_called_ = true;
    last_get_topics_param_ = get_topics;
    last_observe_param_ = observe;
    return true;
  }

  int NumVersionsInTopicsEpochs(
      content::RenderFrameHost* main_frame) const override {
    return 1;
  }

  bool handle_topics_web_api_called() const {
    return handle_topics_web_api_called_;
  }

  bool last_get_topics_param() const { return last_get_topics_param_; }

  bool last_observe_param() const { return last_observe_param_; }

 private:
  bool handle_topics_web_api_called_ = false;
  bool last_get_topics_param_ = false;
  bool last_observe_param_ = false;
};

}  // namespace

class BrowsingTopicsUtilTest : public RenderViewHostTestHarness {
 public:
  void SetUp() override {
    content::RenderViewHostTestHarness::SetUp();

    original_client_ = content::SetBrowserClientForTesting(&browser_client_);

    GURL url("https://foo.com");
    auto simulator =
        NavigationSimulator::CreateBrowserInitiated(url, web_contents());
    simulator->Commit();
  }

  void TearDown() override {
    SetBrowserClientForTesting(original_client_);

    content::RenderViewHostTestHarness::TearDown();
  }

  const TopicsInterceptingContentBrowserClient& browser_client() const {
    return browser_client_;
  }

 private:
  TopicsInterceptingContentBrowserClient browser_client_;
  raw_ptr<ContentBrowserClient> original_client_ = nullptr;
};

TEST_F(BrowsingTopicsUtilTest,
       DeriveTopicsHeaderValue_EmptyTopics_ZeroVersionInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/0);
  EXPECT_EQ(header_value, "();p=P0000000000000000000000000000000");
}

TEST_F(BrowsingTopicsUtilTest,
       DeriveTopicsHeaderValue_EmptyTopics_OneVersionInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1);
  EXPECT_EQ(header_value, "();p=P0000000000000000000000000000000");
}

TEST_F(BrowsingTopicsUtilTest,
       DeriveTopicsHeaderValue_EmptyTopics_TwoVersionsInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2);
  EXPECT_EQ(header_value,
            "();p=P00000000000000000000000000000000000000000000000000");
}

TEST_F(BrowsingTopicsUtilTest,
       DeriveTopicsHeaderValue_EmptyTopics_ThreeVersionsInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/3);
  EXPECT_EQ(
      header_value,
      "();p="
      "P000000000000000000000000000000000000000000000000000000000000000000000");
}

TEST_F(BrowsingTopicsUtilTest,
       DeriveTopicsHeaderValue_OneTopic_OneVersionInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(1, /*model_version=*/"2"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1);

  EXPECT_EQ(header_value, "(1);v=chrome.1:1:2, ();p=P00000000000");
}

TEST_F(BrowsingTopicsUtilTest,
       DeriveTopicsHeaderValue_OneTopic_TwoVersionsInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(1, /*model_version=*/"2"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2);

  EXPECT_EQ(header_value,
            "(1);v=chrome.1:1:2, ();p=P000000000000000000000000000000");
}

TEST_F(BrowsingTopicsUtilTest,
       DeriveTopicsHeaderValue_OneTopic_ThreeVersionsInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(1, /*model_version=*/"2"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/3);

  EXPECT_EQ(header_value,
            "(1);v=chrome.1:1:2, "
            "();p=P0000000000000000000000000000000000000000000000000");
}

TEST_F(BrowsingTopicsUtilTest,
       DeriveTopicsHeaderValue_OneThreeDigitTopic_OneVersionInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(123,
                                    /*model_version=*/"2"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1);

  EXPECT_EQ(header_value, "(123);v=chrome.1:1:2, ();p=P000000000");
}

TEST_F(BrowsingTopicsUtilTest,
       DeriveTopicsHeaderValue_TwoTopics_SameTopicVersions_OneVersionInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(1, /*model_version=*/"2"));
  topics.push_back(CreateMojomTopic(2, /*model_version=*/"2"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1);

  EXPECT_EQ(header_value, "(1 2);v=chrome.1:1:2, ();p=P000000000");
}

TEST_F(
    BrowsingTopicsUtilTest,
    DeriveTopicsHeaderValue_TwoMixedDigitsTopics_SameTopicVersions_OneVersionInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(123, /*model_version=*/"2"));
  topics.push_back(CreateMojomTopic(45, /*model_version=*/"2"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1);

  EXPECT_EQ(header_value, "(123 45);v=chrome.1:1:2, ();p=P000000");
}

TEST_F(
    BrowsingTopicsUtilTest,
    DeriveTopicsHeaderValue_TwoTopics_SameTopicVersions_TwoVersionsInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(1, /*model_version=*/"2"));
  topics.push_back(CreateMojomTopic(2, /*model_version=*/"2"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2);

  EXPECT_EQ(header_value,
            "(1 2);v=chrome.1:1:2, ();p=P0000000000000000000000000000");
}

TEST_F(
    BrowsingTopicsUtilTest,
    DeriveTopicsHeaderValue_TwoTopics_DifferentTopicVersions_TwoVersionsInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(1, /*model_version=*/"2"));
  topics.push_back(CreateMojomTopic(1, /*model_version=*/"4"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2);

  EXPECT_EQ(header_value,
            "(1);v=chrome.1:1:2, (1);v=chrome.1:1:4, ();p=P0000000000");
}

TEST_F(
    BrowsingTopicsUtilTest,
    DeriveTopicsHeaderValue_TwoTopics_DifferentTopicVersions_ThreeVersionsInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(1, /*model_version=*/"2"));
  topics.push_back(CreateMojomTopic(1, /*model_version=*/"4"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/3);
  EXPECT_EQ(header_value,
            "(1);v=chrome.1:1:2, (1);v=chrome.1:1:4, "
            "();p=P00000000000000000000000000000");
}

TEST_F(
    BrowsingTopicsUtilTest,
    DeriveTopicsHeaderValue_ThreeTopics_SameTopicVersions_OneVersionInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(1, /*model_version=*/"2"));
  topics.push_back(CreateMojomTopic(2, /*model_version=*/"2"));
  topics.push_back(CreateMojomTopic(3, /*model_version=*/"2"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1);

  EXPECT_EQ(header_value, "(1 2 3);v=chrome.1:1:2, ();p=P0000000");
}

TEST_F(
    BrowsingTopicsUtilTest,
    DeriveTopicsHeaderValue_ThreeThreeDigitsTopics_SameTopicVersions_OneVersionInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(100, /*model_version=*/"20"));
  topics.push_back(CreateMojomTopic(200, /*model_version=*/"20"));
  topics.push_back(CreateMojomTopic(300, /*model_version=*/"20"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1);

  EXPECT_EQ(header_value, "(100 200 300);v=chrome.1:1:20, ();p=P");
}

TEST_F(
    BrowsingTopicsUtilTest,
    DeriveTopicsHeaderValue_ThreeThreeDigitsTopics_FirstTwoTopicVersionsSame_TwoVersionsInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(100, /*model_version=*/"2"));
  topics.push_back(CreateMojomTopic(200, /*model_version=*/"2"));
  topics.push_back(CreateMojomTopic(300, /*model_version=*/"4"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2);

  EXPECT_EQ(header_value,
            "(100 200);v=chrome.1:1:2, (300);v=chrome.1:1:4, ();p=P00");
}

TEST_F(
    BrowsingTopicsUtilTest,
    DeriveTopicsHeaderValue_ThreeThreeDigitsTopics_LastTwoTopicVersionsSame_TwoVersionsInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(100, /*model_version=*/"2"));
  topics.push_back(CreateMojomTopic(200, /*model_version=*/"4"));
  topics.push_back(CreateMojomTopic(300, /*model_version=*/"4"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2);

  EXPECT_EQ(header_value,
            "(100);v=chrome.1:1:2, (200 300);v=chrome.1:1:4, ();p=P00");
}

TEST_F(BrowsingTopicsUtilTest,
       DeriveTopicsHeaderValue_ThreeThreeDigitsTopics_ThreeTopicVersions) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(100, /*model_version=*/"20"));
  topics.push_back(CreateMojomTopic(200, /*model_version=*/"40"));
  topics.push_back(CreateMojomTopic(300, /*model_version=*/"60"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/3);

  EXPECT_EQ(header_value,
            "(100);v=chrome.1:1:20, (200);v=chrome.1:1:40, "
            "(300);v=chrome.1:1:60, ();p=P");
}

TEST_F(
    BrowsingTopicsUtilTest,
    DeriveTopicsHeaderValue_InconsistentNumTopicsVersionsAndNumVersionsInEpochs) {
  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(100, /*model_version=*/"20"));
  topics.push_back(CreateMojomTopic(200, /*model_version=*/"40"));
  topics.push_back(CreateMojomTopic(300, /*model_version=*/"60"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2);

  EXPECT_EQ(header_value,
            "(100);v=chrome.1:1:20, (200);v=chrome.1:1:40, "
            "(300);v=chrome.1:1:60, ();p=P");
}

TEST_F(BrowsingTopicsUtilTest,
       DeriveTopicsHeaderValue_LengthExceedsDefaultMax_NoPadding) {
  std::string config_version = base::StrCat(
      {"chrome.",
       base::NumberToString(browsing_topics::ConfigVersion::kMaxValue)});
  std::string taxonomy_version = base::NumberToString(
      blink::features::kBrowsingTopicsTaxonomyVersion.Get());

  std::vector<blink::mojom::EpochTopicPtr> topics;
  topics.push_back(CreateMojomTopic(100, /*model_version=*/"20"));
  topics.push_back(CreateMojomTopic(200, /*model_version=*/"40"));
  topics.push_back(CreateMojomTopic(300, /*model_version=*/"600"));

  std::string header_value =
      DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/3);

  EXPECT_EQ(header_value,
            "(100);v=chrome.1:1:20, (200);v=chrome.1:1:40, "
            "(300);v=chrome.1:1:600, ();p=P");
}

TEST_F(BrowsingTopicsUtilTest,
       HandleTopicsEligibleResponse_TrueValueObserveTopicsHeader) {
  network::mojom::ParsedHeadersPtr parsed_headers =
      network::mojom::ParsedHeaders::New();
  parsed_headers->observe_browsing_topics = true;
  HandleTopicsEligibleResponse(
      parsed_headers,
      /*caller_origin=*/url::Origin::Create(GURL("https://bar.com")),
      *web_contents()->GetPrimaryMainFrame(),
      browsing_topics::ApiCallerSource::kFetch);

  EXPECT_TRUE(browser_client().handle_topics_web_api_called());
  EXPECT_FALSE(browser_client().last_get_topics_param());
  EXPECT_TRUE(browser_client().last_observe_param());
}

TEST_F(BrowsingTopicsUtilTest,
       HandleTopicsEligibleResponse_FalseValueObserveTopicsHeader) {
  network::mojom::ParsedHeadersPtr parsed_headers =
      network::mojom::ParsedHeaders::New();
  parsed_headers->observe_browsing_topics = false;
  HandleTopicsEligibleResponse(
      parsed_headers,
      /*caller_origin=*/url::Origin::Create(GURL("https://bar.com")),
      *web_contents()->GetPrimaryMainFrame(),
      browsing_topics::ApiCallerSource::kFetch);

  EXPECT_FALSE(browser_client().handle_topics_web_api_called());
}

TEST_F(BrowsingTopicsUtilTest, HandleTopicsEligibleResponse_InactiveFrame) {
  network::mojom::ParsedHeadersPtr parsed_headers =
      network::mojom::ParsedHeaders::New();
  parsed_headers->observe_browsing_topics = true;
  RenderFrameHostImpl& rfh =
      static_cast<RenderFrameHostImpl&>(*web_contents()->GetPrimaryMainFrame());
  rfh.SetLifecycleState(
      RenderFrameHostImpl::LifecycleStateImpl::kReadyToBeDeleted);

  HandleTopicsEligibleResponse(
      parsed_headers,
      /*caller_origin=*/url::Origin::Create(GURL("https://bar.com")), rfh,
      browsing_topics::ApiCallerSource::kFetch);

  EXPECT_FALSE(browser_client().handle_topics_web_api_called());
}

}  // namespace content
