// 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 <map>
#include <memory>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/containers/flat_set.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h"
#include "components/google/core/common/google_util.h"
#include "components/metrics/content/subprocess_metrics_provider.h"
#include "components/optimization_guide/core/hints_component_info.h"
#include "components/optimization_guide/core/hints_component_util.h"
#include "components/optimization_guide/core/optimization_guide_constants.h"
#include "components/optimization_guide/core/optimization_guide_enums.h"
#include "components/optimization_guide/core/optimization_guide_features.h"
#include "components/optimization_guide/core/optimization_guide_prefs.h"
#include "components/optimization_guide/core/optimization_guide_store.h"
#include "components/optimization_guide/core/optimization_guide_switches.h"
#include "components/optimization_guide/core/optimization_hints_component_update_listener.h"
#include "components/optimization_guide/core/test_hints_component_creator.h"
#include "components/optimization_guide/core/top_host_provider.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "components/prefs/pref_service.h"
#include "components/site_engagement/content/site_engagement_service.h"
#include "components/ukm/test_ukm_recorder.h"
#include "components/variations/hashing.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_base.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/network_connection_change_simulator.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/network/public/cpp/network_quality_tracker.h"
#include "third_party/blink/public/common/features.h"

namespace {

// Fetch and calculate the total number of samples from all the bins for
// |histogram_name|. Note: from some browertests run (such as chromeos) there
// might be two profiles created, and this will return the total sample count
// across profiles.
int GetTotalHistogramSamples(const base::HistogramTester* histogram_tester,
                             const std::string& histogram_name) {
  std::vector<base::Bucket> buckets =
      histogram_tester->GetAllSamples(histogram_name);
  int total = 0;
  for (const auto& bucket : buckets)
    total += bucket.count;

  return total;
}

// Retries fetching |histogram_name| until it contains at least |count| samples.
int RetryForHistogramUntilCountReached(
    const base::HistogramTester* histogram_tester,
    const std::string& histogram_name,
    int count) {
  int total = 0;
  while (true) {
    base::ThreadPoolInstance::Get()->FlushForTesting();
    base::RunLoop().RunUntilIdle();

    total = GetTotalHistogramSamples(histogram_tester, histogram_name);
    if (total >= count)
      return total;

    content::FetchHistogramsFromChildProcesses();
    metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
    base::RunLoop().RunUntilIdle();
  }
}

enum class HintsFetcherRemoteResponseType {
  kSuccessful = 0,
  kUnsuccessful = 1,
  kMalformed = 2,
  kHung = 3,
};

constexpr char kGoogleHost[] = "www.google.com";

// Modifies |relative_url|:
// Scheme of the returned URL matches the scheme of the |server|.
// Host of the returned URL matches kGoogleHost.
// Port number of the returned URL matches the port at which |server| is
// listening.
// Path of the returned URL is set to |relative_url|.
GURL GetURLWithGoogleHost(net::EmbeddedTestServer* server,
                          const std::string& relative_url) {
  GURL server_base_url = server->base_url();
  GURL base_url =
      GURL(base::StrCat({server_base_url.scheme(), "://", kGoogleHost, ":",
                         server_base_url.port()}));
  EXPECT_TRUE(base_url.is_valid()) << base_url.possibly_invalid_spec();
  return base_url.Resolve(relative_url);
}

}  // namespace

// This test class sets up everything but does not enable any
// HintsFetcher-related features. The parameter selects whether the
// OptimizationGuideKeyedService is enabled (tests should pass in the same way
// for both cases).
class HintsFetcherDisabledBrowserTest : public InProcessBrowserTest {
 public:
  HintsFetcherDisabledBrowserTest() = default;
  ~HintsFetcherDisabledBrowserTest() override = default;

  void SetUpOnMainThread() override {
    content::NetworkConnectionChangeSimulator().SetConnectionType(
        network::mojom::ConnectionType::CONNECTION_2G);

    // Ensure that kGoogleHost resolves to the localhost where the embedded test
    // server is listening.
    host_resolver()->AddRule("*", "127.0.0.1");

    ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();

    InProcessBrowserTest::SetUpOnMainThread();
  }

  void SetUp() override {
    origin_server_ = std::make_unique<net::EmbeddedTestServer>(
        net::EmbeddedTestServer::TYPE_HTTPS);
    origin_server_->ServeFilesFromSourceDirectory("chrome/test/data/previews");

    ASSERT_TRUE(origin_server_->Start());

    https_url_ = origin_server_->GetURL("/hint_setup.html");
    ASSERT_TRUE(https_url().SchemeIs(url::kHttpsScheme));

    search_results_page_url_ =
        GetURLWithGoogleHost(origin_server_.get(), "/search_results_page.html");
    ASSERT_TRUE(search_results_page_url_.is_valid() &&
                search_results_page_url_.SchemeIs(url::kHttpsScheme) &&
                google_util::IsGoogleHostname(search_results_page_url_.host(),
                                              google_util::DISALLOW_SUBDOMAIN));

    hints_server_ = std::make_unique<net::EmbeddedTestServer>(
        net::EmbeddedTestServer::TYPE_HTTPS);
    hints_server_->ServeFilesFromSourceDirectory("chrome/test/data/previews");
    hints_server_->RegisterRequestHandler(base::BindRepeating(
        &HintsFetcherDisabledBrowserTest::HandleGetHintsRequest,
        base::Unretained(this)));

    ASSERT_TRUE(hints_server_->Start());

    std::map<std::string, std::string> params;
    params["random_anchor_sampling_period"] = "1";
    param_feature_list_.InitAndEnableFeatureWithParameters(
        blink::features::kNavigationPredictor, params);

    InProcessBrowserTest::SetUp();
  }

