// Copyright 2023 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/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "components/ukm/test_ukm_recorder.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/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "testing/gtest/include/gtest/gtest-param-test.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

namespace {
const PreloadingPredictor kPredictors[] = {
    preloading_predictor::kUnspecified,
    preloading_predictor::kUrlPointerDownOnAnchor,
    preloading_predictor::kUrlPointerHoverOnAnchor,
    preloading_predictor::kLinkRel,
    content_preloading_predictor::kSpeculationRules,
};

const PreloadingType kTypes[] = {
    PreloadingType::kUnspecified,     PreloadingType::kPreconnect,
    PreloadingType::kPrefetch,        PreloadingType::kPrerender,
    PreloadingType::kNoStatePrefetch,
};

const char* kUmaTriggerOutcome = "Preloading.%s.Attempt.%s.TriggeringOutcome";

}  // namespace

using PreloadingAttemptImplRecordUMATest = ::testing::TestWithParam<
    ::testing::tuple<PreloadingPredictor, PreloadingType>>;

TEST_P(PreloadingAttemptImplRecordUMATest, TestHistogramRecordedCorrectly) {
  const auto& test_param = GetParam();
  const auto predictor = ::testing::get<0>(test_param);
  const auto preloading_type = ::testing::get<1>(test_param);
  auto attempt = std::make_unique<PreloadingAttemptImpl>(
      predictor, preloading_type, /*triggered_primary_page_source_id=*/0,
      /*url_match_predicate=*/
      PreloadingData::GetSameURLMatcher(GURL("http://example.com/")),
      /*sampling_seed=*/1ul);
  {
    base::HistogramTester histogram_tester;
    // Use `ukm::kInvalidSourceId` so we skip the UKM recording.
    attempt->RecordPreloadingAttemptMetrics(ukm::kInvalidSourceId);
    histogram_tester.ExpectUniqueSample(
        base::StringPrintf(kUmaTriggerOutcome,
                           PreloadingTypeToString(preloading_type).data(),
                           predictor.name().data()),
        PreloadingTriggeringOutcome::kUnspecified, 1);
  }
  {
    attempt->SetEligibility(PreloadingEligibility::kEligible);
    attempt->SetHoldbackStatus(PreloadingHoldbackStatus::kAllowed);
    attempt->SetTriggeringOutcome(PreloadingTriggeringOutcome::kRunning);
    base::HistogramTester histogram_tester;
    attempt->RecordPreloadingAttemptMetrics(ukm::kInvalidSourceId);
    histogram_tester.ExpectUniqueSample(
        base::StringPrintf(kUmaTriggerOutcome,
                           PreloadingTypeToString(preloading_type).data(),
                           predictor.name().data()),
        PreloadingTriggeringOutcome::kRunning, 1);
  }
}

INSTANTIATE_TEST_SUITE_P(PreloadingAttemptImplRecordUMATests,
                         PreloadingAttemptImplRecordUMATest,
                         ::testing::Combine(::testing::ValuesIn(kPredictors),
                                            ::testing::ValuesIn(kTypes)));

class PreloadingAttemptUKMTest : public ::testing::Test {
 public:
  PreloadingAttemptUKMTest() = default;

  void SetUp() override {
    ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
  }

  void TearDown() override { ukm_recorder_.reset(); }

  ukm::TestUkmRecorder* ukm_recorder() { return ukm_recorder_.get(); }

 private:
  base::test::SingleThreadTaskEnvironment task_environment_;
  std::unique_ptr<ukm::TestUkmRecorder> ukm_recorder_;
};

TEST_F(PreloadingAttemptUKMTest, NoSampling) {
  base::test::ScopedFeatureList features;
  features.InitAndEnableFeatureWithParameters(features::kPreloadingConfig,
                                              {{"preloading_config", R"(
  [{
    "preloading_type": "Preconnect",
    "preloading_predictor": "UrlPointerDownOnAnchor",
    "sampling_likelihood": 1.0
  }]
  )"}});
  PreloadingConfig& config = PreloadingConfig::GetInstance();
  config.ParseConfig();

  PreloadingAttemptImpl attempt(
      preloading_predictor::kUrlPointerDownOnAnchor,
      PreloadingType::kPreconnect, ukm::AssignNewSourceId(),
      PreloadingData::GetSameURLMatcher(GURL("http://example.com/")),
      /*sampling_seed=*/1ul);
  attempt.RecordPreloadingAttemptMetrics(ukm::AssignNewSourceId());
  const char* entry_name =
      ukm::builders::Preloading_Attempt_PreviousPrimaryPage::kEntryName;

  // Make sure the attempt is recorded, with a sampling_likelihood of 1,000,000.
  EXPECT_EQ(ukm_recorder()->GetEntriesByName(entry_name).size(), 1ul);
  auto* entry = ukm_recorder()->GetEntriesByName(entry_name)[0];
  ukm_recorder()->EntryHasMetric(
      entry, ukm::builders::Preloading_Attempt_PreviousPrimaryPage::
                 kSamplingLikelihoodName);
  ukm_recorder()->ExpectEntryMetric(
      entry,
      ukm::builders::Preloading_Attempt_PreviousPrimaryPage::
          kSamplingLikelihoodName,
      1'000'000);
}

TEST_F(PreloadingAttemptUKMTest, SampledOut) {
  base::test::ScopedFeatureList features;
  features.InitAndEnableFeatureWithParameters(features::kPreloadingConfig,
                                              {{"preloading_config", R"(
  [{
    "preloading_type": "Preconnect",
    "preloading_predictor": "UrlPointerDownOnAnchor",
    "sampling_likelihood": 0.0
  }]
  )"}});
  PreloadingConfig& config = PreloadingConfig::GetInstance();
  config.ParseConfig();

  PreloadingAttemptImpl attempt(
      preloading_predictor::kUrlPointerDownOnAnchor,
      PreloadingType::kPreconnect, ukm::AssignNewSourceId(),
      PreloadingData::GetSameURLMatcher(GURL("http://example.com/")),
      /*sampling_seed=*/1ul);
  attempt.RecordPreloadingAttemptMetrics(ukm::AssignNewSourceId());
  const char* entry_name =
      ukm::builders::Preloading_Attempt_PreviousPrimaryPage::kEntryName;

  // Make sure the attempt is not recorded.
  EXPECT_EQ(ukm_recorder()->GetEntriesByName(entry_name).size(), 0ul);
}
}  // namespace content
