// 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 "components/browsing_topics/common/common_types.h"
#include "components/browsing_topics/common/semantic_tree.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/page.h"
#include "content/public/common/content_client.h"
#include "net/http/http_request_headers.h"
#include "net/http/structured_headers.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"

namespace content {

namespace {

// The max number of digits in a topic. As new taxonomies are introduced and old
// topics are expired, the expectation is this value will gradually grow.
constexpr int kTopicMaxLength = 3;

// The number of characters in a version string, e.g., chrome.1:1:10. This will
// grow as versions require more digits.
constexpr int kVersionMaxLength = 13;

static_assert(browsing_topics::ConfigVersion::kMaxValue < 10,
              "Topics config version should not exceed 1 digit, or "
              "`kVersionMaxLength` should be updated accordingly.");

static_assert(blink::features::kBrowsingTopicsTaxonomyVersionDefault < 10,
              "Topics taxonomy version should not exceed 1 digit, or "
              "`kVersionMaxLength` should be updated accordingly.");

static_assert(browsing_topics::SemanticTree::kNumTopics < 1000,
              "Total number of topics (i.e. max topic ID) should not exceed 3 "
              "digits, or `kTopicMaxLength` should be updated accordingly.");

}  // namespace

std::string DeriveTopicsHeaderValue(
    const std::vector<blink::mojom::EpochTopicPtr>& topics,
    int num_versions_in_epochs) {
  net::structured_headers::List header_list;
  std::optional<std::string> last_version;
  std::vector<net::structured_headers::ParameterizedItem> cur_topics;

  // Build up the header without the padding parameter.
  for (auto& topic : topics) {
    bool new_version =
        (!last_version.has_value() || last_version.value() != topic->version);
    if (new_version) {
      if (cur_topics.size() > 0) {
        CHECK(last_version.has_value());
        header_list.push_back(net::structured_headers::ParameterizedMember(
            cur_topics,
            {{"v",
              net::structured_headers::Item(
                  *last_version, net::structured_headers::Item::kTokenType)}}));
        cur_topics.clear();
      }
      last_version = topic->version;
    }
    cur_topics.push_back(net::structured_headers::ParameterizedItem(
        net::structured_headers::Item(static_cast<int64_t>(topic->topic)), {}));
  }

  if (cur_topics.size() > 0) {
    CHECK(last_version.has_value());
    header_list.push_back(net::structured_headers::ParameterizedMember(
        cur_topics, {{"v", net::structured_headers::Item(
                               *last_version,
                               net::structured_headers::Item::kTokenType)}}));
  }

  // The header is now complete, except for padding. We want the header to be of
  // fixed size for the given number of versions in the list, so we add padding
  // to make that happen.

  // When adding padding, we'll always have at least 1 version.
  if (num_versions_in_epochs == 0) {
    num_versions_in_epochs = 1;
  }

  // The number of topics that should be in the padded response.
  int max_number_of_epochs =
      blink::features::kBrowsingTopicsNumberOfEpochsToExpose.Get();
  CHECK_LE(num_versions_in_epochs, max_number_of_epochs);
  CHECK_GT(max_number_of_epochs, 0);

  // The padded length of the header given the number of versions.
  // Example header: Sec-Browsing-Topics: (100 200);v=chrome.1:1:2,
  // (300);v=chrome.1:1:4, ();p=P00
  int max_length =
      max_number_of_epochs * kTopicMaxLength +  // length of three topics
      max_number_of_epochs -
      num_versions_in_epochs +      // spaces between topics in a list
      num_versions_in_epochs * 5 +  // '();v='
      num_versions_in_epochs *
          kVersionMaxLength +            // max length of the versions
      (num_versions_in_epochs - 1) * 2;  // the ', ' between topic lists

  // Add the bytes for the ", " between the last list and the padding list in
  // the event that there are no topics.
  if (header_list.size() == 0) {
    max_length += 2;
  }

  // How many bytes of padding do we need to add?
  int padding_needed =
      header_list.size() > 0
          ? max_length -
                net::structured_headers::SerializeList(header_list)->length()
          : max_length;

  // The padding should generally be >= 0. It can be negative in certain
  // circumstances and we need to handle that here. It can be negative if a new
  // version is rolled out via finch (e.g., model or taxonomy) that uses an
  // extra digit in its number but the binary hasn't been updated to handle the
  // extra digit yet. It could also happen if there is a race between getting
  // topics and getting the number of distinct topic versions. We clamp to 0 to
  // prevent breakage in these rare circumstances.
  if (padding_needed < 0) {
    padding_needed = 0;
  }

  // Add the padding list at the end.
  header_list.push_back(net::structured_headers::ParameterizedMember(
      std::vector<net::structured_headers::ParameterizedItem>(),
      {{"p", net::structured_headers::Item(
                 base::StrCat({"P", std::string(padding_needed, '0')}),
                 net::structured_headers::Item::kTokenType)}}));

  std::optional<std::string> serialized_header =
      net::structured_headers::SerializeList(header_list);
  CHECK(serialized_header);

  return *serialized_header;
}

void HandleTopicsEligibleResponse(
    const network::mojom::ParsedHeadersPtr& parsed_headers,
    const url::Origin& caller_origin,
    RenderFrameHost& request_initiator_frame,
    browsing_topics::ApiCallerSource caller_source) {
  DCHECK(caller_source == browsing_topics::ApiCallerSource::kFetch ||
         caller_source == browsing_topics::ApiCallerSource::kIframeAttribute ||
         caller_source == browsing_topics::ApiCallerSource::kImgAttribute);

  if (!parsed_headers || !parsed_headers->observe_browsing_topics) {
    return;
  }

  // Check the page's IsPrimary() status again in case it has changed since the
  // request time.
  if (!request_initiator_frame.GetPage().IsPrimary()) {
    return;
  }

  // Store the observation.
  std::vector<blink::mojom::EpochTopicPtr> topics;
  GetContentClient()->browser()->HandleTopicsWebApi(
      caller_origin, request_initiator_frame.GetMainFrame(), caller_source,
      /*get_topics=*/false,
      /*observe=*/true, topics);
}

}  // namespace content