  void SetUpCommandLine(base::CommandLine* cmd) override {
    cmd->AppendSwitch("ignore-certificate-errors");

    cmd->AppendSwitch("purge_hint_cache_store");

    cmd->AppendSwitch(optimization_guide::switches::
                          kDisableCheckingUserPermissionsForTesting);

    // Set up OptimizationGuideServiceURL, this does not enable HintsFetching,
    // only provides the URL.
    cmd->AppendSwitchASCII(
        optimization_guide::switches::kOptimizationGuideServiceGetHintsURL,
        hints_server_
            ->GetURL(GURL(optimization_guide::
                              kOptimizationGuideServiceGetHintsDefaultURL)
                         .host(),
                     "/")
            .spec());
    cmd->AppendSwitchASCII("host-rules", "MAP * 127.0.0.1");
    cmd->AppendSwitchASCII("force-variation-ids", "4");

    cmd->AppendSwitchASCII(optimization_guide::switches::kFetchHintsOverride,
                           "example1.com, example2.com");

    cmd->AppendSwitch(optimization_guide::switches::kFetchHintsOverrideTimer);
  }

  // Creates hint data for the |hint_setup_url|'s so that the fetching of the
  // hints is triggered.
  void SetUpComponentUpdateHints(const GURL& hint_setup_url) {
    const optimization_guide::HintsComponentInfo& component_info =
        test_hints_component_creator_.CreateHintsComponentInfoWithPageHints(
            optimization_guide::proto::NOSCRIPT, {hint_setup_url.host()}, "*");

    base::HistogramTester histogram_tester;

    optimization_guide::OptimizationHintsComponentUpdateListener::GetInstance()
        ->MaybeUpdateHintsComponent(component_info);

    RetryForHistogramUntilCountReached(
        &histogram_tester,
        optimization_guide::kComponentHintsUpdatedResultHistogramString, 1);
  }

  void SetNetworkConnectionOffline() {
    content::NetworkConnectionChangeSimulator().SetConnectionType(
        network::mojom::ConnectionType::CONNECTION_NONE);
  }

  void SetResponseType(HintsFetcherRemoteResponseType response_type) {
    response_type_ = response_type;
  }

  void LoadHintsForUrl(const GURL& url) {
    base::HistogramTester histogram_tester;

    // Navigate to |url| to prime the OptimizationGuide hints for the
    // url's host and ensure that they have been loaded from the store (via
    // histogram) prior to the navigation that tests functionality.
    ui_test_utils::NavigateToURL(browser(), url);

    RetryForHistogramUntilCountReached(
        &histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);
  }

  const GURL& https_url() const { return https_url_; }
  const base::HistogramTester* GetHistogramTester() {
    return &histogram_tester_;
  }

  const GURL& search_results_page_url() const {
    return search_results_page_url_;
  }

  void SetExpectedHintsRequestForHostsAndUrls(
      const base::flat_set<std::string>& hosts_or_urls) {
    base::AutoLock lock(lock_);
    expect_hints_request_for_hosts_and_urls_ = hosts_or_urls;
  }

  size_t count_hints_requests_received() {
    base::AutoLock lock(lock_);
    return count_hints_requests_received_;
  }

  void WaitUntilHintsFetcherRequestReceived() {
    while (true) {
      {
        // Acquire the |lock_| inside to avoid starving other consumers of the
        // lock.
        base::AutoLock lock(lock_);
        if (count_hints_requests_received_ > 0)
          return;
      }
      base::RunLoop().RunUntilIdle();
    }
  }

  void ResetCountHintsRequestsReceived() {
    base::AutoLock lock(lock_);
    count_hints_requests_received_ = 0;
  }

 protected:
  base::test::ScopedFeatureList scoped_feature_list_;
  std::unique_ptr<net::EmbeddedTestServer> origin_server_;
  std::unique_ptr<net::EmbeddedTestServer> hints_server_;
  HintsFetcherRemoteResponseType response_type_ =
      HintsFetcherRemoteResponseType::kSuccessful;

 private:
  std::unique_ptr<net::test_server::HttpResponse> HandleOriginRequest(
      const net::test_server::HttpRequest& request) {
    EXPECT_EQ(request.method, net::test_server::METHOD_GET);
    auto response = std::make_unique<net::test_server::BasicHttpResponse>();
    response->set_code(net::HTTP_OK);

    return std::move(response);
  }

