// 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/preloading/preloading_attempt_impl.h"

#include "base/containers/span.h"
#include "base/metrics/crc32.h"
#include "base/metrics/histogram_functions.h"
#include "base/state_transitions.h"
#include "base/strings/strcat.h"
#include "content/browser/preloading/preloading.h"
#include "content/browser/preloading/preloading_config.h"
#include "content/public/browser/preloading.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 "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/common/features.h"

namespace content {

namespace {

void DCHECKTriggeringOutcomeTransitions(PreloadingTriggeringOutcome old_state,
                                        PreloadingTriggeringOutcome new_state) {
#if DCHECK_IS_ON()
  static const base::NoDestructor<
      base::StateTransitions<PreloadingTriggeringOutcome>>
      allowed_transitions(base::StateTransitions<PreloadingTriggeringOutcome>({
          {PreloadingTriggeringOutcome::kUnspecified,
           {PreloadingTriggeringOutcome::kDuplicate,
            PreloadingTriggeringOutcome::kRunning,
            PreloadingTriggeringOutcome::kReady,
            PreloadingTriggeringOutcome::kSuccess,
            PreloadingTriggeringOutcome::kFailure,
            PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown,
            PreloadingTriggeringOutcome::kTriggeredButUpgradedToPrerender,
            PreloadingTriggeringOutcome::kTriggeredButPending,
            PreloadingTriggeringOutcome::kNoOp}},

          {PreloadingTriggeringOutcome::kDuplicate, {}},

          {PreloadingTriggeringOutcome::kRunning,
           {PreloadingTriggeringOutcome::kReady,
            PreloadingTriggeringOutcome::kFailure,
            PreloadingTriggeringOutcome::kTriggeredButUpgradedToPrerender}},

          // It can be possible that the preloading attempt may end up failing
          // after being ready to use, for cases where we have to cancel the
          // attempt for performance and security reasons.
          // The transition of kReady to kReady occurs when the main frame
          // navigation is completed in a preloaded page.
          {PreloadingTriggeringOutcome::kReady,
           {PreloadingTriggeringOutcome::kReady,
            PreloadingTriggeringOutcome::kSuccess,
            PreloadingTriggeringOutcome::kFailure,
            PreloadingTriggeringOutcome::kTriggeredButUpgradedToPrerender}},

          {PreloadingTriggeringOutcome::kSuccess, {}},

          {PreloadingTriggeringOutcome::kFailure, {}},

          {PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown, {}},

          {PreloadingTriggeringOutcome::kTriggeredButUpgradedToPrerender,
           {PreloadingTriggeringOutcome::kFailure}},

          {PreloadingTriggeringOutcome::kTriggeredButPending,
           {PreloadingTriggeringOutcome::kRunning,
            PreloadingTriggeringOutcome::kFailure}},

          {PreloadingTriggeringOutcome::kNoOp, {}},
      }));
  DCHECK_STATE_TRANSITION(allowed_transitions,
                          /*old_state=*/old_state,
                          /*new_state=*/new_state);
#endif  // DCHECK_IS_ON()
}

// Preorder of PreloadingType, generated by `kPrefetch < kPrerender`.
bool IsPreloadingTypeUpgradableTo(PreloadingType lhs, PreloadingType rhs) {
  // Naive implementation. It's easier than defining ordering table.
  return (lhs == rhs) || (lhs == PreloadingType::kPrefetch &&
                          rhs == PreloadingType::kPrerender);
}

}  // namespace

void PreloadingAttemptImpl::SetEligibility(PreloadingEligibility eligibility) {
  // Ensure that eligiblity is only set once and that it's set before the
  // holdback status and the triggering outcome.
  CHECK_EQ(eligibility_, PreloadingEligibility::kUnspecified);
  CHECK_EQ(holdback_status_, PreloadingHoldbackStatus::kUnspecified);
  CHECK_EQ(triggering_outcome_, PreloadingTriggeringOutcome::kUnspecified);
  CHECK_NE(eligibility, PreloadingEligibility::kUnspecified);
  eligibility_ = eligibility;
}

// TODO(crbug.com/40275772): most call sites of this should be removed, as
// PreloadingConfig should subsume most feature-specific holdbacks that exist
// today. Some cases can remain as specific overrides of the PreloadingConfig
// logic, e.g. if DevTools is open, or for features that are still launching and
// thus have their own separate holdback feature while they ramp up.
void PreloadingAttemptImpl::SetHoldbackStatus(
    PreloadingHoldbackStatus holdback_status) {
  // Ensure that the holdback status is only set once and that it's set for
  // eligible attempts and before the triggering outcome.
  CHECK_EQ(eligibility_, PreloadingEligibility::kEligible);
  CHECK_EQ(holdback_status_, PreloadingHoldbackStatus::kUnspecified);
  CHECK_EQ(triggering_outcome_, PreloadingTriggeringOutcome::kUnspecified);
  CHECK_NE(holdback_status, PreloadingHoldbackStatus::kUnspecified);
  holdback_status_ = holdback_status;
}

bool PreloadingAttemptImpl::ShouldHoldback() {
  CHECK_EQ(eligibility_, PreloadingEligibility::kEligible);
  if (holdback_status_ != PreloadingHoldbackStatus::kUnspecified) {
    // The holdback status has already been determined, just use that value.
    return holdback_status_ == PreloadingHoldbackStatus::kHoldback;
  }

  bool should_holdback_due_to_preloading_config =
      PreloadingConfig::GetInstance().ShouldHoldback(preloading_type_,
                                                     creating_predictor_);
  bool should_holdback_due_to_autosr_holdback =
      creating_predictor_ == content_preloading_predictor::
                                 kSpeculationRulesFromAutoSpeculationRules &&
      blink::features::kAutoSpeculationRulesHoldback.Get();
  bool should_holdback = should_holdback_due_to_preloading_config ||
                         should_holdback_due_to_autosr_holdback;
  if (should_holdback) {
    holdback_status_ = PreloadingHoldbackStatus::kHoldback;
  } else {
    holdback_status_ = PreloadingHoldbackStatus::kAllowed;
  }
  return should_holdback;
}

void PreloadingAttemptImpl::SetTriggeringOutcome(
    PreloadingTriggeringOutcome triggering_outcome) {
  // Ensure that the triggering outcome is only set for eligible and
  // non-holdback attempts.
  CHECK_EQ(eligibility_, PreloadingEligibility::kEligible);
  CHECK_EQ(holdback_status_, PreloadingHoldbackStatus::kAllowed);
  // Check that we do the correct transition before setting
  // `triggering_outcome_`.
  DCHECKTriggeringOutcomeTransitions(/*old_state=*/triggering_outcome_,
                                     /*new_state=*/triggering_outcome);
  triggering_outcome_ = triggering_outcome;

  // Set the ready time, if this attempt was not already ready.
  switch (triggering_outcome_) {
    // Currently only Prefetch, Prerender and NoStatePrefetch have a ready
    // state. Other preloading features do not track the entire progress of the
    // preloading attempt, where
    // `PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown` is set for
    // those other features.
    case PreloadingTriggeringOutcome::kReady:
      CHECK(preloading_type_ == PreloadingType::kPrefetch ||
            preloading_type_ == PreloadingType::kPrerender ||
            preloading_type_ == PreloadingType::kNoStatePrefetch ||
            preloading_type_ == PreloadingType::kLinkPreview);
      if (!ready_time_) {
        ready_time_ = elapsed_timer_.Elapsed();
      }
      break;
    default:
      break;
  }
}

void PreloadingAttemptImpl::SetFailureReason(PreloadingFailureReason reason) {
  // Ensure that the failure reason is only set once and is only set for
  // eligible and non-holdback attempts.
  CHECK_EQ(eligibility_, PreloadingEligibility::kEligible);
  CHECK_EQ(holdback_status_, PreloadingHoldbackStatus::kAllowed);
  CHECK_EQ(failure_reason_, PreloadingFailureReason::kUnspecified);
  CHECK_NE(reason, PreloadingFailureReason::kUnspecified);

  // It could be possible that the TriggeringOutcome is already kFailure, when
  // we try to set FailureReason after setting TriggeringOutcome to kFailure.
  if (triggering_outcome_ != PreloadingTriggeringOutcome::kFailure)
    SetTriggeringOutcome(PreloadingTriggeringOutcome::kFailure);
  failure_reason_ = reason;
}

base::WeakPtr<PreloadingAttempt> PreloadingAttemptImpl::GetWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

PreloadingAttemptImpl::PreloadingAttemptImpl(
    const PreloadingPredictor& creating_predictor,
    const PreloadingPredictor& enacting_predictor,
    PreloadingType preloading_type,
    ukm::SourceId triggered_primary_page_source_id,
    PreloadingURLMatchCallback url_match_predicate,
    std::optional<PreloadingType> planned_max_preloading_type,
    uint32_t sampling_seed)
    : creating_predictor_(creating_predictor),
      enacting_predictor_(enacting_predictor),
      preloading_type_(preloading_type),
      triggered_primary_page_source_id_(triggered_primary_page_source_id),
      url_match_predicate_(std::move(url_match_predicate)),
      planned_max_preloading_type_(
          planned_max_preloading_type.value_or(preloading_type)),
      sampling_seed_(sampling_seed) {
  CHECK(IsPreloadingTypeUpgradableTo(preloading_type_,
                                     planned_max_preloading_type_));
}

PreloadingAttemptImpl::~PreloadingAttemptImpl() = default;

std::vector<PreloadingPredictor> PreloadingAttemptImpl::GetPredictors() const {
  if (creating_predictor_ == enacting_predictor_) {
    return {creating_predictor_};
  }
  return {creating_predictor_, enacting_predictor_};
}

void PreloadingAttemptImpl::RecordPreloadingAttemptMetrics(
    ukm::SourceId navigated_page_source_id) {
  ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();

  // Ensure that when the `triggering_outcome_` is kSuccess, then the
  // accurate_triggering should be true.
  if (triggering_outcome_ == PreloadingTriggeringOutcome::kSuccess) {
    // TODO(crbug.com/40263357): Fix PreloadingAttempt for Prefetching in
    // a different WebContents. It is allowed to activate a prefetched result in
    // another WebContents instance, and the WebContents that stores `this`
    // instance does not have the opportunity to set the
    // `is_accurate_triggering_` flag to true in this case.
    if (preloading_type_ != PreloadingType::kPrefetch) {
      CHECK(is_accurate_triggering_)
          << "TriggeringOutcome set to kSuccess without correct prediction\n";
    }
  }

  // Always record UMA, regardless of sampling.
  RecordPreloadingAttemptUMA();

  // Check if the preloading attempt is sampled in.
  // We prefer to use the UKM source ID of the triggering page for determining
  // sampling, so that all preloading attempts from a given (preloading_type,
  // predictor) for the same page are included (or not) together. If there is
  // no source for the triggering page, fallback to the navigated-to page.
  ukm::SourceId sampling_source = triggered_primary_page_source_id_;
  if (sampling_source == ukm::kInvalidSourceId) {
    sampling_source = navigated_page_source_id;
  }
  if (sampling_source == ukm::kInvalidSourceId) {
    // There is no valid UKM source, so there is nothing to log.
    return;
  }

  PreloadingConfig& config = PreloadingConfig::GetInstance();

  for (const auto& predictor : GetPredictors()) {
    uint32_t sampled_num = sampling_seed_;
    sampled_num =
        base::Crc32(sampled_num, base::byte_span_from_ref(sampling_source));

    double sampling_likelihood =
        config.SamplingLikelihood(preloading_type_, predictor);
    if (sampled_num >
        sampling_likelihood * std::numeric_limits<uint32_t>::max()) {
      // PreloadingAttempt is sampled out.
      continue;
    }

    // Turn sampling_likelihood into an int64_t for UKM logging. Multiply by one
    // million to preserve accuracy.
    int64_t sampling_likelihood_per_million =
        static_cast<int64_t>(1'000'000 * sampling_likelihood);

    if (navigated_page_source_id != ukm::kInvalidSourceId) {
      ukm::builders::Preloading_Attempt builder(navigated_page_source_id);
      builder.SetPreloadingType(static_cast<int64_t>(preloading_type_))
          .SetPreloadingPredictor(predictor.ukm_value())
          .SetEligibility(static_cast<int64_t>(eligibility_))
          .SetHoldbackStatus(static_cast<int64_t>(holdback_status_))
          .SetTriggeringOutcome(static_cast<int64_t>(triggering_outcome_))
          .SetFailureReason(static_cast<int64_t>(failure_reason_))
          .SetAccurateTriggering(is_accurate_triggering_)
          .SetSamplingLikelihood(sampling_likelihood_per_million);
      if (time_to_next_navigation_) {
        builder.SetTimeToNextNavigation(
            ukm::GetExponentialBucketMinForCounts1000(
                time_to_next_navigation_->InMilliseconds()));
      }
      if (ready_time_) {
        builder.SetReadyTime(ukm::GetExponentialBucketMinForCounts1000(
            ready_time_->InMilliseconds()));
      }
      if (eagerness_) {
        builder.SetSpeculationEagerness(
            static_cast<int64_t>(eagerness_.value()));
      }
      if (service_worker_registered_check_) {
        builder.SetPrefetchServiceWorkerRegisteredCheck(
            static_cast<int64_t>(service_worker_registered_check_.value()));
      }
      if (service_worker_registered_check_duration_) {
        builder.SetPrefetchServiceWorkerRegisteredForURLCheckDuration(
            ukm::GetExponentialBucketMin(
                service_worker_registered_check_duration_.value()
                    .InMicroseconds(),
                kServiceWorkerRegisteredCheckDurationBucketSpacing));
      }
      builder.Record(ukm_recorder);
    }

    if (triggered_primary_page_source_id_ != ukm::kInvalidSourceId) {
      ukm::builders::Preloading_Attempt_PreviousPrimaryPage builder(
          triggered_primary_page_source_id_);
      builder.SetPreloadingType(static_cast<int64_t>(preloading_type_))
          .SetPreloadingPredictor(predictor.ukm_value())
          .SetEligibility(static_cast<int64_t>(eligibility_))
          .SetHoldbackStatus(static_cast<int64_t>(holdback_status_))
          .SetTriggeringOutcome(static_cast<int64_t>(triggering_outcome_))
          .SetFailureReason(static_cast<int64_t>(failure_reason_))
          .SetAccurateTriggering(is_accurate_triggering_)
          .SetSamplingLikelihood(sampling_likelihood_per_million);
      if (time_to_next_navigation_) {
        builder.SetTimeToNextNavigation(
            ukm::GetExponentialBucketMinForCounts1000(
                time_to_next_navigation_->InMilliseconds()));
      }
      if (ready_time_) {
        builder.SetReadyTime(ukm::GetExponentialBucketMinForCounts1000(
            ready_time_->InMilliseconds()));
      }
      if (eagerness_) {
        builder.SetSpeculationEagerness(
            static_cast<int64_t>(eagerness_.value()));
      }
      if (service_worker_registered_check_) {
        builder.SetPrefetchServiceWorkerRegisteredCheck(
            static_cast<int64_t>(service_worker_registered_check_.value()));
      }
      if (service_worker_registered_check_duration_) {
        builder.SetPrefetchServiceWorkerRegisteredForURLCheckDuration(
            ukm::GetExponentialBucketMin(
                service_worker_registered_check_duration_.value()
                    .InMicroseconds(),
                kServiceWorkerRegisteredCheckDurationBucketSpacing));
      }
      builder.Record(ukm_recorder);
    }
  }
}

void PreloadingAttemptImpl::RecordPreloadingAttemptUMA() {
  // Records the triggering outcome enum. This can be used to:
  // 1. Track the number of attempts;
  // 2. Track the attempts' rates of various terminal status (i.e. success
  // rate).
  for (const auto& predictor : GetPredictors()) {
    const auto uma_triggering_outcome_histogram =
        base::StrCat({"Preloading.", PreloadingTypeToString(preloading_type_),
                      ".Attempt.", predictor.name(), ".TriggeringOutcome"});
    base::UmaHistogramEnumeration(std::move(uma_triggering_outcome_histogram),
                                  triggering_outcome_);
  }
}

void PreloadingAttemptImpl::SetNoVarySearchMatchPredicate(
    PreloadingURLMatchCallback no_vary_search_match_predicate) {
  CHECK(!no_vary_search_match_predicate_);
  no_vary_search_match_predicate_ = std::move(no_vary_search_match_predicate);
}

void PreloadingAttemptImpl::SetIsAccurateTriggering(const GURL& navigated_url) {
  CHECK(url_match_predicate_);

  // `PreloadingAttemptImpl::SetIsAccurateTriggering` is called during
  // `WCO::DidStartNavigation`.
  if (!time_to_next_navigation_) {
    time_to_next_navigation_ = elapsed_timer_.Elapsed();
  }

  // Use the predicate to match the URLs as the matching logic varies for each
  // predictor.
  is_accurate_triggering_ |= url_match_predicate_.Run(navigated_url);
  if (no_vary_search_match_predicate_) {
    is_accurate_triggering_ |=
        no_vary_search_match_predicate_.Run(navigated_url);
  }
}

void PreloadingAttemptImpl::SetSpeculationEagerness(
    blink::mojom::SpeculationEagerness eagerness) {
  CHECK(creating_predictor_ ==
            content_preloading_predictor::kSpeculationRules ||
        creating_predictor_ ==
            content_preloading_predictor::kSpeculationRulesFromIsolatedWorld ||
        creating_predictor_ == content_preloading_predictor::
                                   kSpeculationRulesFromAutoSpeculationRules)
      << "predictor_type_: " << creating_predictor_.name()
      << " (ukm_value = " << creating_predictor_.ukm_value() << ")";
  eagerness_ = eagerness;
}

void PreloadingAttemptImpl::SetServiceWorkerRegisteredCheck(
    ServiceWorkerRegisteredCheck check) {
  service_worker_registered_check_ = check;
}

void PreloadingAttemptImpl::SetServiceWorkerRegisteredCheckDuration(
    base::TimeDelta duration) {
  service_worker_registered_check_duration_ = duration;
}

// Used for StateTransitions matching.
std::ostream& operator<<(std::ostream& os,
                         const PreloadingTriggeringOutcome& outcome) {
  switch (outcome) {
    case PreloadingTriggeringOutcome::kUnspecified:
      os << "Unspecified";
      break;
    case PreloadingTriggeringOutcome::kDuplicate:
      os << "Duplicate";
      break;
    case PreloadingTriggeringOutcome::kRunning:
      os << "Running";
      break;
    case PreloadingTriggeringOutcome::kReady:
      os << "Ready";
      break;
    case PreloadingTriggeringOutcome::kSuccess:
      os << "Success";
      break;
    case PreloadingTriggeringOutcome::kFailure:
      os << "Failure";
      break;
    case PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown:
      os << "TriggeredButOutcomeUnknown";
      break;
    case PreloadingTriggeringOutcome::kTriggeredButUpgradedToPrerender:
      os << "TriggeredButUpgradedToPrerender";
      break;
    case PreloadingTriggeringOutcome::kTriggeredButPending:
      os << "TriggeredButPending";
      break;
    case PreloadingTriggeringOutcome::kNoOp:
      os << "NoOp";
      break;
  }
  return os;
}

}  // namespace content
