// 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.

#ifndef CONTENT_BROWSER_PRELOADING_PRELOADING_ATTEMPT_IMPL_H_
#define CONTENT_BROWSER_PRELOADING_PRELOADING_ATTEMPT_IMPL_H_

#include <optional>
#include <vector>

#include "base/timer/elapsed_timer.h"
#include "content/public/browser/preloading.h"
#include "content/public/browser/preloading_data.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom-shared.h"
#include "url/gurl.h"

namespace content {

namespace test {
class PreloadingAttemptAccessor;
}

class CONTENT_EXPORT PreloadingAttemptImpl : public PreloadingAttempt {
 public:
  ~PreloadingAttemptImpl() override;

  // PreloadingAttempt implementation:
  void SetEligibility(PreloadingEligibility eligibility) override;
  void SetHoldbackStatus(PreloadingHoldbackStatus holdback_status) override;
  bool ShouldHoldback() override;
  void SetTriggeringOutcome(
      PreloadingTriggeringOutcome triggering_outcome) override;
  void SetFailureReason(PreloadingFailureReason reason) override;
  base::WeakPtr<PreloadingAttempt> GetWeakPtr() override;

  // Records UKMs for both Preloading_Attempt and
  // Preloading_Attempt_PreviousPrimaryPage. Metrics for both these are same.
  // Only difference is that the Preloading_Attempt_PreviousPrimaryPage UKM is
  // associated with the WebContents primary page that triggered the preloading
  // attempt. This is done to easily analyze the impact of the preloading
  // attempt on the primary visible page. Here `navigated_page` represent the
  // ukm::SourceId of the navigated page. If the navigation doesn't happen this
  // could be invalid. This must be called after the page load ends and we know
  // if the attempt was accurate.
  void RecordPreloadingAttemptMetrics(ukm::SourceId navigated_page);

  void SetNoVarySearchMatchPredicate(
      PreloadingURLMatchCallback no_vary_search_match_predicate);

  // Sets `is_accurate_triggering_` to true if `navigated_url` matches the
  // predicate URL logic. It also records `time_to_next_navigation_`.
  void SetIsAccurateTriggering(const GURL& navigated_url);

  bool IsAccurateTriggering() const { return is_accurate_triggering_; }

  PreloadingAttemptImpl(
      const PreloadingPredictor& creating_predictor,
      const PreloadingPredictor& enacting_predictor,
      PreloadingType preloading_type,
      ukm::SourceId triggered_primary_page_source_id,
      PreloadingURLMatchCallback url_match_predicate,
      uint32_t sampling_seed);

  std::vector<PreloadingPredictor> GetPredictors() const;

  PreloadingType preloading_type() const { return preloading_type_; }

  void SetSpeculationEagerness(blink::mojom::SpeculationEagerness eagerness);

  // Describes what type of checks we had to do to identify if the attempt's
  // URL is or is not under a Service Worker.
  enum class ServiceWorkerRegisteredCheck {
    // These values are persisted to logs. Entries should not be renumbered and
    // numeric values should never be reused.

    // The origin doesn't have any Service Workers registered.
    kOriginOnly = 0,
    // The origin has at least one Service Worker registered and we had to
    // perform a path test to identify if the attempt's URL is under a
    // registered Service Worker.
    kPath = 1,
    kMaxValue = kPath
  };
  static constexpr double kServiceWorkerRegisteredCheckDurationBucketSpacing =
      1.15;
  void SetServiceWorkerRegisteredCheck(ServiceWorkerRegisteredCheck check);
  void SetServiceWorkerRegisteredCheckDuration(base::TimeDelta duration);

 private:
  friend class test::PreloadingAttemptAccessor;

  void RecordPreloadingAttemptUMA();

  // Reason why the preloading attempt failed, this is similar to specific
  // preloading logging reason. Zero as a failure reason signifies no reason is
  // specified. This value is casted from preloading specific enum to int64_t
  // instead of having an enum declaration for each case.
  PreloadingFailureReason failure_reason_ =
      PreloadingFailureReason::kUnspecified;

  // Specifies the eligibility status for this PreloadingAttempt.
  PreloadingEligibility eligibility_ = PreloadingEligibility::kUnspecified;

  PreloadingHoldbackStatus holdback_status_ =
      PreloadingHoldbackStatus::kUnspecified;

  // Specifies the triggering outcome for this PreloadingAttempt.
  PreloadingTriggeringOutcome triggering_outcome_ =
      PreloadingTriggeringOutcome::kUnspecified;

  // Preloading predictor of this PreloadingAttempt.
  const PreloadingPredictor creating_predictor_;
  const PreloadingPredictor enacting_predictor_;

  // PreloadingType this attempt is associated with.
  const PreloadingType preloading_type_;

  // Holds the ukm::SourceId of the triggered primary page of this preloading
  // attempt.
  const ukm::SourceId triggered_primary_page_source_id_;

  // Triggers can specify their own predicate for judging whether two URLs are
  // considered as pointing to the same destination.
  const PreloadingURLMatchCallback url_match_predicate_;

  // Set when a predicted page provides No-Vary-Search header.
  PreloadingURLMatchCallback no_vary_search_match_predicate_;

  // Set to true if this PreloadingAttempt was used for the next navigation.
  bool is_accurate_triggering_ = false;

  // Records when the preloading attempt began, for computing times.
  const base::ElapsedTimer elapsed_timer_;

  // The time between the creation of the attempt and the start of the next
  // navigation, whether accurate or not. The latency is reported as standard
  // buckets, of 1.15 spacing.
  std::optional<base::TimeDelta> time_to_next_navigation_;

  // Represents the duration between the attempt creation and its
  // `triggering_outcome_` becoming `kReady`. The latency is reported as
  // standard buckets, of 1.15 spacing.
  std::optional<base::TimeDelta> ready_time_;

  // The random seed used to determine if a preloading attempt should be sampled
  // in UKM logs. We use a different random seed for each session (that is the
  // source of randomness for sampling) and then hash that seed with the UKM
  // source ID so that all attempts for a given source ID use the same random
  // value to determine sampling. This allows all PreloadingAttempt for a given
  // (preloading_type, predictor) in a page load to be sampled in or out
  // together.
  uint32_t sampling_seed_;

  // Eagerness of this preloading attempt (specified by a speculation rule).
  // This is only set for attempts that are triggered by speculation rules.
  std::optional<blink::mojom::SpeculationEagerness> eagerness_ = std::nullopt;

  // Describes the type of check we did for to find out if the attempt's URL
  // is under a Service Worker's path. The simplest check is: does the URL's
  // origin have any registered service workers or not, the more complicated
  // check is: given the URL's origin has service workers registered, is the
  // URL under one of these Service Workers.
  // This is only set for prefetch attempts that are triggered by speculation
  // rules.
  std::optional<ServiceWorkerRegisteredCheck> service_worker_registered_check_ =
      std::nullopt;
  std::optional<base::TimeDelta> service_worker_registered_check_duration_ =
      std::nullopt;

  base::WeakPtrFactory<PreloadingAttemptImpl> weak_factory_{this};
};

// Used when DCHECK_STATE_TRANSITION triggers.
CONTENT_EXPORT std::ostream& operator<<(std::ostream& o,
                                        const PreloadingTriggeringOutcome& s);

}  // namespace content

#endif  // CONTENT_BROWSER_PRELOADING_PRELOADING_ATTEMPT_IMPL_H_