  std::unique_ptr<net::test_server::HttpResponse> HandleGetHintsRequest(
      const net::test_server::HttpRequest& request) {
    base::AutoLock lock(lock_);

    ++count_hints_requests_received_;
    auto response = std::make_unique<net::test_server::BasicHttpResponse>();
    // If the request is a GET, it corresponds to a navigation so return a
    // normal response.
    EXPECT_EQ(request.method, net::test_server::METHOD_POST);
    EXPECT_NE(request.headers.end(), request.headers.find("X-Client-Data"));

    optimization_guide::proto::GetHintsRequest hints_request;
    EXPECT_TRUE(hints_request.ParseFromString(request.content));
    EXPECT_FALSE(hints_request.hosts().empty() && hints_request.urls().empty());
    EXPECT_GE(optimization_guide::features::
                  MaxHostsForOptimizationGuideServiceHintsFetch(),
              static_cast<size_t>(hints_request.hosts().size()));

    // Only verify the hints if there are hosts in the request.
    if (!hints_request.hosts().empty())
      VerifyHintsMatchExpectedHostsAndUrls(hints_request);

    if (response_type_ == HintsFetcherRemoteResponseType::kSuccessful) {
      response->set_code(net::HTTP_OK);

      optimization_guide::proto::GetHintsResponse get_hints_response;

      optimization_guide::proto::Hint* hint = get_hints_response.add_hints();
      hint->set_key_representation(optimization_guide::proto::HOST);
      hint->set_key(https_url_.host());
      optimization_guide::proto::PageHint* page_hint = hint->add_page_hints();
      page_hint->set_page_pattern("page pattern");

      std::string serialized_request;
      get_hints_response.SerializeToString(&serialized_request);
      response->set_content(serialized_request);
    } else if (response_type_ ==
               HintsFetcherRemoteResponseType::kUnsuccessful) {
      response->set_code(net::HTTP_NOT_FOUND);

    } else if (response_type_ == HintsFetcherRemoteResponseType::kMalformed) {
      response->set_code(net::HTTP_OK);

      std::string serialized_request = "Not a proto";
      response->set_content(serialized_request);
    } else if (response_type_ == HintsFetcherRemoteResponseType::kHung) {
      return std::make_unique<net::test_server::HungResponse>();
    } else {
      NOTREACHED();
    }

    return std::move(response);
  }

  // Verifies that the hosts present in |hints_request| match the expected set
  // of hosts present in |expect_hints_request_for_hosts_|. The ordering of the
  // hosts in not matched.
  void VerifyHintsMatchExpectedHostsAndUrls(
      const optimization_guide::proto::GetHintsRequest& hints_request) const {
    if (!expect_hints_request_for_hosts_and_urls_)
      return;

    base::flat_set<std::string> hosts_and_urls_requested;
    for (const auto& host : hints_request.hosts())
      hosts_and_urls_requested.insert(host.host());
    for (const auto& url : hints_request.urls()) {
      // TODO(crbug/1051365):  Remove normalization step once nav predictor
      // provides predictable URLs.
      hosts_and_urls_requested.insert(GURL(url.url()).GetAsReferrer().spec());
    }

    EXPECT_EQ(expect_hints_request_for_hosts_and_urls_.value().size(),
              hosts_and_urls_requested.size());
    for (const auto& host_or_url :
         expect_hints_request_for_hosts_and_urls_.value()) {
      hosts_and_urls_requested.erase(host_or_url);
    }
    EXPECT_EQ(0u, hosts_and_urls_requested.size());

    // We only expect 1 field trial to be allowed and sent up.
    EXPECT_EQ(1, hints_request.active_field_trials_size());
    EXPECT_EQ(variations::HashName(
                  "scoped_feature_list_trial_for_OptimizationHintsFetching"),
              hints_request.active_field_trials(0).name_hash());
  }

  void TearDownOnMainThread() override {
    EXPECT_TRUE(origin_server_->ShutdownAndWaitUntilComplete());
    EXPECT_TRUE(hints_server_->ShutdownAndWaitUntilComplete());

    InProcessBrowserTest::TearDownOnMainThread();
  }

  base::test::ScopedFeatureList param_feature_list_;

  GURL https_url_;

  GURL search_results_page_url_;

  base::HistogramTester histogram_tester_;

  optimization_guide::testing::TestHintsComponentCreator
      test_hints_component_creator_;

  base::Lock lock_;

  // Guarded by |lock_|.
  // Count of hints requests received so far by |hints_server_|.
  size_t count_hints_requests_received_ = 0;

  // Guarded by |lock_|. Set of hosts and URLs for which a hints request is
  // expected to arrive. This set is verified to match with the set of hosts and
  // URLs present in the hints request. If null, then the verification is not
  // done.
  absl::optional<base::flat_set<std::string>>
      expect_hints_request_for_hosts_and_urls_;

  std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_;

  DISALLOW_COPY_AND_ASSIGN(HintsFetcherDisabledBrowserTest);
};

// This test class enables OnePlatform Hints.
class HintsFetcherBrowserTest : public HintsFetcherDisabledBrowserTest {
 public:
  HintsFetcherBrowserTest() = default;

  ~HintsFetcherBrowserTest() override = default;

