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

#include "third_party/blink/renderer/platform/fonts/font_matching_metrics.h"

#include "base/metrics/histogram_macros.h"
#include "services/metrics/public/cpp/metrics_utils.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
#include "third_party/blink/public/common/privacy_budget/identifiable_token.h"
#include "third_party/blink/renderer/platform/fonts/font_global_context.h"
#include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h"

namespace {

constexpr double kUkmFontLoadCountBucketSpacing = 1.3;

template <typename T>
HashSet<T> SetIntersection(const HashSet<T>& a, const HashSet<T>& b) {
  HashSet<T> result;
  for (const T& a_value : a) {
    if (b.Contains(a_value))
      result.insert(a_value);
  }
  return result;
}

}  // namespace

namespace blink {

FontMatchingMetrics::FontMatchingMetrics(
    bool top_level,
    ukm::UkmRecorder* ukm_recorder,
    ukm::SourceId source_id,
    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
    : load_context_(top_level ? kTopLevelFrame : kSubframe),
      ukm_recorder_(ukm_recorder),
      source_id_(source_id),
      identifiability_metrics_timer_(
          task_runner,
          this,
          &FontMatchingMetrics::IdentifiabilityMetricsTimerFired) {
  Initialize();
}

FontMatchingMetrics::FontMatchingMetrics(
    ukm::UkmRecorder* ukm_recorder,
    ukm::SourceId source_id,
    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
    : load_context_(kWorker),
      ukm_recorder_(ukm_recorder),
      source_id_(source_id),
      identifiability_metrics_timer_(
          task_runner,
          this,
          &FontMatchingMetrics::IdentifiabilityMetricsTimerFired) {
  Initialize();
}

void FontMatchingMetrics::Initialize() {
  // Estimate of average page font use from anecdotal browsing session.
  constexpr unsigned kEstimatedFontCount = 7;
  local_fonts_succeeded_.ReserveCapacityForSize(kEstimatedFontCount);
  local_fonts_failed_.ReserveCapacityForSize(kEstimatedFontCount);
}

void FontMatchingMetrics::ReportSuccessfulFontFamilyMatch(
    const AtomicString& font_family_name) {
  successful_font_families_.insert(font_family_name);
}

void FontMatchingMetrics::ReportFailedFontFamilyMatch(
    const AtomicString& font_family_name) {
  failed_font_families_.insert(font_family_name);
}

void FontMatchingMetrics::ReportSystemFontFamily(
    const AtomicString& font_family_name) {
  system_font_families_.insert(font_family_name);
}

void FontMatchingMetrics::ReportWebFontFamily(
    const AtomicString& font_family_name) {
  web_font_families_.insert(font_family_name);
}

void FontMatchingMetrics::ReportSuccessfulLocalFontMatch(
    const AtomicString& font_name) {
  local_fonts_succeeded_.insert(font_name);
  ReportLocalFontExistenceByUniqueNameOnly(font_name, /*font_exists=*/true);
}

void FontMatchingMetrics::ReportFailedLocalFontMatch(
    const AtomicString& font_name) {
  local_fonts_failed_.insert(font_name);
  ReportLocalFontExistenceByUniqueNameOnly(font_name, /*font_exists=*/false);
}

void FontMatchingMetrics::ReportLocalFontExistenceByUniqueNameOnly(
    const AtomicString& font_name,
    bool font_exists) {
  if (!IdentifiabilityStudySettings::Get()->IsTypeAllowed(
          IdentifiableSurface::Type::kLocalFontExistenceByUniqueNameOnly)) {
    return;
  }
  IdentifiableTokenKey input_key(
      IdentifiabilityBenignCaseFoldingStringToken(font_name));
  local_font_existence_by_unique_name_only_.insert(input_key, font_exists);
}

void FontMatchingMetrics::InsertFontHashIntoMap(IdentifiableTokenKey input_key,
                                                SimpleFontData* font_data,
                                                TokenToTokenHashMap& hash_map) {
  DCHECK(IdentifiabilityStudySettings::Get()->IsActive());
  if (hash_map.Contains(input_key))
    return;
  IdentifiableToken output_token(GetHashForFontData(font_data));
  hash_map.insert(input_key, output_token);

  // We only record postscript name metrics if both the the broader lookup's
  // type and kLocalFontLoadPostScriptName are allowed. (If the former is not,
  // InsertFontHashIntoMap would not be called.)
  if (!font_data ||
      !IdentifiabilityStudySettings::Get()->IsTypeAllowed(
          IdentifiableSurface::Type::kLocalFontLoadPostScriptName)) {
    return;
  }
  IdentifiableTokenKey postscript_name_key(
      GetPostScriptNameTokenForFontData(font_data));
  font_load_postscript_name_.insert(postscript_name_key, output_token);
}

IdentifiableTokenBuilder
FontMatchingMetrics::GetTokenBuilderWithFontSelectionRequest(
    const FontDescription& font_description) {
  IdentifiableTokenBuilder builder;
  builder.AddValue(font_description.GetFontSelectionRequest().GetHash());
  return builder;
}

void FontMatchingMetrics::ReportFontLookupByUniqueOrFamilyName(
    const AtomicString& name,
    const FontDescription& font_description,
    SimpleFontData* resulting_font_data) {
  if (!IdentifiabilityStudySettings::Get()->IsTypeAllowed(
          IdentifiableSurface::Type::kLocalFontLookupByUniqueOrFamilyName)) {
    return;
  }
  OnFontLookup();

  IdentifiableTokenBuilder builder =
      GetTokenBuilderWithFontSelectionRequest(font_description);

  // Font name lookups are case-insensitive.
  builder.AddToken(IdentifiabilityBenignCaseFoldingStringToken(name));

  IdentifiableTokenKey input_key(builder.GetToken());
  InsertFontHashIntoMap(input_key, resulting_font_data,
                        font_lookups_by_unique_or_family_name_);
}

void FontMatchingMetrics::ReportFontLookupByUniqueNameOnly(
    const AtomicString& name,
    const FontDescription& font_description,
    SimpleFontData* resulting_font_data,
    bool is_loading_fallback) {
  // We ignore lookups that result in loading fallbacks for now as they should
  // only be temporary.
  if (is_loading_fallback ||
      !IdentifiabilityStudySettings::Get()->IsTypeAllowed(
          IdentifiableSurface::Type::kLocalFontLookupByUniqueNameOnly)) {
    return;
  }
  OnFontLookup();

  IdentifiableTokenBuilder builder =
      GetTokenBuilderWithFontSelectionRequest(font_description);

  // Font name lookups are case-insensitive.
  builder.AddToken(IdentifiabilityBenignCaseFoldingStringToken(name));

  IdentifiableTokenKey input_key(builder.GetToken());
  InsertFontHashIntoMap(input_key, resulting_font_data,
                        font_lookups_by_unique_name_only_);
}

void FontMatchingMetrics::ReportFontLookupByFallbackCharacter(
    UChar32 fallback_character,
    FontFallbackPriority fallback_priority,
    const FontDescription& font_description,
    SimpleFontData* resulting_font_data) {
  if (!IdentifiabilityStudySettings::Get()->IsTypeAllowed(
          IdentifiableSurface::Type::kLocalFontLookupByFallbackCharacter)) {
    return;
  }
  OnFontLookup();

  IdentifiableTokenBuilder builder =
      GetTokenBuilderWithFontSelectionRequest(font_description);
  builder.AddValue(fallback_character)
      .AddToken(IdentifiableToken(fallback_priority));

  IdentifiableTokenKey input_key(builder.GetToken());
  InsertFontHashIntoMap(input_key, resulting_font_data,
                        font_lookups_by_fallback_character_);
}

void FontMatchingMetrics::ReportLastResortFallbackFontLookup(
    const FontDescription& font_description,
    SimpleFontData* resulting_font_data) {
  if (!IdentifiabilityStudySettings::Get()->IsTypeAllowed(
          IdentifiableSurface::Type::kLocalFontLookupAsLastResort)) {
    return;
  }
  OnFontLookup();

  IdentifiableTokenBuilder builder =
      GetTokenBuilderWithFontSelectionRequest(font_description);

  IdentifiableTokenKey input_key(builder.GetToken());
  InsertFontHashIntoMap(input_key, resulting_font_data,
                        font_lookups_as_last_resort_);
}

void FontMatchingMetrics::ReportFontFamilyLookupByGenericFamily(
    const AtomicString& generic_font_family_name,
    UScriptCode script,
    FontDescription::GenericFamilyType generic_family_type,
    const AtomicString& resulting_font_name) {
  if (!IdentifiabilityStudySettings::Get()->IsTypeAllowed(
          IdentifiableSurface::Type::kGenericFontLookup)) {
    return;
  }
  OnFontLookup();

  // kStandardFamily lookups override the |generic_font_family_name|. See
  // FontSelector::FamilyNameFromSettings. No need to be case-insensitive as
  // generic names should already be lowercase.
  DCHECK(generic_family_type == FontDescription::kStandardFamily ||
         generic_font_family_name == generic_font_family_name.LowerASCII());
  IdentifiableToken lookup_name_token = IdentifiabilityBenignStringToken(
      generic_family_type == FontDescription::kStandardFamily
          ? font_family_names::kWebkitStandard
          : generic_font_family_name);

  IdentifiableTokenBuilder builder;
  builder.AddToken(lookup_name_token).AddToken(IdentifiableToken(script));
  IdentifiableTokenKey input_key(builder.GetToken());

  // Font name lookups are case-insensitive.
  generic_font_lookups_.insert(
      input_key,
      IdentifiabilityBenignCaseFoldingStringToken(resulting_font_name));
}

void FontMatchingMetrics::PublishIdentifiabilityMetrics() {
  if (!IdentifiabilityStudySettings::Get()->IsActive())
    return;

  IdentifiabilityMetricBuilder builder(source_id_);

  std::pair<TokenToTokenHashMap*, IdentifiableSurface::Type>
      hash_maps_with_corresponding_surface_types[] = {
          {&font_lookups_by_unique_or_family_name_,
           IdentifiableSurface::Type::kLocalFontLookupByUniqueOrFamilyName},
          {&font_lookups_by_unique_name_only_,
           IdentifiableSurface::Type::kLocalFontLookupByUniqueNameOnly},
          {&font_lookups_by_fallback_character_,
           IdentifiableSurface::Type::kLocalFontLookupByFallbackCharacter},
          {&font_lookups_as_last_resort_,
           IdentifiableSurface::Type::kLocalFontLookupAsLastResort},
          {&generic_font_lookups_,
           IdentifiableSurface::Type::kGenericFontLookup},
          {&font_load_postscript_name_,
           IdentifiableSurface::Type::kLocalFontLoadPostScriptName},
          {&local_font_existence_by_unique_name_only_,
           IdentifiableSurface::Type::kLocalFontExistenceByUniqueNameOnly},
      };

  for (const auto& surface_entry : hash_maps_with_corresponding_surface_types) {
    TokenToTokenHashMap* hash_map = surface_entry.first;
    const IdentifiableSurface::Type& surface_type = surface_entry.second;
    for (const auto& individual_lookup : *hash_map) {
      if (IdentifiabilityStudySettings::Get()->ShouldSample(surface_type)) {
        builder.Set(IdentifiableSurface::FromTypeAndToken(
                        surface_type, individual_lookup.key.token),
                    individual_lookup.value);
      }
    }
    hash_map->clear();
  }

  builder.Record(ukm_recorder_);
}

void FontMatchingMetrics::PublishUkmMetrics() {
  ukm::builders::FontMatchAttempts(source_id_)
      .SetLoadContext(load_context_)
      .SetSystemFontFamilySuccesses(ukm::GetExponentialBucketMin(
          SetIntersection(successful_font_families_, system_font_families_)
              .size(),
          kUkmFontLoadCountBucketSpacing))
      .SetSystemFontFamilyFailures(ukm::GetExponentialBucketMin(
          SetIntersection(failed_font_families_, system_font_families_).size(),
          kUkmFontLoadCountBucketSpacing))
      .SetSystemFontFamilyTotal(ukm::GetExponentialBucketMin(
          system_font_families_.size(), kUkmFontLoadCountBucketSpacing))
      .SetWebFontFamilySuccesses(ukm::GetExponentialBucketMin(
          SetIntersection(successful_font_families_, web_font_families_).size(),
          kUkmFontLoadCountBucketSpacing))
      .SetWebFontFamilyFailures(ukm::GetExponentialBucketMin(
          SetIntersection(failed_font_families_, web_font_families_).size(),
          kUkmFontLoadCountBucketSpacing))
      .SetWebFontFamilyTotal(ukm::GetExponentialBucketMin(
          web_font_families_.size(), kUkmFontLoadCountBucketSpacing))
      .SetLocalFontFailures(ukm::GetExponentialBucketMin(
          local_fonts_failed_.size(), kUkmFontLoadCountBucketSpacing))
      .SetLocalFontSuccesses(ukm::GetExponentialBucketMin(
          local_fonts_succeeded_.size(), kUkmFontLoadCountBucketSpacing))
      .SetLocalFontTotal(ukm::GetExponentialBucketMin(
          local_fonts_succeeded_.size() + local_fonts_failed_.size(),
          kUkmFontLoadCountBucketSpacing))
      .Record(ukm_recorder_);
  UMA_HISTOGRAM_COUNTS_10000("Blink.Fonts.FontFamilyMatchAttempts.System",
                             system_font_families_.size());
  UMA_HISTOGRAM_COUNTS_10000(
      "Blink.Fonts.FontMatchAttempts.System",
      local_fonts_failed_.size() + local_fonts_succeeded_.size());
}

void FontMatchingMetrics::OnFontLookup() {
  DCHECK(IdentifiabilityStudySettings::Get()->IsActive());
  if (!identifiability_metrics_timer_.IsActive()) {
    identifiability_metrics_timer_.StartOneShot(base::TimeDelta::FromMinutes(1),
                                                FROM_HERE);
  }
}

void FontMatchingMetrics::IdentifiabilityMetricsTimerFired(TimerBase*) {
  PublishIdentifiabilityMetrics();
}

void FontMatchingMetrics::PublishAllMetrics() {
  PublishIdentifiabilityMetrics();
  PublishUkmMetrics();
}

int64_t FontMatchingMetrics::GetHashForFontData(SimpleFontData* font_data) {
  return font_data ? FontGlobalContext::Get()
                         ->GetOrComputeTypefaceDigest(font_data->PlatformData())
                         .ToUkmMetricValue()
                   : 0;
}

IdentifiableToken FontMatchingMetrics::GetPostScriptNameTokenForFontData(
    SimpleFontData* font_data) {
  DCHECK(font_data);
  return FontGlobalContext::Get()->GetOrComputePostScriptNameDigest(
      font_data->PlatformData());
}

}  // namespace blink