  void SetUp() override {
    // Enable OptimizationHintsFetching with |kRemoteOptimizationGuideFetching|.
    scoped_feature_list_.InitWithFeaturesAndParameters(
        {
            {optimization_guide::features::kOptimizationHints, {}},
            {optimization_guide::features::kRemoteOptimizationGuideFetching,
             {{"max_concurrent_page_navigation_fetches", "2"},
              {"onload_delay_for_hints_fetching_ms", "200"}}},
            {optimization_guide::features::kOptimizationHintsFieldTrials,
             {{"allowed_field_trial_names",
               "scoped_feature_list_trial_for_OptimizationHintsFetching"}}},
        },
        {});
    // Call to inherited class to match same set up with feature flags added.
    HintsFetcherDisabledBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    // Register an optimization type, so hints will be fetched at page
    // navigation.
    OptimizationGuideKeyedServiceFactory::GetForProfile(
        Profile::FromBrowserContext(browser()
                                        ->tab_strip_model()
                                        ->GetActiveWebContents()
                                        ->GetBrowserContext()))
        ->RegisterOptimizationTypes({optimization_guide::proto::NOSCRIPT});

    HintsFetcherDisabledBrowserTest::SetUpOnMainThread();
  }

  optimization_guide::TopHostProvider* top_host_provider() {
    OptimizationGuideKeyedService* keyed_service =
        OptimizationGuideKeyedServiceFactory::GetForProfile(
            browser()->profile());
    return keyed_service->GetTopHostProvider();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(HintsFetcherBrowserTest);
};

// This test creates new browser with no profile and loads a random page with
// the feature flags for OptimizationHintsFetching. We confirm that the
// TopHostProvider is called and does not crash by checking UMA
// histograms for the total number of TopEngagementSites and
// the total number of sites returned controlled by the experiments flag
// |max_oneplatform_update_hosts|.
IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest, HintsFetcherEnabled) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherDisabledBrowserTest, HintsFetcherDisabled) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Expect that the histogram for HintsFetcher to be 0 because the OnePlatform
  // is not enabled.
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 0);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcherFetchedHintsLoaded) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();
  GURL url = https_url();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1),
            1);

  LoadHintsForUrl(https_url());

  ui_test_utils::NavigateToURL(browser(), https_url());

  // Verifies that the fetched hint is just used in memory and nothing is
  // loaded.
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintCache.HintType.Loaded", 0);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcherWithResponsesSuccessful) {
  SetResponseType(HintsFetcherRemoteResponseType::kSuccessful);

  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  // Wait until histograms have been updated before performing checks for
  // correct behavior based on the response.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcherWithResponsesUnsuccessful) {
  SetResponseType(HintsFetcherRemoteResponseType::kUnsuccessful);

  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  // Wait until histograms have been updated before performing checks for
  // correct behavior based on the response.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status",
      net::HTTP_NOT_FOUND, 1);
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 0);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcherWithResponsesMalformed) {
  SetResponseType(HintsFetcherRemoteResponseType::kMalformed);

  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  // Wait until histograms have been updated before performing checks for
  // correct behavior based on the response.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 0);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcherWithResponsesUnsuccessfulAtNavigationTime) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  SetResponseType(HintsFetcherRemoteResponseType::kUnsuccessful);

  // Set the ECT to force a fetch at navigation time.
  g_browser_process->network_quality_tracker()
      ->ReportEffectiveConnectionTypeForTesting(
          net::EFFECTIVE_CONNECTION_TYPE_2G);

  ui_test_utils::NavigateToURL(browser(), GURL("https://unsuccessful.com/"));

  // We expect that we requested hints for 1 URL.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.UrlCount", 1),
            1);
}

IN_PROC_BROWSER_TEST_F(
    HintsFetcherBrowserTest,
    HintsFetcherWithResponsesHungShouldRecordWhenActiveRequestCanceled) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  SetResponseType(HintsFetcherRemoteResponseType::kHung);

  // Set the ECT to force a fetch at navigation time.
  g_browser_process->network_quality_tracker()
      ->ReportEffectiveConnectionTypeForTesting(
          net::EFFECTIVE_CONNECTION_TYPE_2G);

  ui_test_utils::NavigateToURL(browser(), GURL("https://hung.com/1"));
  ui_test_utils::NavigateToURL(browser(), GURL("https://hung.com/2"));
  ui_test_utils::NavigateToURL(browser(), GURL("https://hung.com/3"));

  // We expect that one request was canceled.
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.ActiveRequestCanceled."
      "PageNavigation",
      1, 1);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest, HintsFetcherClearFetchedHints) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();
  GURL url = https_url();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as OnePlatform Hints are enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1),
            1);

  LoadHintsForUrl(https_url());

  ui_test_utils::NavigateToURL(browser(), https_url());

  // Verifies that the fetched hint is used in-memory and no hint is loaded
  // from store.
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintCache.HintType.Loaded", 0);

  // Wipe the browser history - clear all the fetched hints.
  browser()->profile()->Wipe();

  // Wait until hint cache stabilizes and clears all the fetched hints.
  base::ThreadPoolInstance::Get()->FlushForTesting();
  base::RunLoop().RunUntilIdle();

  // Try to load the same hint to confirm fetched hints are no longer there.
  LoadHintsForUrl(https_url());

  ui_test_utils::NavigateToURL(browser(), https_url());

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintCache.HintType.Loaded",
      static_cast<int>(optimization_guide::OptimizationGuideStore::
                           StoreEntryType::kComponentHint),
      1);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest, HintsFetcherOverrideTimer) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();
  GURL url = https_url();
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      optimization_guide::switches::kFetchHintsOverride, "whatever.com");
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      optimization_guide::switches::kFetchHintsOverrideTimer);

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as OnePlatform Hints are enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  // There should be 2 sites in the engagement service.
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 2, 1);

  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);
  // There should have been 1 hint returned in the response.
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);

  LoadHintsForUrl(https_url());

  ui_test_utils::NavigateToURL(browser(), https_url());

  // Verifies that the fetched hint is used from memory and no hints are loaded.
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintCache.HintType.Loaded", 0);
}

// TODO(crbug.com/1177122) Re-enable test
IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       DISABLED_HintsFetcherNetworkOffline) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();
  GURL url = https_url();
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      optimization_guide::switches::kFetchHintsOverride, "whatever.com");
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      optimization_guide::switches::kFetchHintsOverrideTimer);

  // Set the network to be offline.
  SetNetworkConnectionOffline();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // No HintsFetch should occur because the connection is offline.
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 0);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest, HintsFetcherFetches) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as hints fetching is enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
}

// Test that the hints are fetched at the time of the navigation.
IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcher_NavigationFetch_ECT) {
  {
    base::HistogramTester histogram_tester;

    // Whitelist NoScript for https_url()'s' host.
    SetUpComponentUpdateHints(https_url());

    RetryForHistogramUntilCountReached(
        &histogram_tester,
        optimization_guide::kComponentHintsUpdatedResultHistogramString, 1);

    // Expect that the browser initialization will record at least one sample
    // in each of the following histograms as One Platform Hints are enabled.
    EXPECT_GE(
        RetryForHistogramUntilCountReached(
            &histogram_tester,
            "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
        1);

    EXPECT_GE(RetryForHistogramUntilCountReached(
                  &histogram_tester,
                  "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
              1);

    histogram_tester.ExpectUniqueSample(
        "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK,
        1);
    histogram_tester.ExpectUniqueSample(
        "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
        1);
    histogram_tester.ExpectUniqueSample(
        "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
    EXPECT_EQ(1u, count_hints_requests_received());
  }

  // Change ECT to a low value. Hints should be fetched at the time of
  // navigation.
  {
    base::HistogramTester histogram_tester;
    ukm::TestAutoSetUkmRecorder ukm_recorder;
    ResetCountHintsRequestsReceived();

    g_browser_process->network_quality_tracker()
        ->ReportEffectiveConnectionTypeForTesting(
            net::EFFECTIVE_CONNECTION_TYPE_2G);

    // Navigate to a host not in the seeded site engagement service; it
    // should be recorded as covered by the hints fetcher due to the race.
    base::flat_set<std::string> expected_request_2g;
    std::string host_2g("https://unseenhost_2g.com/");
    expected_request_2g.insert(GURL(host_2g).host());
    expected_request_2g.insert(GURL(host_2g).spec());
    SetExpectedHintsRequestForHostsAndUrls(expected_request_2g);
    ui_test_utils::NavigateToURL(browser(), GURL(host_2g));

    EXPECT_EQ(1u, count_hints_requests_received());
    RetryForHistogramUntilCountReached(
        &histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);
    // Navigate away so metrics are recorded.
    g_browser_process->network_quality_tracker()
        ->ReportEffectiveConnectionTypeForTesting(
            net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
    ui_test_utils::NavigateToURL(browser(), GURL("http://nohints.com/"));
    auto entries = ukm_recorder.GetEntriesByName(
        ukm::builders::OptimizationGuide::kEntryName);
    EXPECT_EQ(1u, entries.size());
    auto* entry = entries[0];
    EXPECT_TRUE(ukm_recorder.EntryHasMetric(
        entry, ukm::builders::OptimizationGuide::
                   kNavigationHintsFetchRequestLatencyName));
    EXPECT_TRUE(ukm_recorder.EntryHasMetric(
        entry, ukm::builders::OptimizationGuide::
                   kNavigationHintsFetchAttemptStatusName));
    ukm_recorder.ExpectEntryMetric(
        entry,
        ukm::builders::OptimizationGuide::
            kNavigationHintsFetchAttemptStatusName,
        static_cast<int>(optimization_guide::RaceNavigationFetchAttemptStatus::
                             kRaceNavigationFetchHostAndURL));
  }

  // Change ECT to unknown. Hints should not be fetched at the time of
  // navigation as the ECT is unknown so the fetcher should not race.
  {
    base::HistogramTester histogram_tester;
    ResetCountHintsRequestsReceived();

    g_browser_process->network_quality_tracker()
        ->ReportEffectiveConnectionTypeForTesting(
            net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);

    base::flat_set<std::string> expected_request_unknown;
    std::string host_unknown_ect("https://unseenhost_unknown_ect.com/");
    expected_request_unknown.insert((GURL(host_unknown_ect).host()));
    expected_request_unknown.insert((GURL(host_unknown_ect).spec()));
    SetExpectedHintsRequestForHostsAndUrls(expected_request_unknown);
    ui_test_utils::NavigateToURL(browser(), GURL(host_unknown_ect));

    EXPECT_EQ(0u, count_hints_requests_received());
    RetryForHistogramUntilCountReached(
        &histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);

    // Navigate away so metrics are recorded.
    base::HistogramTester prev_nav_histogram_tester;
    ukm::TestAutoSetUkmRecorder prev_nav_ukm_recorder;
    g_browser_process->network_quality_tracker()
        ->ReportEffectiveConnectionTypeForTesting(
            net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
    ui_test_utils::NavigateToURL(browser(), GURL("http://nohints.com/"));
    auto entries = prev_nav_ukm_recorder.GetEntriesByName(
        ukm::builders::OptimizationGuide::kEntryName);
    EXPECT_EQ(1u, entries.size());
    auto* entry = entries[0];
    EXPECT_FALSE(prev_nav_ukm_recorder.EntryHasMetric(
        entry, ukm::builders::OptimizationGuide::
                   kNavigationHintsFetchRequestLatencyName));
    EXPECT_FALSE(prev_nav_ukm_recorder.EntryHasMetric(
        entry, ukm::builders::OptimizationGuide::
                   kNavigationHintsFetchAttemptStatusName));
  }

  // Change ECT back to a low value. Hints should be fetched at the time of
  // navigation.
  {
    base::HistogramTester histogram_tester;
    ResetCountHintsRequestsReceived();

    g_browser_process->network_quality_tracker()
        ->ReportEffectiveConnectionTypeForTesting(
            net::EFFECTIVE_CONNECTION_TYPE_3G);

    // Navigate to a host not in the seeded site engagement service; it
    // should be recorded as not covered by the hints fetcher.
    base::flat_set<std::string> expected_request_3g;
    std::string host_3g("https://unseenhost_3g.com/");
    expected_request_3g.insert(GURL(host_3g).host());
    expected_request_3g.insert(GURL(host_3g).spec());
    SetExpectedHintsRequestForHostsAndUrls(expected_request_3g);
    ui_test_utils::NavigateToURL(browser(), GURL(host_3g));

    EXPECT_EQ(1u, count_hints_requests_received());
    RetryForHistogramUntilCountReached(
        &histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);

    // Navigate away so metrics are recorded.
    base::HistogramTester prev_nav_histogram_tester;
    ukm::TestAutoSetUkmRecorder prev_nav_ukm_recorder;
    g_browser_process->network_quality_tracker()
        ->ReportEffectiveConnectionTypeForTesting(
            net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
    ui_test_utils::NavigateToURL(browser(), GURL("http://nohints.com/"));
    auto entries = prev_nav_ukm_recorder.GetEntriesByName(
        ukm::builders::OptimizationGuide::kEntryName);
    EXPECT_EQ(1u, entries.size());
    auto* entry = entries[0];
    EXPECT_TRUE(prev_nav_ukm_recorder.EntryHasMetric(
        entry, ukm::builders::OptimizationGuide::
                   kNavigationHintsFetchRequestLatencyName));
    EXPECT_TRUE(prev_nav_ukm_recorder.EntryHasMetric(
        entry, ukm::builders::OptimizationGuide::
                   kNavigationHintsFetchAttemptStatusName));
    prev_nav_ukm_recorder.ExpectEntryMetric(
        entry,
        ukm::builders::OptimizationGuide::
            kNavigationHintsFetchAttemptStatusName,
        static_cast<int>(optimization_guide::RaceNavigationFetchAttemptStatus::
                             kRaceNavigationFetchHostAndURL));
  }

  // Navigate again to a webpage with the
  // same host. Hints should be available at the time of
  // navigation.
  {
    base::HistogramTester histogram_tester;
    ResetCountHintsRequestsReceived();

    g_browser_process->network_quality_tracker()
        ->ReportEffectiveConnectionTypeForTesting(
            net::EFFECTIVE_CONNECTION_TYPE_3G);

    // Navigate to a host that was recently fetched. It
    // should be recorded as covered by the hints fetcher.
    base::flat_set<std::string> expected_request_3g;
    std::string host_3g("https://unseenhost_3g.com");
    expected_request_3g.insert(GURL(host_3g).host());
    expected_request_3g.insert(GURL(host_3g).spec());
    SetExpectedHintsRequestForHostsAndUrls(expected_request_3g);
    ui_test_utils::NavigateToURL(browser(),
                                 GURL("https://unseenhost_3g.com/test1.html"));

    // With URL-keyed Hints, every unique URL navigated to will result in a
    // hints fetch if racing is enabled and allowed.
    EXPECT_EQ(1u, count_hints_requests_received());
    RetryForHistogramUntilCountReached(
        &histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);
    // Navigate away so metrics are recorded.
    base::HistogramTester prev_nav_histogram_tester;
    ukm::TestAutoSetUkmRecorder prev_nav_ukm_recorder;
    g_browser_process->network_quality_tracker()
        ->ReportEffectiveConnectionTypeForTesting(
            net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
    ui_test_utils::NavigateToURL(browser(), GURL("http://nohints.com/"));
    auto entries = prev_nav_ukm_recorder.GetEntriesByName(
        ukm::builders::OptimizationGuide::kEntryName);
    EXPECT_EQ(1u, entries.size());
    auto* entry = entries[0];
    EXPECT_TRUE(prev_nav_ukm_recorder.EntryHasMetric(
        entry, ukm::builders::OptimizationGuide::
                   kNavigationHintsFetchRequestLatencyName));
    EXPECT_TRUE(prev_nav_ukm_recorder.EntryHasMetric(
        entry, ukm::builders::OptimizationGuide::
                   kNavigationHintsFetchAttemptStatusName));
    prev_nav_ukm_recorder.ExpectEntryMetric(
        entry,
        ukm::builders::OptimizationGuide::
            kNavigationHintsFetchAttemptStatusName,
        static_cast<int>(optimization_guide::RaceNavigationFetchAttemptStatus::
                             kRaceNavigationFetchHostAndURL));
  }
}

// Test that the hints are fetched at the time of the navigation.
IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcher_NavigationFetch_URLKeyedNotRefetched) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  RetryForHistogramUntilCountReached(
      histogram_tester,
      optimization_guide::kComponentHintsUpdatedResultHistogramString, 1);

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
  EXPECT_EQ(1u, count_hints_requests_received());

  // Setting the connection type to be slow so the page navigation race fetch
  // is initiated.
  g_browser_process->network_quality_tracker()
      ->ReportEffectiveConnectionTypeForTesting(
          net::EFFECTIVE_CONNECTION_TYPE_2G);
  std::string full_url("https://foo.com/test/");
  {
    // Navigate to a host not in the seeded site engagement service; it
    // should be recorded as a race for both the host and the URL.
    base::flat_set<std::string> expected_request;
    expected_request.insert(GURL(full_url).host());
    expected_request.insert(GURL(full_url).spec());
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ui_test_utils::NavigateToURL(browser(), GURL(full_url));

    EXPECT_EQ(2u, count_hints_requests_received());
    RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);
    histogram_tester->ExpectUniqueSample(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchHostAndURL,
        1);
  }

  // Navigate again to the same webpage, no race should occur.
  {
    // Navigate to a host that was recently fetched. It
    // should be recorded as covered by the hints fetcher.
    base::flat_set<std::string> expected_request;
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ui_test_utils::NavigateToURL(browser(), GURL(full_url));

    // With URL-keyed Hints, every unique URL navigated to will result in a
    // hints fetch if racing is enabled and allowed.
    EXPECT_EQ(2u, count_hints_requests_received());
    RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        2);

    // Only the host will be attempted to race, the fetcher should block the
    // host from being fetched.
    histogram_tester->ExpectBucketCount(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchNotAttempted,
        1);
  }

  // Incognito page loads should not initiate any fetches.
  {
    base::HistogramTester incognito_histogram_tester;
    // Instantiate off the record Optimization Guide Service.
    OptimizationGuideKeyedServiceFactory::GetForProfile(
        browser()->profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true))
        ->RegisterOptimizationTypes({optimization_guide::proto::NOSCRIPT});

    Browser* otr_browser = CreateIncognitoBrowser(browser()->profile());
    ui_test_utils::NavigateToURL(otr_browser, GURL(full_url));

    // Make sure no additional hints requests were received.
    RetryForHistogramUntilCountReached(
        &incognito_histogram_tester,
        optimization_guide::kLoadedHintLocalHistogramString, 1);
    EXPECT_EQ(2u, count_hints_requests_received());

    incognito_histogram_tester.ExpectTotalCount(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus", 0);
  }
}

// Test that the hints are fetched at the time of the navigation.
IN_PROC_BROWSER_TEST_F(
    HintsFetcherBrowserTest,
    HintsFetcher_NavigationFetch_FetchWithNewlyRegisteredOptType) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  RetryForHistogramUntilCountReached(
      histogram_tester,
      optimization_guide::kComponentHintsUpdatedResultHistogramString, 1);

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
  EXPECT_EQ(1u, count_hints_requests_received());

  // Setting the connection type to be slow so the page navigation race fetch
  // is initiated.
  g_browser_process->network_quality_tracker()
      ->ReportEffectiveConnectionTypeForTesting(
          net::EFFECTIVE_CONNECTION_TYPE_2G);
  std::string full_url("https://foo.com/test/");
  {
    // Navigate to a host not in the seeded site engagement service; it
    // should be recorded as a race for both the host and the URL.
    base::flat_set<std::string> expected_request;
    expected_request.insert(GURL(full_url).host());
    expected_request.insert(GURL(full_url).spec());
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ui_test_utils::NavigateToURL(browser(), GURL(full_url));

    EXPECT_EQ(2u, count_hints_requests_received());
    RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);
    histogram_tester->ExpectUniqueSample(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchHostAndURL,
        1);
  }

  OptimizationGuideKeyedServiceFactory::GetForProfile(
      Profile::FromBrowserContext(browser()
                                      ->tab_strip_model()
                                      ->GetActiveWebContents()
                                      ->GetBrowserContext()))
      ->RegisterOptimizationTypes(
          {optimization_guide::proto::COMPRESS_PUBLIC_IMAGES});

  // Navigate again to the same webpage, the race should occur because the
  // hints have been cleared.
  {
    // Navigate to a host that was recently fetched. It
    // should be recorded as covered by the hints fetcher.
    base::flat_set<std::string> expected_request;
    expected_request.insert(GURL(full_url).host());
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ui_test_utils::NavigateToURL(browser(), GURL(full_url));

    // With URL-keyed Hints, every unique URL navigated to will result in a
    // hints fetch if racing is enabled and allowed.
    EXPECT_EQ(3u, count_hints_requests_received());
    RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        2);

    histogram_tester->ExpectBucketCount(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchHost,
        1);
  }
}

// Test that the hints are fetched at the time of the navigation.
IN_PROC_BROWSER_TEST_F(
    HintsFetcherBrowserTest,
    HintsFetcher_NavigationFetch_CacheNotClearedOnLaunchedOptTypes) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  RetryForHistogramUntilCountReached(
      histogram_tester,
      optimization_guide::kComponentHintsUpdatedResultHistogramString, 1);

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
  EXPECT_EQ(1u, count_hints_requests_received());

  // Setting the connection type to be slow so the page navigation race fetch
  // is initiated.
  g_browser_process->network_quality_tracker()
      ->ReportEffectiveConnectionTypeForTesting(
          net::EFFECTIVE_CONNECTION_TYPE_2G);
  std::string full_url("https://foo.com/test/");
  {
    // Navigate to a host not in the seeded site engagement service; it
    // should be recorded as a race for both the host and the URL.
    base::flat_set<std::string> expected_request;
    expected_request.insert(GURL(full_url).host());
    expected_request.insert(GURL(full_url).spec());
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ui_test_utils::NavigateToURL(browser(), GURL(full_url));

    EXPECT_EQ(2u, count_hints_requests_received());
    RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);
    histogram_tester->ExpectUniqueSample(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchHostAndURL,
        1);
  }

  OptimizationGuideKeyedServiceFactory::GetForProfile(
      Profile::FromBrowserContext(browser()
                                      ->tab_strip_model()
                                      ->GetActiveWebContents()
                                      ->GetBrowserContext()))
      ->RegisterOptimizationTypes(
          {optimization_guide::proto::DEFER_ALL_SCRIPT});

  // Navigate again to the same webpage, no race should occur.
  {
    // Navigate to a host that was recently fetched. It
    // should be recorded as covered by the hints fetcher.
    base::flat_set<std::string> expected_request;
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ui_test_utils::NavigateToURL(browser(), GURL(full_url));

    // With URL-keyed Hints, every unique URL navigated to will result in a
    // hints fetch if racing is enabled and allowed.
    EXPECT_EQ(2u, count_hints_requests_received());
    RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        2);

    // Only the host will be attempted to race, the fetcher should block the
    // host from being fetched.
    histogram_tester->ExpectBucketCount(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchNotAttempted,
        1);
  }
}

class HintsFetcherSearchPageBrowserTest : public HintsFetcherBrowserTest {
  void SetUpCommandLine(base::CommandLine* cmd) override {
    cmd->AppendSwitch(optimization_guide::switches::
                          kDisableFetchingHintsAtNavigationStartForTesting);
    cmd->AppendSwitch("ignore-certificate-errors");
    HintsFetcherBrowserTest::SetUpCommandLine(cmd);
  }
};

IN_PROC_BROWSER_TEST_F(HintsFetcherSearchPageBrowserTest,
                       HintsFetcher_SRP_Slow_Connection) {
  g_browser_process->network_quality_tracker()
      ->ReportEffectiveConnectionTypeForTesting(
          net::EFFECTIVE_CONNECTION_TYPE_2G);

  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Whitelist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 1),
            1);

  EXPECT_GE(RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);

  // Populate expected hosts with hosts contained in the html response of
  // search_results_page_url(). example2.com is contained in the HTML
  // response, but hints for example2.com must not be fetched since they
  // were pushed via kFetchHintsOverride switch above.
  base::flat_set<std::string> expected_hosts_and_urls;
  // Unique hosts.
  expected_hosts_and_urls.insert(GURL("https://foo.com").host());
  expected_hosts_and_urls.insert(GURL("https://example.com").host());
  expected_hosts_and_urls.insert(GURL("https://example3.com").host());
  // Unique URLs.
  expected_hosts_and_urls.insert("https://foo.com/");
  expected_hosts_and_urls.insert(
      "https://foo.com/simple_page_with_anchors.html");
  expected_hosts_and_urls.insert("https://example.com/foo.html");
  expected_hosts_and_urls.insert("https://example.com/bar.html");
  expected_hosts_and_urls.insert("https://example.com/baz.html");
  expected_hosts_and_urls.insert("https://example2.com/foo.html");
  expected_hosts_and_urls.insert("https://example3.com/foo.html");
  SetExpectedHintsRequestForHostsAndUrls(expected_hosts_and_urls);

  histogram_tester->ExpectTotalCount(
      optimization_guide::kLoadedHintLocalHistogramString, 0);

  // Navigate to a host not in the seeded site engagement service; it
  // should be recorded as not covered by the hints fetcher.
  ResetCountHintsRequestsReceived();
  ui_test_utils::NavigateToURL(browser(), search_results_page_url());

  WaitUntilHintsFetcherRequestReceived();
  EXPECT_EQ(1u, count_hints_requests_received());
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 3, 1);
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.UrlCount", 7, 1);
}
