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

#include "base/memory/raw_ptr.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_clock.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "chrome/browser/captive_portal/captive_portal_service_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/extensions/api/settings_private/generated_prefs.h"
#include "chrome/browser/interstitials/security_interstitial_page_test_utils.h"
#include "chrome/browser/preloading/scoped_prewarm_feature_list.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
#include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h"
#include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
#include "chrome/browser/ssl/ask_before_http_dialog_controller.h"
#include "chrome/browser/ssl/chrome_security_blocking_page_factory.h"
#include "chrome/browser/ssl/chrome_security_state_util.h"
#include "chrome/browser/ssl/generated_https_first_mode_pref.h"
#include "chrome/browser/ssl/https_first_mode_settings_tracker.h"
#include "chrome/browser/ssl/https_upgrades_interceptor.h"
#include "chrome/browser/ssl/https_upgrades_navigation_throttle.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "chrome/browser/ui/omnibox/omnibox_controller.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/captive_portal/content/captive_portal_service.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/embedder_support/pref_names.h"
#include "components/enterprise/isolated_mode/isolated_mode_features.h"
#include "components/omnibox/browser/omnibox_client.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/core/browser/db/fake_database_manager.h"
#include "components/safe_browsing/core/common/threat_enums.h"
#include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h"
#include "components/security_interstitials/core/features.h"
#include "components/security_interstitials/core/https_only_mode_metrics.h"
#include "components/security_interstitials/core/metrics_helper.h"
#include "components/site_engagement/content/site_engagement_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/tabs/public/tab_interface.h"
#include "components/ukm/test_ukm_recorder.h"
#include "components/variations/active_field_trials.h"
#include "components/variations/hashing.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/content_mock_cert_verifier.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/url_loader_interceptor.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_util.h"
#include "net/test/cert_test_util.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/request_handler_util.h"
#include "net/test/test_data_directory.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "services/network/public/cpp/ip_address_space_overrides_test_utils.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
#include "services/network/public/mojom/ip_address_space.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/window_open_disposition.h"
#include "url/url_constants.h"

#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && !BUILDFLAG(IS_CHROMEOS)
#include "chrome/test/base/scoped_channel_override.h"
#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING) && !BUILDFLAG(IS_CHROMEOS)

namespace {

[[nodiscard]] bool NavigateToURLWithLinkTransition(
    content::WebContents* web_contents,
    const GURL& url,
    const GURL& expected_commit_url) {
  content::TestNavigationObserver nav_observer(web_contents, 1);
  content::NavigationController::LoadURLParams params(url);
  params.transition_type = ui::PAGE_TRANSITION_LINK;
  web_contents->GetController().LoadURLWithParams(params);
  nav_observer.Wait();
  return nav_observer.last_navigation_succeeded() &&
         web_contents->GetLastCommittedURL() == expected_commit_url;
}

[[nodiscard]] bool NavigateToURLWithLinkTransition(
    content::WebContents* web_contents,
    const GURL& url) {
  return NavigateToURLWithLinkTransition(web_contents, url, url);
}

void NavigateToURLWithLinkTransitionBlockUntilNavigationsComplete(
    content::WebContents* web_contents,
    const GURL& url,
    int number_of_navigations) {
  content::NavigationController::LoadURLParams params(url);
  params.transition_type = ui::PAGE_TRANSITION_LINK;
  content::NavigateToURLBlockUntilNavigationsComplete(web_contents, params,
                                                      number_of_navigations);
}

}  // namespace

using chrome_browser_interstitials::
    DontProceedThroughHttpsFirstModeInterstitial;
using chrome_browser_interstitials::GetHFMInterstitialType;
using chrome_browser_interstitials::HFMInterstitialType;
using chrome_browser_interstitials::IsInterstitialDisplayingText;
using chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial;
using chrome_browser_interstitials::IsShowingInterstitial;
using chrome_browser_interstitials::ProceedThroughHttpsFirstModeInterstitial;
using security_interstitials::https_only_mode::BlockingResult;
using security_interstitials::https_only_mode::Event;
using security_interstitials::https_only_mode::FallbackReason;
using security_interstitials::https_only_mode::InterstitialReason;
using security_interstitials::https_only_mode::kEventHistogram;
using security_interstitials::https_only_mode::
    kEventHistogramWithEngagementHeuristic;
using security_interstitials::https_only_mode::kInterstitialReasonHistogram;
using security_interstitials::https_only_mode::
    kNavigationRequestSecurityLevelHistogram;
using security_interstitials::https_only_mode::
    kSiteEngagementHeuristicAccumulatedHostCountHistogram;
using security_interstitials::https_only_mode::
    kSiteEngagementHeuristicEnforcementDurationHistogram;
using security_interstitials::https_only_mode::
    kSiteEngagementHeuristicHostCountHistogram;
using security_interstitials::https_only_mode::
    kSiteEngagementHeuristicStateHistogram;
using security_interstitials::https_only_mode::NavigationRequestSecurityLevel;
using security_interstitials::https_only_mode::SiteEngagementHeuristicState;
using UkmEntry = ukm::builders::HttpsFirstMode_Event;

// Many of the following tests have only minor variations for HTTPS-First Mode
// vs. HTTPS-Upgrades. These get parameterized so the tests run under both
// versions on their own as well as when both HTTPS Upgrades and HTTPS-First
// Mode are enabled (to test any interactions between the two upgrade modes).
// HTTPS-Upgrades is now enabled by default, so all of these variations build
// on top of that baseline.
//
// Quick summary of all features tested here:
// * HTTPS-Upgrades:
//     Automatically upgrades main frame navigations to HTTPS. Silently falls
//     back to HTTP on failure.
// * HTTPS First Mode:
//     Automatically upgrades main frame navigations to HTTPS. Shows an
//     interstitial on failure.
// * HTTPS First Mode With Site Engagement:
//     Automatically enables HTTPS First Mode for sites that are visited mainly
//     over HTTPS.
// * HTTPS First Mode for Typically Secure Users
//     Automatically enables HTTPS First Mode for users that mainly visit HTTPS
//     sites.
// * HTTPS First Mode in Incognito:
//     Automatically enables HTTPS First Mode in Incognito windows.
// * HTTPS First Balanced Mode:
//     Enables HTTPS First Mode like full HFM, but exempt navigations that are
//     likely to fail.
// * HTTPS First Balanced Mode with old UI:
//     Same as Balanced Mode, but uses the old UI for HTTPS-First
//     interstitials (all other variations use the default UI).
//
enum class HttpsUpgradesTestType {
  // Enables the HFM pref.
  kHttpsFirstModeOnly,

  // Enables HFM with Site Engagement heuristic.
  kHttpsFirstModeWithSiteEngagement,

  // Enables HFM for Typically Secure Users.
  kHttpsFirstModeForTypicallySecureUsers,

  // Enables HFM with Site Engagement and HFM for Typically Secure Users (both
  // automatically enable HFM). Disables BalancedModeByDefault as that case is
  // already tested by kHttpsFirstBalancedMode.
  kAllAutoHFM,

  // Enables HFM in Incognito mode. Runs testcases inside an Incognito
  // window.
  kHttpsFirstModeIncognito,

  // Enables HFM in Enterprise Isolated Mode, which replaces Incognito. Runs
  // testcases inside an Isolated Mode window. Behaves identically to
  // kHttpsFirstModeIncognito apart from the warning strings.
  kHttpsFirstModeIsolatedMode,

  // Enables HFM in balanced mode.
  kHttpsFirstBalancedMode,

  // Enables HFM for Advanced Protection users.
  kHttpsFirstModeAdvancedProtection,

  // Enables HFM pref, HFM with Site Engagement heuristic, HFM for typically
  // secure users, HFM in incognito, and balanced HFM feature flags.
  kAll,

  // Enables HFM in balanced mode but with the old interstitial UI.
  kHttpsFirstBalancedModeWithOldUi,

  // Disables HFM pref, HFM with Site Engagement heuristic, the HFM for
  // typically secure users feature, and the HFM in Incognito feature.
  kNone,

  // HttpsUpgradesBrowserTest tests don't run in these modes. They are used to
  // instantiate individual tests instead:

  // Enables HFM with Site Engagement heuristic without Balanced Mode. This
  // should be a no-op.
  kHttpsFirstModeWithSiteEngagementWithoutBalancedMode,
};

// Stores the number of times the HTTPS-First Mode interstitial is shown for the
// given reason.
struct ExpectedInterstitialReasons {
  // The number of times the interstitial was shown because the HFM pref was
  // enabled.
  size_t pref = 0;
  // The number of times the interstitial was shown because of the Typically
  // Secure User heuristic.
  size_t typically_secure_user = 0;
  // The number of times the interstitial was shown because of being in balanced
  // mode.
  size_t balanced = 0;
  // The number of times the interstitial was shown because of Advanced
  // Protection.
  size_t advanced_protection = 0;
};

// A very low site engagement score.
constexpr int kLowSiteEngagementScore = 1;
// A very high site engagement score.
constexpr int kHighSiteEnagementScore = 99;

// Tests for HTTPS-Upgrades and the v2 implementation of HTTPS-First Mode.
class HttpsUpgradesBrowserTest
    : public testing::WithParamInterface<HttpsUpgradesTestType>,
      public InProcessBrowserTest {
 public:
  HttpsUpgradesBrowserTest() = default;
  ~HttpsUpgradesBrowserTest() override = default;

  void SetUp() override {
    // HFM heuristics are disabled on enterprise managed machines, so some of
    // the tests may fail on bots. Explicitly set management status to false.
    // Some of the tests check enterprise policies, so this configuration is
    // unusual because non-enterprise machines are unlikely to have an
    // enterprise allowlist, but it's good for test coverage.
    ChromeSecurityBlockingPageFactory::SetEnterpriseManagedForTesting(false);

    // HFM is controlled by a pref (configured in SetUpOnMainThread).
    switch (https_upgrades_test_type()) {
      case HttpsUpgradesTestType::kHttpsFirstModeOnly:
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{security_interstitials::features::
                                      kHttpsFirstDialogUi},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForEngagedSites,
                features::kHttpsFirstModeV2ForTypicallySecureUsers});
        break;

      case HttpsUpgradesTestType::kHttpsFirstModeWithSiteEngagement:
        // HFM pref is disabled in SetUpOnMainThread.
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstModeV2ForEngagedSites,
                                  features::kHttpsFirstBalancedMode,
                                  security_interstitials::features::
                                      kHttpsFirstDialogUi},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstBalancedModeAutoEnable});
        break;

      case HttpsUpgradesTestType::
          kHttpsFirstModeWithSiteEngagementWithoutBalancedMode:
        // HFM pref is disabled in SetUpOnMainThread.
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstModeV2ForEngagedSites,
                                  security_interstitials::features::
                                      kHttpsFirstDialogUi},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstBalancedMode});
        break;

      case HttpsUpgradesTestType::kHttpsFirstModeForTypicallySecureUsers:
        // HFM pref is disabled in SetUpOnMainThread.
        feature_list_.InitWithFeatures(
            /*enabled_features=*/
            {features::kHttpsFirstModeV2ForTypicallySecureUsers,
             features::kHttpsFirstBalancedMode,
             security_interstitials::features::kHttpsFirstDialogUi},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForEngagedSites,
                features::kHttpsFirstBalancedModeAutoEnable});
        break;

      case HttpsUpgradesTestType::kAllAutoHFM:
        // HFM pref is disabled in SetUpOnMainThread.
        feature_list_.InitWithFeatures(
            /*enabled_features=*/
            {features::kHttpsFirstModeV2ForTypicallySecureUsers,
             features::kHttpsFirstModeV2ForEngagedSites,
             features::kHttpsFirstBalancedMode,
             security_interstitials::features::kHttpsFirstDialogUi},
            /*disabled_features=*/{
                features::kHttpsFirstBalancedModeAutoEnable});
        break;

      case HttpsUpgradesTestType::kHttpsFirstModeIncognito:
      case HttpsUpgradesTestType::kHttpsFirstModeIsolatedMode:
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstModeIncognito,
                                  security_interstitials::features::
                                      kHttpsFirstDialogUi},
            /*disabled_features=*/{});
        break;

      case HttpsUpgradesTestType::kHttpsFirstBalancedMode:
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstBalancedMode,
                                  features::kHttpsFirstBalancedModeAutoEnable,
                                  security_interstitials::features::
                                      kHttpsFirstDialogUi},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstModeV2ForEngagedSites});
        break;

      case HttpsUpgradesTestType::kHttpsFirstModeAdvancedProtection:
        feature_list_.InitWithFeatures(
            /*enabled_features=*/
            {features::kHttpsFirstModeForAdvancedProtectionUsers,
             features::kHttpsFirstBalancedModeAutoEnable,
             security_interstitials::features::kHttpsFirstDialogUi},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstModeV2ForEngagedSites});
        break;

      // Enable HFM, HFM with Site Engagement heuristic, HFM for typically
      // secure users, and HFM in Incognito.
      case HttpsUpgradesTestType::kAll:
        // HFM pref is enabled in SetUpOnMainThread.
        feature_list_.InitWithFeatures(
            /*enabled_features=*/
            {
                features::kHttpsFirstModeV2ForEngagedSites,
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstModeForAdvancedProtectionUsers,
                features::kHttpsFirstModeIncognito,
                features::kHttpsFirstBalancedMode,
                features::kHttpsFirstBalancedModeAutoEnable,
                security_interstitials::features::kHttpsFirstDialogUi,
            },
            /*disabled_features=*/{});
        break;

      case HttpsUpgradesTestType::kHttpsFirstBalancedModeWithOldUi:
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstBalancedMode,
                                  features::kHttpsFirstBalancedModeAutoEnable},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstModeV2ForEngagedSites,
                security_interstitials::features::kHttpsFirstDialogUi});
        break;

      // Disable HFM, HFM with Site Engagement heuristic, HFM for Typically
      // Secure Users, and HFM in Incognito. (HFM pref is disabled in
      // SetUpOnMainThread.) This is equivalent to the baseline default of
      // HTTPS-Upgrades.
      case HttpsUpgradesTestType::kNone:
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForEngagedSites,
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstBalancedMode,
                features::kHttpsFirstBalancedModeAutoEnable,
                features::kHttpsFirstModeForAdvancedProtectionUsers,
                security_interstitials::features::kHttpsFirstDialogUi});
        break;
    }

    InProcessBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    // By default allow all hosts on HTTPS.
    mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
    host_resolver()->AddRule("*", "127.0.0.1");

    // Set up "bad-https.com", "bad-https2.com", "nonunique-hostname-bad-https"
    // and "nonunique-hostname-bad-https2" as hostnames with an SSL error.
    // HTTPS upgrades to these hosts will fail.
    scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate());
    net::CertVerifyResult verify_result;
    verify_result.is_issued_by_known_root = false;
    verify_result.verified_cert = cert;
    verify_result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "bad-https.com", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "www.bad-https.com", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "bad-https2.com", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "nonunique-hostname-bad-https", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "nonunique-hostname-bad-https2", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);

    http_server_.AddDefaultHandlers(GetChromeTestDataDir());
    https_server_.AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(http_server_.Start());
    ASSERT_TRUE(https_server_.Start());

    HttpsUpgradesInterceptor::SetHttpsPortForTesting(https_server()->port());
    HttpsUpgradesInterceptor::SetHttpPortForTesting(http_server()->port());

    // Incognito and Isolated Mode tests swap out the default Browser instance
    // for an off-the-record window, and then should behave like
    // kHttpsFirstMode type tests but without enabling the full HFM pref.
    if (IsIncognitoMode() || IsIsolatedMode()) {
      UseIncognitoBrowser();
      SetPref(false);
    }

    if (https_upgrades_test_type() ==
        HttpsUpgradesTestType::kHttpsFirstModeAdvancedProtection) {
      safe_browsing::AdvancedProtectionStatusManagerFactory::GetForProfile(
          browser()->GetProfile())
          ->SetAdvancedProtectionStatusForTesting(true);
    }

    // Only enable the HTTPS-First Mode pref when the test config calls for it.
    // Some of the HFM heuristics check that the preference wasn't set so as
    // not to override user preference (e.g. if the user changed the pref by
    // turning it off from the UI, we don't want to override it).
    if (IsHttpsFirstModePrefEnabled()) {
      SetPref(true);
    }

    if (InBalancedMode()) {
      SetBalancedPref(true);
    }

    test_ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
  }

  void TearDownOnMainThread() override {
    browser()->GetProfile()->GetPrefs()->ClearPref(
        prefs::kHttpsOnlyModeEnabled);
    browser()->GetProfile()->GetPrefs()->ClearPref(
        prefs::kHttpsOnlyModeAutoEnabled);
    browser()->GetProfile()->GetPrefs()->ClearPref(
        prefs::kHttpsUpgradeFallbacks);
    browser()->GetProfile()->GetPrefs()->ClearPref(
        prefs::kHttpsUpgradeNavigations);
    browser()->GetProfile()->GetPrefs()->ClearPref(
        prefs::kHttpsFirstBalancedMode);

    HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
    HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    mock_cert_verifier_.SetUpCommandLine(command_line);

    if (IsIsolatedMode()) {
      command_line->AppendSwitch(
          enterprise_isolated_mode::switches::
              kForceEnterpriseIsolatedModeReplacesIncognito);
    }
  }

  void SetUpInProcessBrowserTestFixture() override {
    mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
  }

  void TearDownInProcessBrowserTestFixture() override {
    mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
  }

  // Incognito testing support
  //
  // Returns the active Browser for the test type being run.
  BrowserWindowInterface* GetBrowser() const {
    return incognito_browser_ ? incognito_browser_.get() : browser();
  }
  // Call to use an Incognito browser rather than the default.
  void UseIncognitoBrowser() {
    ASSERT_EQ(nullptr, incognito_browser_.get());
    incognito_browser_ = CreateIncognitoBrowser();
    ASSERT_EQ(
        IsIsolatedMode(),
        incognito_browser_->GetProfile()->IsEnterpriseIsolatedModeProfile());
  }
  // Returns true if the test is running in the off-the-record browser window,
  // which is used by both the Incognito and the Isolated Mode test types.
  bool IsIncognitoOrIsolatedBrowser() const {
    return incognito_browser_ != nullptr;
  }
  bool IsIncognitoMode() const {
    return https_upgrades_test_type() ==
           HttpsUpgradesTestType::kHttpsFirstModeIncognito;
  }
  bool IsIsolatedMode() const {
    return https_upgrades_test_type() ==
           HttpsUpgradesTestType::kHttpsFirstModeIsolatedMode;
  }

  bool OnlyInBalancedMode() const {
    return https_upgrades_test_type() ==
               HttpsUpgradesTestType::kHttpsFirstBalancedMode ||
           https_upgrades_test_type() ==
               HttpsUpgradesTestType::kHttpsFirstBalancedModeWithOldUi;
  }
  bool InBalancedMode() const {
    return https_upgrades_test_type() ==
               HttpsUpgradesTestType::kHttpsFirstBalancedMode ||
           https_upgrades_test_type() ==
               HttpsUpgradesTestType::kHttpsFirstBalancedModeWithOldUi ||
           https_upgrades_test_type() == HttpsUpgradesTestType::kAll;
  }

 protected:
  HttpsUpgradesTestType https_upgrades_test_type() const { return GetParam(); }

  void SetPref(bool enabled) {
    auto* prefs = browser()->GetProfile()->GetPrefs();
    prefs->SetBoolean(prefs::kHttpsOnlyModeEnabled, enabled);
  }

  bool GetPref() const {
    auto* prefs = browser()->GetProfile()->GetPrefs();
    return prefs->GetBoolean(prefs::kHttpsOnlyModeEnabled);
  }

  void SetBalancedPref(bool enabled) {
    auto* prefs = browser()->GetProfile()->GetPrefs();
    prefs->SetBoolean(prefs::kHttpsFirstBalancedMode, enabled);
  }

  bool GetBalancedPref() const {
    auto* prefs = browser()->GetProfile()->GetPrefs();
    return prefs->GetBoolean(prefs::kHttpsFirstBalancedMode);
  }

  void NavigateAndWaitForFallback(content::WebContents* tab, const GURL& url) {
    // TODO(crbug.com/40248833): With fallback as part of the same navigation,
    // this helper is no longer particularly useful. Consider updating callers.
    NavigateToURLWithLinkTransitionBlockUntilNavigationsComplete(tab, url, 1);
  }

  // Whether HFM is enabled by the UI setting.
  bool IsHttpsFirstModePrefEnabled() const {
    return https_upgrades_test_type() ==
               HttpsUpgradesTestType::kHttpsFirstModeOnly ||
           https_upgrades_test_type() == HttpsUpgradesTestType::kAll;
  }

  // Whether HFM strict mode is enabled.
  bool IsStrictInterstitialEnabledForTest() const {
    return IsHttpsFirstModePrefEnabled() ||
           safe_browsing::AdvancedProtectionStatusManagerFactory::GetForProfile(
               browser()->GetProfile())
               ->IsUnderAdvancedProtection();
  }

  // Whether HFM is enabled for many sites, and thus the tests should run steps
  // that assume the HTTP interstitial will trigger (i.e., for fallback HTTP
  // navigations when HTTPS-First Mode is enabled).
  bool IsHttpsFirstModeInterstitialEnabledAcrossSites() const {
    return IsHttpsFirstModePrefEnabled() || InBalancedMode() ||
           IsIncognitoOrIsolatedBrowser() ||
           safe_browsing::AdvancedProtectionStatusManagerFactory::GetForProfile(
               browser()->GetProfile())
               ->IsUnderAdvancedProtection();
  }

  // Whether HTTPS-First Mode with Site Engagement Heuristic is enabled. When
  // enabled, this feature will enable HFM on sites that have high Site
  // Engagement scores on their HTTPS URLs. HFM with Site Engagement requires
  // HTTPS-Upgrades to be enabled.
  bool IsSiteEngagementHeuristicEnabled() const {
    bool enabled =
        https_upgrades_test_type() ==
            HttpsUpgradesTestType::kHttpsFirstModeWithSiteEngagement ||
        https_upgrades_test_type() == HttpsUpgradesTestType::kAllAutoHFM ||
        https_upgrades_test_type() == HttpsUpgradesTestType::kAll;
    return enabled;
  }

  // Whether automatic HTTPS-First Mode for typically secure users is enabled.
  // When enabled, this feature will enable HFM for users who would see HFM
  // warnings very rarely. HFM for typically secure users requires
  // HTTPS-Upgrades to be enabled.
  bool IsTypicallySecureUserFeatureEnabled() const {
    bool enabled =
        https_upgrades_test_type() ==
            HttpsUpgradesTestType::kHttpsFirstModeForTypicallySecureUsers ||
        https_upgrades_test_type() == HttpsUpgradesTestType::kAllAutoHFM ||
        https_upgrades_test_type() == HttpsUpgradesTestType::kAll;
    return enabled;
  }

  void SetSiteEngagementScore(const GURL& url, double score) {
    site_engagement::SiteEngagementService* service =
        site_engagement::SiteEngagementService::Get(browser()->GetProfile());
    service->ResetBaseScoreForURL(url, score);
    ASSERT_EQ(score, service->GetScore(url));
  }

  // Checks that the HTTPS-First Mode interstitial has been shown for the
  // correct reasons.
  void CheckInterstitialReasonHistogram(
      const ExpectedInterstitialReasons& expected_reasons) {
    histograms()->ExpectTotalCount(
        kInterstitialReasonHistogram,
        expected_reasons.pref + expected_reasons.typically_secure_user +
            expected_reasons.balanced + expected_reasons.advanced_protection);
    histograms()->ExpectBucketCount(kInterstitialReasonHistogram,
                                    static_cast<int>(InterstitialReason::kPref),
                                    expected_reasons.pref);
    histograms()->ExpectBucketCount(
        kInterstitialReasonHistogram,
        static_cast<int>(InterstitialReason::kBalanced),
        expected_reasons.balanced);
    histograms()->ExpectBucketCount(
        kInterstitialReasonHistogram,
        static_cast<int>(InterstitialReason::kTypicallySecureUserHeuristic),
        expected_reasons.typically_secure_user);
    histograms()->ExpectBucketCount(
        kInterstitialReasonHistogram,
        static_cast<int>(InterstitialReason::kAdvancedProtection),
        expected_reasons.advanced_protection);
  }

  // Verifies that an HFM interstitial is shown.
  void ExpectInterstitial(content::WebContents* contents) {
    EXPECT_EQ(HFMInterstitialType::kStandard, GetHFMInterstitialType(contents));
  }

  // Verifies that an HFM interstitial is shown only if the HFM-pref is enabled
  // or we're in balanced mode.
  void ExpectInterstitialOnlyIfPrefIsSetOrInBalancedMode(
      content::WebContents* contents) {
    if (IsHttpsFirstModePrefEnabled() || InBalancedMode()) {
      ExpectInterstitial(contents);
    } else {
      EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
    }
  }

  // Verifies that an HFM interstitial is shown either due to prefs being
  // enabled or typically secure heuristic.
  void MaybeExpectTypicallySecureInterstitial(content::WebContents* contents) {
    if (IsHttpsFirstModePrefEnabled() || InBalancedMode() ||
        IsTypicallySecureUserFeatureEnabled()) {
      // Typically secure interstitial should only be shown iff HFM is not
      // enabled by prefs.
      if (IsTypicallySecureUserFeatureEnabled() &&
          !IsHttpsFirstModePrefEnabled() && !InBalancedMode()) {
        EXPECT_EQ(HFMInterstitialType::kTypicallySecure,
                  GetHFMInterstitialType(contents));
      } else {
        // Otherwise, interstitial is enabled by prefs.
        EXPECT_EQ(HFMInterstitialType::kStandard,
                  GetHFMInterstitialType(contents));
      }
      return;
    }
    // Interstitial isn't enabled by the prefs or heuristic.
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  }

  base::SimpleTestClock* GetTestClock() { return &test_clock_; }

  // Prepare the profile so that HFM can be automatically enabled.
  void SatisfyTypicallySecureHeuristicRequirements() {
    base::SimpleTestClock* clock = GetTestClock();

    // The total engagement score of all sites must be over a certain threshold.
    SetSiteEngagementScore(GURL("https://google.com:12345"), 90);

    // Profile must be old enough.
    browser()->GetProfile()->SetCreationTimeForTesting(clock->Now() -
                                                       base::Days(30));
    hfm_service()->SetClockForTesting(clock);

    // There must be a lot of recorded navigations.
    for (size_t i = 0; i < 1500; i++) {
      hfm_service()->IncrementRecentNavigationCount();
    }
    clock->Advance(base::Days(15));

    // Navigate to an HTTP URL that will upgrade and fall back to HTTP.
    // This will start Typically Secure observation.
    GURL http_url("http://bad-https2.com/simple.html");
    content::WebContents* contents =
        GetBrowser()->GetTabStripModel()->GetActiveWebContents();
    NavigateToURLWithLinkTransitionBlockUntilNavigationsComplete(
        contents, http_url, /*number_of_navigations=*/1);
    ExpectInterstitialOnlyIfPrefIsSetOrInBalancedMode(contents);

    // Advance the clock and navigate to an HTTP URL again. This will drop the
    // first fallback event.
    clock->Advance(base::Days(35));
  }

  net::EmbeddedTestServer* http_server() { return &http_server_; }
  net::EmbeddedTestServer* https_server() { return &https_server_; }
  base::HistogramTester* histograms() { return &histograms_; }
  base::test::ScopedFeatureList* feature_list() { return &feature_list_; }

  HttpsFirstModeService* hfm_service() const {
    return HttpsFirstModeServiceFactory::GetForProfile(browser()->GetProfile());
  }

  // Checks that the interstitial UKM has an entry for `url` and `result`.
  void ExpectUKMEntry(
      const GURL& url,
      security_interstitials::https_only_mode::BlockingResult result) {
    auto entries = test_ukm_recorder_->GetEntriesByName(UkmEntry::kEntryName);
    EXPECT_EQ(1u, entries.size());

    test_ukm_recorder_->ExpectEntrySourceHasUrl(entries[0], url);
    test_ukm_recorder_->ExpectEntryMetric(entries[0], "Result",
                                          static_cast<int>(result));
  }

  // Checks that the interstitial UKM has an entry for `url`, `result` and
  // `fallback_reason`.
  void ExpectUKMEntryWithReason(
      const GURL& url,
      security_interstitials::https_only_mode::BlockingResult result,
      security_interstitials::https_only_mode::FallbackReason fallback_reason) {
    auto entries = test_ukm_recorder_->GetEntriesByName(UkmEntry::kEntryName);
    EXPECT_EQ(1u, entries.size());

    test_ukm_recorder_->ExpectEntrySourceHasUrl(entries[0], url);
    test_ukm_recorder_->ExpectEntryMetric(entries[0], "Result",
                                          static_cast<int>(result));
    test_ukm_recorder_->ExpectEntryMetric(entries[0], "FallbackReason",
                                          static_cast<int>(fallback_reason));
  }

  // Checks that the interstitial UKM has no entry.
  void ExpectEmptyUKM() {
    auto entries = test_ukm_recorder_->GetEntriesByName(UkmEntry::kEntryName);
    EXPECT_EQ(0u, entries.size());
  }

  void EnableCaptivePortalDetection(BrowserWindowInterface* browser);

 private:
#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && !BUILDFLAG(IS_CHROMEOS)
  chrome::ScopedChannelOverride channel_override_{
      chrome::ScopedChannelOverride::Channel::kDev};
#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING) && !BUILDFLAG(IS_CHROMEOS)
  // TODO(https://crbug.com/423465927): Explore a better approach to make the
  // existing tests run with the prewarm feature enabled.
  test::ScopedPrewarmFeatureList prewarm_feature_list_{
      test::ScopedPrewarmFeatureList::PrewarmState::kDisabled};
  base::test::ScopedFeatureList feature_list_;
  net::EmbeddedTestServer http_server_{net::EmbeddedTestServer::TYPE_HTTP};
  net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
  content::ContentMockCertVerifier mock_cert_verifier_;
  base::HistogramTester histograms_;
  raw_ptr<BrowserWindowInterface, AcrossTasksDanglingUntriaged>
      incognito_browser_ = nullptr;
  std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;

  // A clock that can be installed with
  // HttpsFirstModeService::SetClockForTesting(). This must outlive the test
  // because HttpsFirstModeService can access it from shutdown tasks that run
  // during PostRunTestOnMainThread().
  base::SimpleTestClock test_clock_;
};

// HttpsUpgradesBrowserTest is NOT instantiated for unusual configurations like
// kHttpsFirstModeWithSiteEngagementWithoutBalancedMode.
INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    HttpsUpgradesBrowserTest,
    ::testing::Values(
        HttpsUpgradesTestType::kHttpsFirstModeOnly,
        HttpsUpgradesTestType::kHttpsFirstModeWithSiteEngagement,
        HttpsUpgradesTestType::kHttpsFirstModeForTypicallySecureUsers,
        HttpsUpgradesTestType::kAllAutoHFM,
        HttpsUpgradesTestType::kHttpsFirstModeIncognito,
        HttpsUpgradesTestType::kHttpsFirstModeIsolatedMode,
        HttpsUpgradesTestType::kHttpsFirstBalancedMode,
        HttpsUpgradesTestType::kHttpsFirstModeAdvancedProtection,
        HttpsUpgradesTestType::kAll,
        HttpsUpgradesTestType::kHttpsFirstBalancedModeWithOldUi,
        HttpsUpgradesTestType::kNone),
    // Map param to a human-readable string for better test output.
    [](testing::TestParamInfo<HttpsUpgradesTestType> input_type)
        -> std::string {
      switch (input_type.param) {
        case HttpsUpgradesTestType::kHttpsFirstModeOnly:
          return "HttpsFirstModeOnly";
        case HttpsUpgradesTestType::kHttpsFirstModeWithSiteEngagement:
          return "HttpsFirstModeWithSiteEngagement";
        case HttpsUpgradesTestType::kHttpsFirstModeForTypicallySecureUsers:
          return "HttpsFirstModeForTypicallySecureUsers";
        case HttpsUpgradesTestType::kAllAutoHFM:
          return "AllAutoHFM";
        case HttpsUpgradesTestType::kHttpsFirstModeIncognito:
          return "HttpsFirstModeIncognito";
        case HttpsUpgradesTestType::kHttpsFirstModeIsolatedMode:
          return "HttpsFirstModeIsolatedMode";
        case HttpsUpgradesTestType::kHttpsFirstBalancedMode:
          return "HttpsFirstBalancedMode";
        case HttpsUpgradesTestType::kHttpsFirstModeAdvancedProtection:
          return "HttpsFirstModeAdvancedProtection";
        case HttpsUpgradesTestType::kAll:
          return "AllFeatures";
        case HttpsUpgradesTestType::kHttpsFirstBalancedModeWithOldUi:
          return "HttpsFirstBalancedModeWithOldUi";
        case HttpsUpgradesTestType::kNone:
          return "None";
        case HttpsUpgradesTestType::
            kHttpsFirstModeWithSiteEngagementWithoutBalancedMode:
          return "kHttpsFirstModeWithSiteEngagementWithoutBalancedMode";
      }
    });

// If the user navigates to an HTTP URL for a site that supports HTTPS, the
// navigation should end up on the HTTPS version of the URL if upgrading is
// enabled.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       UrlWithHttpScheme_ShouldUpgrade) {
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");

  auto* contents = browser()->GetTabStripModel()->GetActiveWebContents();
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url, https_url));
  EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));

  EXPECT_EQ(https_url, contents->GetLastCommittedURL());
  histograms()->ExpectTotalCount(kEventHistogram, 2);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeSucceeded, 1);

  // Also record general request metrics.
  histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 2);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kSecure, 1);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kUpgraded, 1);

  ExpectEmptyUKM();
}

// If the user navigates to an HTTPS URL for a site that supports HTTPS, the
// navigation should end up on that exact URL.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       UrlWithHttpsScheme_ShouldLoad) {
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, https_url));

  // Verify that navigation event metrics were not recorded as the navigation
  // was not upgraded.
  histograms()->ExpectTotalCount(kEventHistogram, 0);

  // General navigation metrics should still be recorded.
  histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 1);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kSecure, 1);

  ExpectEmptyUKM();
}

// If the user navigates to a localhost URL, the navigation should end up on
// that exact URL.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, Localhost_ShouldNotUpgrade) {
  GURL localhost_url = http_server()->GetURL("localhost", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, localhost_url));

  // Verify that navigation event metrics were not recorded as the navigation
  // was not upgraded.
  histograms()->ExpectTotalCount(kEventHistogram, 0);

  // Verify that general navigation request metrics were recorded.
  histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 1);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kLocalhost,
                                  1);

  ExpectEmptyUKM();
}

// Test that HTTPS Upgrades are skipped for non-unique hostnames, such as
// non-publicly routable (RFC1918/4193) IP addresses, but HTTPS-First Mode
// should still apply.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       NonRoutableIPAddress_ShouldNotUpgrade) {
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);

  // Set up an interceptor because the test server can't listen on private IPs.
  GURL local_ip_url("http://192.168.0.1/simple.html");
  auto url_loader_interceptor =
      content::URLLoaderInterceptor::ServeFilesFromDirectoryAtOrigin(
          GetChromeTestDataDir().MaybeAsASCII(),
          local_ip_url.GetWithEmptyPath());

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();

  if (IsStrictInterstitialEnabledForTest()) {
    // HFM should attempt the upgrade, fail, and fallback to the interstitial.
    EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, local_ip_url));
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

    // Verify that upgrade events were recorded because an upgrade was attempted
    // and failed.
    histograms()->ExpectTotalCount(kEventHistogram, 3);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeAttempted, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeFailed, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeTimedOut, 1);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // If HFM strict mode is not enabled, we should not attempt to upgrade the
    // navigation.
    EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, local_ip_url));
    histograms()->ExpectTotalCount(kEventHistogram, 0);
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kNonUniqueHostname, 1);
  }

  ExpectEmptyUKM();
}

// Test that unique single-label hostnames (e.g. gTLDs) are only upgraded and
// warned on in strict mode.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       UniqueSingleLabel_NoWarnInBalancedMode) {
  // Set an HTTPS testing port that does not match the test server to have all
  // attempted upgrades fail.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);

  GURL singlelabel_url = http_server()->GetURL("cl", "/simple.html");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();

  if (IsStrictInterstitialEnabledForTest()) {
    // HFM should attempt the upgrade, fail, and fallback to the interstitial.
    EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, singlelabel_url));
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 2);
  } else {
    // Otherwise, the request should not be upgraded and just navigate to HTTP.
    EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, singlelabel_url));
    EXPECT_EQ(singlelabel_url, contents->GetLastCommittedURL());
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kSingleLabelHostname, 1);
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 1);
  }

  // If in Strict Mode, verify that upgrade events were recorded because an
  // upgrade was attempted and failed.
  if (IsStrictInterstitialEnabledForTest()) {
    histograms()->ExpectTotalCount(kEventHistogram, 3);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeAttempted, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeFailed, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeTimedOut, 1);

    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 1);
  }

  ExpectEmptyUKM();
}

// If the user navigates to a non-unique hostname, the navigation should be
// upgraded only if strict mode is enabled. If we skip upgrading we should
// record that the reason was the non-unique hostname.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, NonUniqueHost_RecordsMetrics) {
  GURL nonunique_url1 = http_server()->GetURL("test.local", "/simple.html");
  GURL nonunique_url2 = http_server()->GetURL("test", "/simple.html");
  // Note that we don't test with an RFC1918 IP because the test server
  // wouldn't receive the traffic (since it relies on DNS).

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  if (IsStrictInterstitialEnabledForTest()) {
    EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, nonunique_url1));
    EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, nonunique_url2));
    // Other histograms are still recorded.
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    2);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 2);
  } else {
    // When HFM strict mode is not enabled, Chrome does NOT upgrade, so other
    // histograms are not recorded.
    EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, nonunique_url1));
    EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, nonunique_url2));
    histograms()->ExpectUniqueSample(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kNonUniqueHostname, 2);
  }

  ExpectEmptyUKM();
}

// Test that non-default ports (e.g. not HTTP80) are only upgraded and warned on
// in strict mode and Incognito.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       NonDefaultPorts_NoWarnInBalancedMode) {
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);

  // Set up an interceptor so we can test non-default (and non-testing) ports.
  GURL non_default_http_url = GURL("http://example.com:8080/simple.html");
  auto url_loader_interceptor =
      content::URLLoaderInterceptor::ServeFilesFromDirectoryAtOrigin(
          GetChromeTestDataDir().MaybeAsASCII(),
          non_default_http_url.GetWithEmptyPath());

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();

  if (IsStrictInterstitialEnabledForTest()) {
    // HFM should attempt the upgrade, fail, and fallback to the interstitial.
    EXPECT_FALSE(
        NavigateToURLWithLinkTransition(contents, non_default_http_url));
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 2);
  } else {
    // Otherwise, the request should not be upgraded and just navigate to HTTP.
    EXPECT_TRUE(
        NavigateToURLWithLinkTransition(contents, non_default_http_url));
    EXPECT_EQ(non_default_http_url, contents->GetLastCommittedURL());
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kNonDefaultPorts, 1);
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 1);
  }

  // If in Strict Mode, verify that upgrade events were recorded
  // because an upgrade was attempted and failed.
  if (IsStrictInterstitialEnabledForTest()) {
    histograms()->ExpectTotalCount(kEventHistogram, 3);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeAttempted, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeFailed, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeNetError, 1);

    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 1);
  }

  ExpectEmptyUKM();
}

// If the user navigates to an HTTPS URL, the navigation should end up on that
// exact URL, even if the site has an SSL error.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       UrlWithHttpsScheme_BrokenSSL_ShouldNotFallback) {
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, https_url));
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());

  // The SSL error should show regardless of the HFM state.
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingSSLInterstitial(contents));

  // Verify that navigation event metrics were not recorded as the navigation
  // was not upgraded.
  histograms()->ExpectTotalCount(kEventHistogram, 0);

  ExpectEmptyUKM();
}

// If the user navigates to an HTTP URL for a site with broken HTTPS, the
// navigation should end up on the HTTPS URL and show the HTTPS-Only Mode
// interstitial.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       UrlWithHttpScheme_BrokenSSL_ShouldInterstitial) {
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
  }

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  // The user hasn't taken action yet, so this should be empty.
  ExpectEmptyUKM();
}

// HTTPS-First Mode in Incognito should customize the interstitial.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       IncognitoInterstitialVariation) {
  // This test only applies to fully-enabled HFM, HFM-in-Incognito and
  // HFM-in-Isolated-Mode.
  if (!IsHttpsFirstModePrefEnabled() && !IsIncognitoOrIsolatedBrowser()) {
    return;
  }

  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModePrefEnabled()) {
    EXPECT_EQ(HFMInterstitialType::kStandard, GetHFMInterstitialType(contents));
  } else if (IsIsolatedMode()) {
    // Test that HFM-in-Isolated-Mode overrides the default interstitial text.
    EXPECT_EQ(HFMInterstitialType::kIsolatedMode,
              GetHFMInterstitialType(contents));
  } else if (IsIncognitoMode()) {
    // Test that HFM-in-Incognito overrides the default interstitial text.
    EXPECT_EQ(HFMInterstitialType::kIncognito,
              GetHFMInterstitialType(contents));
  }

  // The user hasn't taken action yet, so this should be empty.
  ExpectEmptyUKM();
}

void MaybeEnableHttpsFirstModeForEngagedSitesAndWait(
    HttpsFirstModeService* hfm_service) {
  base::RunLoop run_loop;
  hfm_service->MaybeEnableHttpsFirstModeForEngagedSites(run_loop.QuitClosure());
  run_loop.Run();
}

// Returns a URL loader interceptor that responds to HTTPS URLs with a cert
// error and to HTTP URLs with a good response.
std::unique_ptr<content::URLLoaderInterceptor>
MakeInterceptorForSiteEngagementHeuristic() {
  return std::make_unique<content::URLLoaderInterceptor>(
      base::BindLambdaForTesting(
          [](content::URLLoaderInterceptor::RequestParams* params) {
            if (params->url_request.url.SchemeIs("https")) {
              // Fail with an SSL error.
              network::URLLoaderCompletionStatus status;
              status.error_code = net::ERR_CERT_COMMON_NAME_INVALID;
              status.ssl_info = net::SSLInfo();
              status.ssl_info->cert_status =
                  net::CERT_STATUS_COMMON_NAME_INVALID;
              // The cert doesn't matter.
              status.ssl_info->cert = net::ImportCertFromFile(
                  net::GetTestCertsDirectory(), "ok_cert.pem");
              status.ssl_info->unverified_cert = status.ssl_info->cert;
              params->client->OnComplete(status);
              return true;
            }
            content::URLLoaderInterceptor::WriteResponse(
                "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                "<html>Done</html>", params->client.get());
            return true;
          }));
}

// TODO(crbug.com/40904694): Fails on the linux-wayland-rel bot.
#if defined(OZONE_PLATFORM_WAYLAND)
#define MAYBE_UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldInterstitial \
  DISABLED_UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldInterstitial
#else
#define MAYBE_UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldInterstitial \
  UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldInterstitial
#endif
// Test for Site Engagement Heuristic, a feature that enables HFM on specific
// sites based on their site engagement scores.
// If the user navigates to an HTTP URL for a site with broken HTTPS, the
// navigation should end up on the HTTPS URL and show the HTTPS-Only Mode
// interstitial. It should also record a separate histogram for Site Engagement
// Heuristic if the interstitial isn't enabled.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    MAYBE_UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldInterstitial) {
  // HFM+SE is not enabled in Incognito or Isolated Mode.
  if (IsIncognitoOrIsolatedBrowser()) {
    return;
  }
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  Profile* profile = GetBrowser()->GetProfile();
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Set test clock.
  auto clock = std::make_unique<base::SimpleTestClock>();
  auto* clock_ptr = clock.get();
  StatefulSSLHostStateDelegate* chrome_state =
      static_cast<StatefulSSLHostStateDelegate*>(state);
  chrome_state->SetClockForTesting(std::move(clock));

  // Start the clock at standard system time.
  clock_ptr->SetNow(base::Time::NowFromSystemTime());

  GURL http_url("http://bad-https.com");
  GURL https_url("https://bad-https.com");
  SetSiteEngagementScore(http_url, kLowSiteEngagementScore);
  SetSiteEngagementScore(https_url, kHighSiteEnagementScore);
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  MaybeEnableHttpsFirstModeForEngagedSitesAndWait(hfm_service);
  const bool is_interstitial_due_to_se_heuristic =
      IsSiteEngagementHeuristicEnabled() && !IsHttpsFirstModePrefEnabled() &&
      !InBalancedMode();

  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites() ||
      IsSiteEngagementHeuristicEnabled()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    EXPECT_EQ(is_interstitial_due_to_se_heuristic
                  ? HFMInterstitialType::kSiteEngagement
                  : HFMInterstitialType::kStandard,
              GetHFMInterstitialType(contents));
  } else {
    EXPECT_EQ(HFMInterstitialType::kNone, GetHFMInterstitialType(contents));
  }

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  // Check engagement heuristic metrics. These are only recorded when the
  // site engagement heuristic is enabled and the interstitial is due to this
  // heuristic and not because of prefs.
  if (is_interstitial_due_to_se_heuristic) {
    histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 3);
    histograms()->ExpectBucketCount(kEventHistogramWithEngagementHeuristic,
                                    Event::kUpgradeAttempted, 1);
    histograms()->ExpectBucketCount(kEventHistogramWithEngagementHeuristic,
                                    Event::kUpgradeFailed, 1);
    histograms()->ExpectBucketCount(kEventHistogramWithEngagementHeuristic,
                                    Event::kUpgradeCertError, 1);
    // Check the heuristic state.
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicStateHistogram, 1);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicStateHistogram,
                                    SiteEngagementHeuristicState::kDisabled, 0);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicStateHistogram,
                                    SiteEngagementHeuristicState::kEnabled, 1);
    // Check host count.
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicHostCountHistogram,
                                   1);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    0,
                                    /*expected_count=*/0);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    1,
                                    /*expected_count=*/1);
    // Check accumulated host count.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 1);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 0,
        /*expected_count=*/0);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 1,
        /*expected_count=*/1);
    // Check enforcement duration. Since the host isn't removed from HFM
    // enforcement list, no duration should be recorded yet.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicEnforcementDurationHistogram, 0);

    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kHttpsEnforcedOnHostname, 1);
  } else {
    histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);

    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kHttpsEnforcedOnHostname, 0);
  }

  // Lower HTTPS engagement score. This disables HFM on the site. Also advance
  // the clock.
  SetSiteEngagementScore(https_url, 5);
  clock_ptr->Advance(base::Hours(1));
  MaybeEnableHttpsFirstModeForEngagedSitesAndWait(hfm_service);

  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  // Should only show the interstitial if the HFM pref is enabled. Site
  // engagement heuristic alone will no longer cause an interstitial.
  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

    // Proceed through the interstitial, which will add the host to the
    // allowlist and navigate to the HTTP fallback URL.
    ProceedThroughHttpsFirstModeInterstitial(contents);

    // Verify that the interstitial metrics were correctly recorded. The
    // interstitial was shown twice, once clicked through and once not.
    histograms()->ExpectTotalCount("interstitial.https_first_mode.decision", 4);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::SHOW, 2);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::PROCEED, 1);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::DONT_PROCEED, 1);
  } else {
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
    if (IsSiteEngagementHeuristicEnabled()) {
      // Verify that the interstitial metrics were correctly recorded. The
      // interstitial was shown once and navigated away from.
      histograms()->ExpectTotalCount("interstitial.https_first_mode.decision",
                                     2);
      histograms()->ExpectBucketCount(
          "interstitial.https_first_mode.decision",
          security_interstitials::MetricsHelper::Decision::SHOW, 1);
      histograms()->ExpectBucketCount(
          "interstitial.https_first_mode.decision",
          security_interstitials::MetricsHelper::Decision::DONT_PROCEED, 1);
    } else {
      histograms()->ExpectTotalCount("interstitial.https_first_mode.decision",
                                     0);
    }
  }

  // Check engagement heuristic metrics. These are only recorded when the
  // site engagement heuristic is enabled and the interstitial is due to this
  // heuristic and not because of prefs.
  if (IsSiteEngagementHeuristicEnabled() &&
      !IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // Event histogram shouldn't change because Site Engagement heuristic didn't
    // kick in.
    histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 3);

    // Check host count.
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicHostCountHistogram,
                                   2);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    0,
                                    /*expected_count=*/1);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    1,
                                    /*expected_count=*/1);
    // Check accumulated host count.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 2);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 0,
        /*expected_count=*/0);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 1,
        /*expected_count=*/2);
    // Check enforcement duration. The host is now removed from HFM
    // enforcement list, so its HFM enforcement duration should be recorded now.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicEnforcementDurationHistogram, 1);
    histograms()->ExpectTimeBucketCount(
        kSiteEngagementHeuristicEnforcementDurationHistogram, base::Hours(1),
        1);

    // This bucket was recorded once previously, shouldn't be recorded again.
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kHttpsEnforcedOnHostname, 1);

  } else {
    // Event histogram shouldn't change because Site Engagement heuristic didn't
    // kick in.
    histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);

    // If HFM pref was enabled, no SE metrics should be recorded because HFM
    // won't be auto-enabled.
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicHostCountHistogram,
                                   0);
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 0);
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicEnforcementDurationHistogram, 0);

    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kHttpsEnforcedOnHostname, 0);
  }
}

// Test that Site Engagement Heuristic doesn't enforce HTTPS on URLs with
// non-default ports.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldIgnoreUrlsWithNonDefaultPorts) {
  // HFM+SE is not enabled in Incognito or Isolated Mode.
  if (IsIncognitoOrIsolatedBrowser()) {
    return;
  }
  // Advanced Protection users have HFM enabled unconditionally, which does not
  // exempt non-default ports. This test assumes the heuristic decides whether
  // to upgrade, which is not the case when AP is active.
  if (https_upgrades_test_type() ==
      HttpsUpgradesTestType::kHttpsFirstModeAdvancedProtection) {
    return;
  }
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  Profile* profile = GetBrowser()->GetProfile();
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Set test clock.
  auto clock = std::make_unique<base::SimpleTestClock>();
  auto* clock_ptr = clock.get();
  StatefulSSLHostStateDelegate* chrome_state =
      static_cast<StatefulSSLHostStateDelegate*>(state);
  chrome_state->SetClockForTesting(std::move(clock));

  // Start the clock at standard system time.
  clock_ptr->SetNow(base::Time::NowFromSystemTime());

  GURL http_url("http://bad-https.com");
  GURL https_url("https://bad-https.com");
  GURL navigated_url("http://bad-https.com:8080");

  // Set engagement for the HTTP and HTTPS origins with default ports.
  SetSiteEngagementScore(http_url, kLowSiteEngagementScore);
  SetSiteEngagementScore(https_url, kHighSiteEnagementScore);
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  MaybeEnableHttpsFirstModeForEngagedSitesAndWait(hfm_service);

  // Navigate to a non-default port version of the URL.
  NavigateAndWaitForFallback(contents, navigated_url);
  EXPECT_EQ(navigated_url, contents->GetLastCommittedURL());

  // Non-strict modes should not upgrade because `navigated_url` has a
  // non-default port, regardless of whether the hostname is on the enforcelist.
  if (IsHttpsFirstModePrefEnabled()) {
    EXPECT_EQ(HFMInterstitialType::kStandard, GetHFMInterstitialType(contents));
  } else {
    EXPECT_EQ(HFMInterstitialType::kNone, GetHFMInterstitialType(contents));
  }

  // Strict mode should have upgraded and fallen back to HTTP.
  if (IsHttpsFirstModePrefEnabled()) {
    // Verify that navigation event metrics were correctly recorded.
    histograms()->ExpectTotalCount(kEventHistogram, 3);
    histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted,
                                    1);
    histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
    histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError,
                                    1);
  } else {
    histograms()->ExpectTotalCount(kEventHistogram, 0);
  }

  // Engagement heuristic shouldn't handle any navigation events because we
  // didn't navigate to bad-https.com:80.
  histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);

  // Check engagement heuristic metrics. These are only recorded when the
  // site engagement interstitial is enabled.
  if (IsSiteEngagementHeuristicEnabled() &&
      !IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // Check the heuristic state. The heuristic should enable HFM for
    // example.com
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicStateHistogram, 1);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicStateHistogram,
                                    SiteEngagementHeuristicState::kDisabled, 0);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicStateHistogram,
                                    SiteEngagementHeuristicState::kEnabled, 1);
    // Check host count.
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicHostCountHistogram,
                                   1);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    0,
                                    /*expected_count=*/0);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    1,
                                    /*expected_count=*/1);
    // Check accumulated host count.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 1);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 0,
        /*expected_count=*/0);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 1,
        /*expected_count=*/1);
    // Check enforcement duration. Since the host isn't removed from HFM
    // enforcement list, no duration should be recorded yet.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicEnforcementDurationHistogram, 0);
  } else {
    histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);
  }
}

IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    PRE_UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser) {
  // HFM-for-Typically-Secure-Users is not enabled in Incognito or Isolated
  // Mode.
  if (IsIncognitoOrIsolatedBrowser()) {
    return;
  }
  if (https_upgrades_test_type() ==
      HttpsUpgradesTestType::kHttpsFirstModeAdvancedProtection) {
    return;
  }

  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());

  if (!IsHttpsFirstModePrefEnabled() && !InBalancedMode()) {
    // When HFM is not enabled via pref, these should never be set in this test.
    EXPECT_FALSE(
        profile->GetPrefs()->HasPrefPath(prefs::kHttpsOnlyModeEnabled));
    EXPECT_FALSE(
        profile->GetPrefs()->HasPrefPath(prefs::kHttpsOnlyModeAutoEnabled));
  }

  // Typically Secure User heuristic requires a minimum total site engagement
  // score.
  SetSiteEngagementScore(GURL("https://google.com"), 90);

  base::Time now;
  EXPECT_TRUE(base::Time::FromUTCString("2023-10-15T06:00:00Z", &now));
  // Start the clock at standard system time.
  GetTestClock()->SetNow(now);

  profile->SetCreationTimeForTesting(GetTestClock()->Now() - base::Days(30));

  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  hfm_service->SetClockForTesting(GetTestClock());

  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  // Visit the HTTP URL. Profile age is old enough but we haven't been observing
  // navigations for long enough, so Typically Secure Users feature won't show
  // an interstitial here.
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  ExpectedInterstitialReasons expected_reasons;

  if (IsHttpsFirstModePrefEnabled()) {
    ExpectInterstitial(contents);
    expected_reasons.pref++;
  } else if (InBalancedMode()) {
    ExpectInterstitial(contents);
    expected_reasons.balanced++;
  } else if (safe_browsing::AdvancedProtectionStatusManagerFactory::
                 GetForProfile(browser()->GetProfile())
                     ->IsUnderAdvancedProtection()) {
    ExpectInterstitial(contents);
    expected_reasons.advanced_protection++;
  } else {
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  }
  CheckInterstitialReasonHistogram(expected_reasons);

  // Move the clock forward and revisit HTTP. Profile is old enough now, but
  // Typically Secure Users feature will only auto-enable HFM after a restart
  // and show an interstitial.
  GetTestClock()->Advance(base::Days(15));
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModePrefEnabled()) {
    ExpectInterstitial(contents);
    expected_reasons.pref++;
  } else if (InBalancedMode()) {
    ExpectInterstitial(contents);
    expected_reasons.balanced++;
  } else if (safe_browsing::AdvancedProtectionStatusManagerFactory::
                 GetForProfile(browser()->GetProfile())
                     ->IsUnderAdvancedProtection()) {
    ExpectInterstitial(contents);
    expected_reasons.advanced_protection++;
  } else {
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  }
  CheckInterstitialReasonHistogram(expected_reasons);

  if (!IsHttpsFirstModePrefEnabled() && !InBalancedMode()) {
    EXPECT_FALSE(
        profile->GetPrefs()->HasPrefPath(prefs::kHttpsOnlyModeEnabled));
    EXPECT_FALSE(
        profile->GetPrefs()->HasPrefPath(prefs::kHttpsOnlyModeAutoEnabled));
  }
}

// TODO(crbug.com/40925331): Fails on the linux-wayland-rel bot.
#if defined(OZONE_PLATFORM_WAYLAND)
#define MAYBE_UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser \
  DISABLED_UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser
#else
#define MAYBE_UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser \
  UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser
#endif
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    MAYBE_UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser) {
  // HFM-for-Typically-Secure-Users is not enabled in Incognito or Isolated
  // Mode.
  if (IsIncognitoOrIsolatedBrowser()) {
    return;
  }
  if (https_upgrades_test_type() ==
      HttpsUpgradesTestType::kHttpsFirstModeAdvancedProtection) {
    return;
  }

  // Advance the clock to one day after the last fallback event, which happened
  // on the 15th day.
  GetTestClock()->SetNow(base::Time::NowFromSystemTime() + base::Days(16));

  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());

  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  // Do lots of navigations so that Typically Secure User can kick in.
  for (size_t i = 0; i < 1500; i++) {
    hfm_service->IncrementRecentNavigationCount();
  }

  hfm_service->SetClockForTesting(GetTestClock());
  // HFM service runs this on startup, but we can't set the test clock before it
  // runs, and we need to move the clock forward for this to work. So call it
  // explicitly again here.
  hfm_service->CheckUserIsTypicallySecureAndMaybeEnableHttpsFirstBalancedMode();
  size_t initial_navigation_count = hfm_service->GetRecentNavigationCount();

  // Use a different hostname than the PRE_ test so that we don't hit the
  // allowlist.
  GURL http_url = http_server()->GetURL("bad-https2.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https2.com", "/simple.html");
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_EQ(initial_navigation_count + 1u,
            hfm_service->GetRecentNavigationCount());

  bool expect_interstitial = IsHttpsFirstModeInterstitialEnabledAcrossSites() ||
                             IsTypicallySecureUserFeatureEnabled();
  // Expect typically secure text only when HFM is auto-enabled, so exclude
  // HttpsUpgradesTestType::kAll where HFM is enabled via pref).
  bool expect_typically_secure_user_interstitial_text =
      https_upgrades_test_type() ==
          HttpsUpgradesTestType::kHttpsFirstModeForTypicallySecureUsers ||
      https_upgrades_test_type() == HttpsUpgradesTestType::kAllAutoHFM;

  ExpectedInterstitialReasons expected_reasons;
  if (expect_interstitial) {
    EXPECT_EQ(expect_typically_secure_user_interstitial_text
                  ? HFMInterstitialType::kTypicallySecure
                  : HFMInterstitialType::kStandard,
              GetHFMInterstitialType(contents));

    if (expect_typically_secure_user_interstitial_text) {
      expected_reasons.typically_secure_user++;
    } else if (IsHttpsFirstModePrefEnabled()) {
      expected_reasons.pref++;
    } else if (InBalancedMode()) {
      expected_reasons.balanced++;
    } else if (safe_browsing::AdvancedProtectionStatusManagerFactory::
                   GetForProfile(browser()->GetProfile())
                       ->IsUnderAdvancedProtection()) {
      expected_reasons.advanced_protection++;
    } else {
      NOTREACHED();
    }
  } else {
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  }
  CheckInterstitialReasonHistogram(expected_reasons);

  // Move the clock forward a day and revisit HTTP. Should still show HFM
  // interstitial.
  GetTestClock()->Advance(base::Days(1));
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_EQ(initial_navigation_count + 2u,
            hfm_service->GetRecentNavigationCount());

  if (expect_interstitial) {
    EXPECT_EQ(expect_typically_secure_user_interstitial_text
                  ? HFMInterstitialType::kTypicallySecure
                  : HFMInterstitialType::kStandard,
              GetHFMInterstitialType(contents));

    if (expect_typically_secure_user_interstitial_text) {
      expected_reasons.typically_secure_user++;
    } else if (IsHttpsFirstModePrefEnabled()) {
      expected_reasons.pref++;
    } else if (InBalancedMode()) {
      expected_reasons.balanced++;
    } else if (safe_browsing::AdvancedProtectionStatusManagerFactory::
                   GetForProfile(browser()->GetProfile())
                       ->IsUnderAdvancedProtection()) {
      expected_reasons.advanced_protection++;
    } else {
      NOTREACHED();
    }

  } else {
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  }
  CheckInterstitialReasonHistogram(expected_reasons);

  // Disable HFM and HF-balanced-mode. Should no longer auto-enable it.
  SetPref(false);
  auto* state = static_cast<StatefulSSLHostStateDelegate*>(
      profile->GetSSLHostStateDelegate());
  state->SetHttpsFirstBalancedModeSuppressedForTesting(true);
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(initial_navigation_count + 3u,
            hfm_service->GetRecentNavigationCount());
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));

  // Re-enable HFM. Should now show HFM interstitial without the auto-enabled
  // text.
  SetPref(true);
  state->SetHttpsFirstBalancedModeSuppressedForTesting(false);
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_EQ(initial_navigation_count + 4u,
            hfm_service->GetRecentNavigationCount());

  EXPECT_EQ(HFMInterstitialType::kStandard, GetHFMInterstitialType(contents));
  expected_reasons.pref++;

  CheckInterstitialReasonHistogram(expected_reasons);
}

// Checks that navigation to a non-unique hostname doesn't display a typically
// secure interstitial.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    TypicallySecure_NonUniqueHostname_ShouldNotShowInterstitial) {
  // HFM-for-Typically-Secure-Users is not enabled in Incognito or Isolated
  // Mode.
  if (IsIncognitoOrIsolatedBrowser()) {
    return;
  }
  if (https_upgrades_test_type() ==
      HttpsUpgradesTestType::kHttpsFirstModeAdvancedProtection) {
    return;
  }
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  SatisfyTypicallySecureHeuristicRequirements();
  // This should auto-enable HFM now:
  hfm_service()
      ->CheckUserIsTypicallySecureAndMaybeEnableHttpsFirstBalancedMode();

  // Check that a bad HTTPS URL should show an interstitial due to the
  // heuristic.
  GURL http_url("http://bad-https.com/simple.html");
  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateToURLWithLinkTransitionBlockUntilNavigationsComplete(
      contents, http_url, /*number_of_navigations=*/1);
  MaybeExpectTypicallySecureInterstitial(contents);

  // Check that a non-unique hostname shouldn't show an interstitial due to the
  // heuristic.
  GURL nonunique_url("http://nonunique-hostname-bad-https/simple.html");
  NavigateToURLWithLinkTransitionBlockUntilNavigationsComplete(
      contents, nonunique_url, /*number_of_navigations=*/1);
  if (IsStrictInterstitialEnabledForTest()) {
    // Non-unique hostnames should only show an interstitial in strict mode.
    EXPECT_EQ(HFMInterstitialType::kStandard, GetHFMInterstitialType(contents));
  } else {
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  }
}

// Same as TypicallySecure_NonUniqueHostname_ShouldNotShowInterstitial, but
// also navigates to a non-unique URL before checking the heuristic. The
// non-unique URL should not count as a fallback navigation and should not
// disable the Typically Secure heuristic.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    TypicallySecure_NonUniqueHostnameFallbackShouldNotDisableTypicallySecureHeuristic) {
  // HFM-for-Typically-Secure-Users is not enabled in Incognito or Isolated
  // Mode.
  if (IsIncognitoOrIsolatedBrowser()) {
    return;
  }
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  if (https_upgrades_test_type() ==
      HttpsUpgradesTestType::kHttpsFirstModeAdvancedProtection) {
    return;
  }
  SatisfyTypicallySecureHeuristicRequirements();

  // Before running the heuristic checks, also navigate to a non-unique
  // hostname. This will result in an interstitial iff strict mode is enabled.
  content::WebContents* contents =
      browser()->GetTabStripModel()->GetActiveWebContents();
  NavigateToURLWithLinkTransitionBlockUntilNavigationsComplete(
      contents, GURL("http://nonunique-hostname-bad-https2/simple.html"),
      /*number_of_navigations=*/1);
  if (IsStrictInterstitialEnabledForTest()) {
    // Non-unique hostnames should only show an interstitial in strict mode.
    EXPECT_EQ(HFMInterstitialType::kStandard, GetHFMInterstitialType(contents));
  } else {
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  }

  // This should still auto-enable HFM despite the interstitial for the
  // non-unique hostname because Typically Secure heuristic ignores fallbacks
  // for non-unique hostnames.
  hfm_service()
      ->CheckUserIsTypicallySecureAndMaybeEnableHttpsFirstBalancedMode();

  // Check that a bad HTTPS URL should show an interstitial due to the
  // heuristic.
  GURL http_url("http://bad-https.com/simple.html");
  NavigateToURLWithLinkTransitionBlockUntilNavigationsComplete(
      contents, http_url, /*number_of_navigations=*/1);
  MaybeExpectTypicallySecureInterstitial(contents);

  // Check that a non-unique hostname shouldn't show an interstitial due to the
  // heuristic.
  GURL nonunique_url("http://nonunique-hostname-bad-https/simple.html");
  NavigateToURLWithLinkTransitionBlockUntilNavigationsComplete(
      contents, nonunique_url, /*number_of_navigations=*/1);
  if (IsHttpsFirstModePrefEnabled()) {
    // Non-unique hostnames should only show an interstitial in strict mode.
    EXPECT_EQ(HFMInterstitialType::kStandard, GetHFMInterstitialType(contents));
  } else {
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  }
}

// Regression test for crbug.com/40909795. Sequence of events:
// 1. Loads http://example.com. This gets upgraded to https://example.com.
// 2. https://example.com has an iframe for https://nonexistentsite.com. It
//    navigates away immediately to http://example.com.
// 3. This causes a crash in
//    HttpsUpgradesInterceptor::MaybeCreateLoaderForResponse() for
//    nonexistentsite.com.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       LoadIFrameAndNavigateAway_ShouldNotCrash) {
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);

  bool navigated_once = false;
  auto url_loader_interceptor = std::make_unique<content::URLLoaderInterceptor>(
      base::BindLambdaForTesting(
          [&navigated_once](
              content::URLLoaderInterceptor::RequestParams* params) {
            if (params->url_request.url == GURL("https://example.com")) {
              if (!navigated_once) {
                // Load an iframe that will result in an error and immediately
                // navigate away.
                content::URLLoaderInterceptor::WriteResponse(
                    "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                    "<html>"
                    "<iframe src='https://nonexistentsite.com'></iframe>"
                    "<script>window.location.href = "
                    "'http://example.com';</script></html>",
                    params->client.get());
                navigated_once = true;
                return true;
              }
              // Return a normal response the second time this is called,
              // otherwise the test will timeout due to navigating back and
              // forth between http and https URLs.
              content::URLLoaderInterceptor::WriteResponse(
                  "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                  "<html>Done</html>", params->client.get());
              return true;
            }

            if (params->url_request.url == GURL("http://example.com")) {
              content::URLLoaderInterceptor::WriteResponse(
                  "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                  "<html>Test</html>", params->client.get());
              return true;
            }

            if (params->url_request.url.GetHost() == "nonexistentsite.com") {
              // This request must fail for the bug to trigger.
              params->client->OnComplete(network::URLLoaderCompletionStatus(
                  net::ERR_CONNECTION_RESET));
              return true;
            }
            return false;
          }));

  GURL http_url("http://example.com");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
}

// If the user triggers an HTTPS-Only Mode interstitial for a host and then
// clicks through the interstitial, they should end up on the HTTP URL.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       InterstitialBypassed_HttpFallbackLoaded) {
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

    // Proceed through the interstitial, which will add the host to the
    // allowlist and navigate to the HTTP fallback URL.
    ProceedThroughHttpsFirstModeInterstitial(contents);

    // Verify that the interstitial metrics were correctly recorded.
    histograms()->ExpectTotalCount("interstitial.https_first_mode.decision", 2);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::SHOW, 1);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::PROCEED, 1);

    ExpectUKMEntry(http_url, BlockingResult::kInterstitialProceed);
  }

  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  // Revisit the site. Should load without a warning, but also record another
  // UKM.
  // TODO(crbug.com/406530494): This should also record the allowlisted status.
  NavigateAndWaitForFallback(contents, http_url);
  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    ExpectUKMEntry(http_url, BlockingResult::kInterstitialProceed);
  }
}

// If the upgraded HTTPS URL is not available due to a net error, it should
// trigger the HTTPS-Only Mode interstitial and offer fallback.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       NetErrorOnUpgrade_ShouldInterstitial) {
  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL https_url = https_server()->GetURL("foo.com", "/close-socket");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
  }

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeNetError, 1);
}

// If the upgraded HTTPS URL is not available due to a potentially-transient
// exempted net error (here a DNS resolution error), show the regular net error
// page instead of the HTTPS-First Mode interstitial. If the network conditions
// change such that the network error no longer triggers, reloading the tab
// should continue the upgraded navigation, which will fail and trigger fallback
// to HTTP. (Regression test for crbug.com/40809438.)
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       ExemptNetErrorOnUpgrade_ShouldNotFallback) {
  // This test is only interesting when HTTPS-First Mode is enabled.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();

  {
    // Set up an interceptor that will return ERR_NAME_NOT_RESOLVED. Navigating
    // to the HTTP URL should get upgraded to HTTPS, but fail with a net error
    // page on the HTTPS URL.
    auto dns_failure_interceptor =
        std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
            [](content::URLLoaderInterceptor::RequestParams* params) {
              params->client->OnComplete(network::URLLoaderCompletionStatus(
                  net::ERR_NAME_NOT_RESOLVED));
              return true;
            }));
    EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));

    // Reload the tab. The net error should still be showing as the navigation
    // still results in ERR_NAME_NOT_RESOLVED.
    content::TestNavigationObserver nav_observer(contents, 1);
    contents->GetController().Reload(content::ReloadType::NORMAL,
                                     /*check_for_repost=*/false);
    nav_observer.Wait();
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));
  }

  // Interceptor is now out of scope and no longer applies. Reload the tab and
  // the upgraded navigation should continue, fail due to the bad HTTPS on the
  // server, and fall back to HTTP.
  content::TestNavigationObserver nav_observer(contents, 1);
  contents->GetController().Reload(content::ReloadType::NORMAL,
                                   /*check_for_repost=*/false);
  nav_observer.Wait();

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    ASSERT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    ProceedThroughHttpsFirstModeInterstitial(contents);
  }

  // Should now be on the HTTP URL and it should be allowlisted.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));
}

// Test that if one site redirects to a non-existent site, that we show the
// regular net error page instead of the HTTPS-First Mode interstitial.
// (Regression test for crbug.com/40809438.)
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       RedirectToNonexistentSite_ShouldNotInterstitial) {
  // This test is only interesting when HTTPS-First Mode is enabled.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  std::string nonexistent_domain = "nonexistentsite.com";
  GURL nonexistent_http_url =
      http_server()->GetURL(nonexistent_domain, "/simple.html");
  GURL nonexistent_https_url =
      https_server()->GetURL(nonexistent_domain, "/simple.html");
  std::string www_redirect_path =
      base::StrCat({"/server-redirect?", nonexistent_http_url.spec()});
  GURL redirecting_https_url =
      https_server()->GetURL("foo.com", www_redirect_path);
  GURL redirecting_http_url =
      http_server()->GetURL("foo.com", www_redirect_path);

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();

  // Set up an interceptor that will return ERR_NAME_NOT_RESOLVED for
  // nonexistentsite.com.
  auto dns_failure_interceptor =
      std::make_unique<content::URLLoaderInterceptor>(
          base::BindLambdaForTesting(
              [nonexistent_domain](
                  content::URLLoaderInterceptor::RequestParams* params) {
                if (params->url_request.url.GetHost() == nonexistent_domain) {
                  params->client->OnComplete(network::URLLoaderCompletionStatus(
                      net::ERR_NAME_NOT_RESOLVED));
                  return true;
                }
                return false;
              }));

  // Navigating to the HTTP URL should get upgraded to HTTPS, but fail with a
  // net error page on the HTTPS URL.
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, redirecting_http_url));
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  EXPECT_EQ(url::kHttpsScheme, contents->GetLastCommittedURL().GetScheme());
  EXPECT_EQ(nonexistent_domain, contents->GetLastCommittedURL().GetHost());
}

// If the upgraded HTTPS URL is not available due to a potentially-transient
// exempted net error but the hostname is non-unique, don't show the net error
// page and instead just fallback to HTTP and the HTTPS-First Mode interstitial.
// Otherwise, the user can be stuck on the net error page when the HTTP version
// of the host would have resolved, such as for corp single-label hostnames.
// (Regression test for crbug.com/40915602.)
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    ExemptNetErrorOnUpgrade_NonUniqueHostname_ShouldFallback) {
  // This test is only interesting when HTTPS-First Mode is fully enabled.
  if (!IsHttpsFirstModePrefEnabled()) {
    return;
  }

  GURL http_url = http_server()->GetURL("blorp", "/simple.html");
  GURL https_url = https_server()->GetURL("blorp", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();

  // Set up an interceptor that will return ERR_NAME_NOT_RESOLVED. Navigating
  // to the HTTP URL should get upgraded to HTTPS, and then fallback to HTTP
  // and the HFM interstitial.
  auto dns_failure_interceptor =
      std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
          [](content::URLLoaderInterceptor::RequestParams* params) {
            params->client->OnComplete(
                network::URLLoaderCompletionStatus(net::ERR_NAME_NOT_RESOLVED));
            return true;
          }));
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
  ProceedThroughHttpsFirstModeInterstitial(contents);

  // Should now be on the HTTP URL and it should be allowlisted.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));

  ExpectUKMEntry(http_url, BlockingResult::kInterstitialProceed);
}

// If the upgraded HTTPS URL is not available due to an exempted net error but
// is to a single-label unique hostname (i.e. a TLD) don't show the net error
// page. This is the same as
// ExemptNetErrorOnUpgrade_NonUniqueHostname_ShouldFallback except with a unique
// one-label hostname.
// (Partial regression test for impact of crrev.com/c/5507613 on b/348330182.)
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    ExemptNetErrorOnUpgrade_UniqueSingleLabelHostname_ShouldFallback) {
  // This test is only interesting when HTTPS-First Strict Mode is enabled.
  // Balanced Mode won't try to upgrade these requests at all.
  if (!IsHttpsFirstModePrefEnabled() || IsIncognitoOrIsolatedBrowser()) {
    return;
  }

  GURL http_url = http_server()->GetURL("cl", "/simple.html");
  GURL https_url = https_server()->GetURL("cl", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();

  // Set up an interceptor that will return ERR_NAME_NOT_RESOLVED. Navigating
  // to the HTTP URL should get upgraded to HTTPS, and then fallback to HTTP
  // and the HFM interstitial.
  auto dns_failure_interceptor =
      std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
          [](content::URLLoaderInterceptor::RequestParams* params) {
            params->client->OnComplete(
                network::URLLoaderCompletionStatus(net::ERR_NAME_NOT_RESOLVED));
            return true;
          }));
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
  ProceedThroughHttpsFirstModeInterstitial(contents);

  // Should now be on the HTTP URL and the hostname should be allowlisted.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));

  ExpectUKMEntry(http_url, BlockingResult::kInterstitialProceed);
}

// Navigations in subframes should not get upgraded by HTTPS-Only Mode. They
// should be blocked as mixed content.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       HttpsParentHttpSubframeNavigation_Blocked) {
  const GURL parent_url(
      https_server()->GetURL("foo.com", "/iframe_blank.html"));
  const GURL iframe_url(http_server()->GetURL("foo.com", "/simple.html"));

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, parent_url));

  content::TestNavigationObserver nav_observer(contents, 1);
  EXPECT_TRUE(content::NavigateIframeToURL(contents, "test", iframe_url));
  nav_observer.Wait();
  EXPECT_NE(iframe_url, nav_observer.last_navigation_url());

  // Verify that no navigation event metrics were recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 0);
}

// Navigating to an HTTP URL in a subframe of an HTTP page should not upgrade
// the subframe navigation to HTTPS (even if the subframe navigation is to a
// different host than the parent frame).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       HttpParentHttpSubframeNavigation_NotUpgraded) {
  // The parent frame will fail to upgrade to HTTPS.
  const GURL parent_url(
      http_server()->GetURL("bad-https.com", "/iframe_blank.html"));
  const GURL iframe_url(http_server()->GetURL("bar.com", "/simple.html"));

  // Navigate to `parent_url` and bypass the HTTPS-Only Mode warning.
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, parent_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    // Proceeding through the interstitial will add the hostname to the
    // allowlist.
    ProceedThroughHttpsFirstModeInterstitial(contents);
  }

  // Verify that navigation event metrics were recorded for the main frame.
  histograms()->ExpectTotalCount(kEventHistogram, 3);

  // Navigate the iframe to `iframe_url`. It should successfully navigate and
  // not get upgraded to HTTPS as the hostname is now in the allowlist.
  content::TestNavigationObserver nav_observer(contents, 1);
  EXPECT_TRUE(content::NavigateIframeToURL(contents, "test", iframe_url));
  nav_observer.Wait();
  EXPECT_EQ(iframe_url, nav_observer.last_navigation_url());

  // Verify that no new navigation event metrics were recorded for the subframe.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
}

// Tests that a navigation to the HTTP version of a site with an HTTPS version
// that is slow to respond gets upgraded to HTTPS but times out and shows the
// HTTPS-Only Mode interstitial.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, SlowHttps_ShouldInterstitial) {
  // Set timeout to zero so that HTTPS upgrades immediately timeout.
  HttpsUpgradesNavigationThrottle::set_timeout_for_testing(base::TimeDelta());

  // Set up a custom HTTPS server that times out without sending a response.
  net::EmbeddedTestServer timeout_server{net::EmbeddedTestServer::TYPE_HTTPS};
  timeout_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        // Server will hang until destroyed.
        return std::make_unique<net::test_server::HungResponse>();
      }));
  ASSERT_TRUE(timeout_server.Start());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(timeout_server.port());

  const GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
  }
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
}

// Tests that an HTTP POST form navigation to "bar.com" from an HTTP page on
// "foo.com" is not upgraded to HTTPS. (HTTP form navigations from HTTPS are
// blocked by the Mixed Forms warning.)
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, HttpPageHttpPost_NotUpgraded) {
  // Point the HTTP form target to "bar.com".
  base::StringPairs replacement_text;
  replacement_text.emplace_back(make_pair(
      "REPLACE_WITH_HOST_AND_PORT",
      net::HostPortPair::FromURL(http_server()->GetURL("foo.com", "/"))
          .ToString()));
  auto replacement_path = net::test_server::GetFilePathWithReplacements(
      "/ssl/page_with_form_targeting_http_url.html", replacement_text);

  // Navigate to the page hosting the form on "foo.com".
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateToURLWithLinkTransitionBlockUntilNavigationsComplete(
      contents, http_server()->GetURL("bad-https.com", replacement_path), 1);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // The HTTPS-Only Mode interstitial should trigger.
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    // Proceed through the interstitial to add the hostname to the allowlist.
    ProceedThroughHttpsFirstModeInterstitial(contents);
  }

  // Verify that navigation event metrics were recorded for the initial page.
  histograms()->ExpectTotalCount(kEventHistogram, 3);

  // Submit the form and wait for the navigation to complete.
  content::TestNavigationObserver nav_observer(contents, 1);
  ASSERT_TRUE(
      content::ExecJs(contents, "document.getElementById('submit').click();"));
  nav_observer.Wait();

  // Check that the navigation has ended up on the HTTP target.
  EXPECT_EQ("foo.com", contents->GetLastCommittedURL().GetHost());
  EXPECT_TRUE(contents->GetLastCommittedURL().SchemeIs(url::kHttpScheme));

  // Verify that no new navigation event metrics were recorded for the POST
  // navigation.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
}

// Tests that if an HTTPS navigation redirects to HTTP on a different host, it
// should upgrade to HTTPS on that new host. (A downgrade redirect on the same
// host would imply a redirect loop.)
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       HttpsToHttpRedirect_ShouldUpgrade) {
  GURL target_url = http_server()->GetURL("bar.com", "/title1.html");
  GURL url = https_server()->GetURL("foo.com",
                                    "/server-redirect?" + target_url.spec());

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();

  // NavigateToURL() returns `false` because the final redirected URL does not
  // match `url`. Separately ensure the navigation succeeded using a navigation
  // observer.
  content::TestNavigationObserver nav_observer(contents, 1);
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, url));
  nav_observer.Wait();
  EXPECT_TRUE(nav_observer.last_navigation_succeeded());

  // Verify that navigation event metrics were correctly recorded.
  EXPECT_TRUE(contents->GetLastCommittedURL().SchemeIs(url::kHttpsScheme));
  histograms()->ExpectTotalCount(kEventHistogram, 2);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeSucceeded, 1);

  EXPECT_EQ("bar.com", contents->GetLastCommittedURL().GetHost());
}

// Regression test for crbug.com/41488861.
// Tests that a slow fallback load is not cancelled with timeout.
// bad-ssl.com is configured to return a slow load over http. Navigating to
// http://bad-ssl.com should upgrade and immediately fall back, then display the
// http response without cancelling it for timeout.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       CancelTimeoutForFallbackNavigations) {
  net::EmbeddedTestServer http_server;
  net::EmbeddedTestServer https_server{net::EmbeddedTestServer::TYPE_HTTPS};

  // Make the HTTP server return a slow response.
  http_server.RegisterRequestHandler(base::BindRepeating(
      [](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        // The HTTP load needs to be slower than the 1 second timeout configured
        // by the the test.
        auto slow_http_response =
            std::make_unique<net::test_server::DelayedHttpResponse>(
                base::Seconds(2));
        slow_http_response->set_content_type("text/html");
        slow_http_response->set_content("hello from http");
        return std::move(slow_http_response);
      }));
  ASSERT_TRUE(http_server.Start());
  ASSERT_TRUE(https_server.Start());

  // Set the timeout short enough, but not zero. We can't set it to zero
  // because it'll cancel the HTTPS load with timeout instead of an error.
  HttpsUpgradesNavigationThrottle::set_timeout_for_testing(base::Seconds(1));

  HttpsUpgradesInterceptor::SetHttpPortForTesting(http_server.port());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(https_server.port());

  GURL http_url(http_server.GetURL("bad-https.com", "/"));
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    histograms()->ExpectTotalCount("Net.ErrorCodesForMainFrame4", 1);
    histograms()->ExpectBucketCount("Net.ErrorCodesForMainFrame4",
                                    -net::ERR_ABORTED, 1);
  } else {
    // Shouldn't record any net errors.
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
    histograms()->ExpectTotalCount("Net.ErrorCodesForMainFrame4", 0);
  }

  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);
}

// Creates a redirect response.
std::unique_ptr<net::test_server::HttpResponse> RedirectResponseHandler(
    const GURL& dest_url,
    const net::test_server::HttpRequest& request) {
  std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
      new net::test_server::BasicHttpResponse);
  http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
  http_response->AddCustomHeader("Location", dest_url.spec());
  return std::move(http_response);
}

// Creates a response that causes a redirect loop over https and returns a slow
// response over http.
std::unique_ptr<net::test_server::HttpResponse> RedirectLoopResponse(
    int& http_port,
    int& https_port,
    const net::test_server::HttpRequest& request) {
  if (request.GetURL().GetPath() == "/redirect") {
    // Over https, this URL redirects to itself.
    if (request.GetURL().SchemeIs("https")) {
      GURL url(base::StringPrintf("http://a.com:%d/redirect", http_port));
      return RedirectResponseHandler(url, request);
    }
    // Over http, it prints a slow hello. This should delay longer than the
    // HTTPS upgrade timeout which is set to 1 second.
    auto slow_http_response =
        std::make_unique<net::test_server::DelayedHttpResponse>(
            base::Seconds(2));
    slow_http_response->set_content_type("text/html");
    slow_http_response->set_content("hello from http");
    return std::move(slow_http_response);
  }
  return nullptr;
}

// Another regression test for crbug.com/41488861.
// Tests that a slow load that's detected as a redirect loop will not display
// a flash of a net error page.
//
// Assume that a.com/redirect:
// - Shows a slow loading response when loaded over http
// - Redirects to http://a.com/redirect when loaded over https.
//
// The flow of the test is as follows:
// 1. Load http://a.com/redirect.
// 2. http://a.com/redirect is upgraded to http.
// 3. https://a.com/redirect redirects to http://a.com/redirect
// 4. This triggers a redirect loop (the URL was seen at step 1).
// 5. a.com is allowlisted and http://a.com/redirect is loaded as fallback.
// 6. http://a.com/redirect prints a message after a slow load.
//
// This flow should never display a net error page with ERR_TIMED_OUT to the
// user. If the interstitial is enabled, it should be displayed at the final
// step.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       RedirectLoopWithSlowRedirect_ShouldInterstitial) {
  net::EmbeddedTestServer redirect_server_http;
  net::EmbeddedTestServer redirect_server_https{
      net::EmbeddedTestServer::TYPE_HTTPS};

  // Set the timeout short enough, but not zero. We can't set it to zero
  // because it'll cancel the HTTPS load with timeout instead of an error.
  // The HTTP load in this test needs to be slower than this timeout for the
  // test to be meaningful.
  HttpsUpgradesNavigationThrottle::set_timeout_for_testing(base::Seconds(1));

  // We don't know the ports without starting the servers and we can't start
  // the servers without registering request handlers. Pass them as refs so
  // that we can change them later.
  int http_port = 0;
  int https_port = 0;
  redirect_server_http.RegisterRequestHandler(base::BindRepeating(
      &RedirectLoopResponse, std::ref(http_port), std::ref(https_port)));
  redirect_server_https.RegisterRequestHandler(base::BindRepeating(
      &RedirectLoopResponse, std::ref(http_port), std::ref(https_port)));

  ASSERT_TRUE(redirect_server_http.Start());
  ASSERT_TRUE(redirect_server_https.Start());

  http_port = redirect_server_http.port();
  https_port = redirect_server_https.port();

  HttpsUpgradesInterceptor::SetHttpPortForTesting(redirect_server_http.port());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(
      redirect_server_https.port());

  GURL http_url(redirect_server_http.GetURL("a.com", "/redirect"));
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    histograms()->ExpectTotalCount("Net.ErrorCodesForMainFrame4", 1);
    histograms()->ExpectBucketCount("Net.ErrorCodesForMainFrame4",
                                    -net::ERR_ABORTED, 1);
  } else {
    // Shouldn't record any net errors.
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
    histograms()->ExpectTotalCount("Net.ErrorCodesForMainFrame4", 0);
  }

  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeRedirectLoop,
                                  1);
}

// Tests that navigating to an HTTPS page that downgrades to HTTP on the same
// host will fail and trigger the HTTPS-Only Mode interstitial (due to
// interceptor detecting a redirect loop and triggering fallback).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       RedirectLoop_ShouldInterstitial) {
  // Set up a new test server instance so it can have a custom handler.
  net::EmbeddedTestServer downgrading_server{
      net::EmbeddedTestServer::TYPE_HTTPS};
  // Downgrade by swapping the scheme for HTTP. HTTPS-Only Mode will upgrade it
  // back to HTTPS.
  downgrading_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        GURL::Replacements http_downgrade;
        http_downgrade.SetSchemeStr(url::kHttpScheme);
        // The HttpRequest will by default refer to the test server by the
        // loopback address rather than any hostname in the navigation (i.e.,
        // the EmbeddedTestServer has no notion of virtual hosts). This
        // explicitly sets the hostname back to the test host so that this
        // doesn't fail due to the exception for localhost.
        http_downgrade.SetHostStr("foo.com");
        auto redirect_url = request.GetURL().ReplaceComponents(http_downgrade);
        auto response = std::make_unique<net::test_server::BasicHttpResponse>();
        response->set_code(net::HTTP_TEMPORARY_REDIRECT);
        response->AddCustomHeader("Location", redirect_url.spec());
        return response;
      }));
  ASSERT_TRUE(downgrading_server.Start());
  HttpsUpgradesInterceptor::SetHttpPortForTesting(downgrading_server.port());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(downgrading_server.port());

  GURL url = downgrading_server.GetURL("foo.com", "/");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
  }

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeRedirectLoop,
                                  1);
}

// Tests that the security level is WARNING when the HTTPS-Only Mode
// interstitial is shown for a net error on HTTPS. (Without HTTPS-Only Mode, a
// net error would be a security level of NONE.)
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       NetErrorOnUpgrade_SecurityLevelWarning) {
  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL https_url = https_server()->GetURL("foo.com", "/close-socket");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

    EXPECT_EQ(security_state::WARNING,
              chrome_security_state::GetSecurityLevel(contents));

    // Proceed through the interstitial to navigate to the HTTP site.
    ProceedThroughHttpsFirstModeInterstitial(contents);
  }

  // The HTTP site results in a net error, which should have security level NONE
  // (as no connection was made).
  // TODO(crbug.com/40248833): Uncomment once upgrades are tracked
  // per-navigation.
  // EXPECT_EQ(security_state::NONE,
  // chrome_security_state::GetSecurityLevel(contents));
}

// Tests that the security level is WARNING when the HTTPS-Only Mode
// interstitial is shown for a cert error on HTTPS. (Without HTTPS-Only Mode, a
// a cert error would be a security level of DANGEROUS.) After clicking through
// the interstitial, the security level should still be WARNING.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       BrokenSSLOnUpgrade_SecurityLevelWarning) {
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

    EXPECT_EQ(security_state::WARNING,
              chrome_security_state::GetSecurityLevel(contents));

    // Proceed through the interstitial to navigate to the HTTP page.
    ProceedThroughHttpsFirstModeInterstitial(contents);
  }

  // The security level should still be WARNING.
  EXPECT_EQ(security_state::WARNING,
            chrome_security_state::GetSecurityLevel(contents));
}

// Regression test for crbug.com/40780767.
// Tests the case where the HTTP version of a site redirects to HTTPS, but the
// HTTPS version of the site has a cert error. If the user initially navigates
// to the HTTP URL, then HTTPS-First Mode should upgrade the navigation to HTTPS
// and trigger the HTTPS-First Mode interstitial when that fails, but if the
// user clicks through the HTTPS-First Mode interstitial and falls back into the
// HTTP->HTTPS redirect back to the cert error, then the SSL interstitial should
// be shown and the user should be able to click through the SSL interstitial to
// visit the HTTPS version of the site (but in a DANGEROUS security level
// state).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       HttpsUpgradeWithBrokenSSL_ShouldTriggerSSLInterstitial) {
  // Set up a new test server instance so it can have a custom handler that
  // redirects to the HTTPS server.
  net::EmbeddedTestServer upgrading_server{net::EmbeddedTestServer::TYPE_HTTP};
  upgrading_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        auto response = std::make_unique<net::test_server::BasicHttpResponse>();
        response->set_code(net::HTTP_TEMPORARY_REDIRECT);
        response->AddCustomHeader(
            "Location",
            "https://bad-https.com:" +
                base::NumberToString(
                    HttpsUpgradesInterceptor::GetHttpsPortForTesting()) +
                "/simple.html");
        return response;
      }));
  ASSERT_TRUE(upgrading_server.Start());
  HttpsUpgradesInterceptor::SetHttpPortForTesting(upgrading_server.port());

  GURL http_url = upgrading_server.GetURL("bad-https.com", "/simple.html");
  // HTTPS server will have a cert error.
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // The HTTPS-First Mode interstitial should trigger first.
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

    // Proceeding through the HTTPS-First Mode interstitial will hit the
    // upgrading server's HTTP->HTTPS redirect. This should result in an SSL
    // interstitial (not an HTTPS-First Mode interstitial).
    ProceedThroughHttpsFirstModeInterstitial(contents);
  }

  EXPECT_EQ(https_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingSSLInterstitial(contents));

  // Proceeding through the SSL interstitial should navigate to the HTTPS
  // version of the site but with the DANGEROUS security level.
  ProceedThroughHttpsFirstModeInterstitial(contents);
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());
  EXPECT_EQ(security_state::DANGEROUS,
            chrome_security_state::GetSecurityLevel(contents));

  // Verify that navigation event metrics were correctly recorded. They should
  // only have been recorded for the initial navigation that resulted in the
  // HTTPS-First Mode interstitial.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // Verify that the interstitial metrics were correctly recorded.
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::SHOW, 1);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::PROCEED, 1);
  }
}

// Tests that clicking the "Learn More" link in the HTTPS-First Mode
// interstitial opens a new tab for the help center article.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, InterstitialLearnMoreLink) {
  // This test is only relevant to HTTPS-First Mode.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL https_url = https_server()->GetURL("foo.com", "/close-socket");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

  // Simulate clicking the learn more link.
  auto* tab_interface = tabs::TabInterface::MaybeGetFromContents(contents);
  auto* controller = tab_interface
                         ? AskBeforeHttpDialogController::From(tab_interface)
                         : nullptr;
  if (controller && controller->HasOpenDialog()) {
    controller->ClickLearnMoreForTesting();
  } else {
    ASSERT_TRUE(content::ExecJs(
        contents, "window.certificateErrorPageController.openHelpCenter();"));
  }

  // New tab should include the p-link "first_mode".
  EXPECT_EQ(GetBrowser()
                ->tab_strip_model()
                ->GetActiveWebContents()
                ->GetVisibleURL()
                .GetQuery(),
            "p=first_mode");

  // Verify that the interstitial metrics were correctly recorded.
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.decision",
      security_interstitials::MetricsHelper::Decision::SHOW, 1);
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.interaction",
      security_interstitials::MetricsHelper::Interaction::TOTAL_VISITS, 1);
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.interaction",
      security_interstitials::MetricsHelper::Interaction::SHOW_LEARN_MORE, 1);
}

// Tests that if the user bypasses the HTTPS-First Mode interstitial, and then
// later the server fixes their HTTPS support and the user successfully connects
// over HTTPS, the allowlist entry is cleared (so HFM will kick in again for
// that site).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, BadHttpsFollowedByGoodHttps) {
  // TODO(crbug.com/40248833): This test is flakey when only HTTPS Upgrades are
  // enabled.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL bad_https_url = https_server()->GetURL("foo.com", "/close-socket");
  GURL good_https_url = https_server()->GetURL("foo.com", "/ssl/google.html");

  ASSERT_EQ(http_url.GetHost(), bad_https_url.GetHost());
  ASSERT_EQ(bad_https_url.GetHost(), good_https_url.GetHost());

  auto* tab = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  auto* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  auto* state = static_cast<StatefulSSLHostStateDelegate*>(
      profile->GetSSLHostStateDelegate());

  // First check that main frame requests revoke the decision.

  // Navigate to `http_url`, which will get upgraded to `bad_https_url`.
  NavigateAndWaitForFallback(tab, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    ASSERT_TRUE(IsShowingHttpsFirstModeInterstitial(tab));
    ProceedThroughHttpsFirstModeInterstitial(tab);
  }

  EXPECT_TRUE(state->HasAllowException(
      http_url.GetHost(), tab->GetPrimaryMainFrame()->GetStoragePartition()));

  EXPECT_TRUE(NavigateToURLWithLinkTransition(tab, good_https_url));
  EXPECT_FALSE(state->HasAllowException(
      http_url.GetHost(), tab->GetPrimaryMainFrame()->GetStoragePartition()));

  // Rarely, an open connection with the bad cert might be reused for the next
  // navigation, which is supposed to show an interstitial. Close open
  // connections to ensure a fresh connection (and certificate validation) for
  // the next navigation. See https://crbug.com/40732511. A deeper fix for this
  // issue would be to unify certificate bypass logic which is currently split
  // between the net stack and content layer; see https://crbug.com/40418163.
  // See also: SSLUITest.BadCertFollowedByGoodCert.
  state->RevokeUserAllowExceptionsHard(http_url.GetHost());

  // Now check that subresource requests revoke the decision.

  // Navigate to `http_url`, which will get upgraded to `bad_https_url`.
  NavigateAndWaitForFallback(tab, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    ASSERT_TRUE(IsShowingHttpsFirstModeInterstitial(tab));
    ProceedThroughHttpsFirstModeInterstitial(tab);
  }

  EXPECT_TRUE(state->HasAllowException(
      http_url.GetHost(), tab->GetPrimaryMainFrame()->GetStoragePartition()));

  // Load "logo.gif" as an image on the page.
  GURL image = https_server()->GetURL("foo.com", "/ssl/google_files/logo.gif");

  // TODO(crbug.com/422956041): this fetch generates an LNA request, its unclear
  // why. Investigation is required to see if this is an LNA bug or not.
  EXPECT_EQ(
      true,
      EvalJs(tab,
             std::string("var img = document.createElement('img');img.src ='") +
                 image.spec() +
                 "';"
                 "new Promise(resolve => {"
                 "  img.onload=function() { "
                 "    resolve(true); };"
                 "  document.body.appendChild(img);"
                 "});"));

  EXPECT_FALSE(state->HasAllowException(
      http_url.GetHost(), tab->GetPrimaryMainFrame()->GetStoragePartition()));
}

// Tests that clicking the "Go back" button in the HTTPS-First Mode interstitial
// navigates back to the previous page (about:blank in this case).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, InterstitialGoBack) {
  // This test is only relevant to HTTPS-First Mode.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL https_url = https_server()->GetURL("foo.com", "/close-socket");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

  // Simulate clicking the "Go back" button.
  DontProceedThroughHttpsFirstModeInterstitial(contents);

  EXPECT_EQ(GURL("about:blank"), contents->GetLastCommittedURL());

  // Verify that the interstitial metrics were correctly recorded.
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.decision",
      security_interstitials::MetricsHelper::Decision::SHOW, 1);
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.decision",
      security_interstitials::MetricsHelper::Decision::DONT_PROCEED, 1);

  ExpectUKMEntry(http_url, BlockingResult::kInterstitialDontProceed);
}

// Tests that closing the tab of the HTTPS-First Mode interstitial counts as
// not proceeding through the interstitial for metrics.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, CloseInterstitialTab) {
  // This test is only relevant to HTTPS-First Mode.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL https_url = https_server()->GetURL("foo.com", "/close-socket");

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

  // Leave the interstitial by closing the tab.
  chrome::CloseWebContents(GetBrowser(), contents, false);

  // Verify that the interstitial metrics were correctly recorded.
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.decision",
      security_interstitials::MetricsHelper::Decision::SHOW, 1);
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.decision",
      security_interstitials::MetricsHelper::Decision::DONT_PROCEED, 1);

  ExpectUKMEntry(http_url, BlockingResult::kInterstitialDontProceed);
}

// Tests that if a user allowlists a host and then does not visit it again for
// seven days (the expiration period), then the interstitial will be shown again
// the next time they visit the host.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, AllowlistEntryExpires) {
  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Set a testing clock on the StatefulSSLHostStateDelegate, keeping a pointer
  // to the clock object around so the test can manipulate time. `chrome_state`
  // takes ownership of `clock`.
  auto clock = std::make_unique<base::SimpleTestClock>();
  auto* clock_ptr = clock.get();
  StatefulSSLHostStateDelegate* chrome_state =
      static_cast<StatefulSSLHostStateDelegate*>(state);
  chrome_state->SetClockForTesting(std::move(clock));

  // Start the clock at standard system time.
  clock_ptr->SetNow(base::Time::NowFromSystemTime());

  // Visit a host that doesn't support HTTPS for the first time, and click
  // through the HTTPS-First Mode interstitial to allowlist the host.
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    ProceedThroughHttpsFirstModeInterstitial(contents);
  }

  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));

  // Simulate the clock advancing by 16 days, which is past the expiration
  // point.
  clock_ptr->Advance(base::Days(16));

  // The host should no longer be allowlisted, and the interstitial should
  // trigger again.
  EXPECT_FALSE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
  }
}

// Tests that re-visiting an allowlisted host bumps the expiration time to a new
// seven days in the future from now.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, RevisitingBumpsExpiration) {
  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Set a testing clock on the StatefulSSLHostStateDelegate, keeping a pointer
  // to the clock object around so the test can manipulate time. `chrome_state`
  // takes ownership of `clock`.
  auto clock = std::make_unique<base::SimpleTestClock>();
  auto* clock_ptr = clock.get();
  StatefulSSLHostStateDelegate* chrome_state =
      static_cast<StatefulSSLHostStateDelegate*>(state);
  chrome_state->SetClockForTesting(std::move(clock));

  // Start the clock at standard system time.
  clock_ptr->SetNow(base::Time::NowFromSystemTime());

  // Visit a host that doesn't support HTTPS for the first time, and click
  // through the HTTPS-First Mode interstitial to allowlist the host.
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    ProceedThroughHttpsFirstModeInterstitial(contents);
  }

  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));

  // Simulate the clock advancing by ten days.
  clock_ptr->Advance(base::Days(10));

  // Navigate to the host again; this will reset the allowlist expiration to
  // now + 7 days.
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));

  // Simulate the clock advancing another ten days. This will be _after_ the
  // initial expiration date of the allowlist entry, but _before_ the bumped
  // expiration date from the second navigation.
  clock_ptr->Advance(base::Days(10));
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
}

// Tests that if a hostname has an HSTS entry registered, then HTTPS-First Mode
// should not try to upgrade it (instead allowing HSTS to handle the upgrade as
// it is more strict).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, PreferHstsOverHttpsFirstMode) {
  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());

  // URL for HTTPS server that will result in a certificate error.
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  // HTTP version of that URL that will get upgraded to HTTPS (but with the
  // correct port for the HTTPS server -- the test code can configure
  // HTTPS-First Mode to be aware of the different ports, but can't do that for
  // HSTS).
  GURL::Replacements downgrade_scheme_to_http;
  downgrade_scheme_to_http.SetSchemeStr(url::kHttpScheme);
  GURL http_url = https_url.ReplaceComponents(downgrade_scheme_to_http);

  // Set HTTP testing port to match `http_url`.
  HttpsUpgradesInterceptor::SetHttpPortForTesting(http_url.EffectiveIntPort());

  // Add hostname to the TransportSecurityState.
  base::Time expiry = base::Time::Now() + base::Days(100);
  bool include_subdomains = false;
  auto* network_context =
      profile->GetDefaultStoragePartition()->GetNetworkContext();
  base::RunLoop run_loop;
  network_context->AddHSTS(http_url.GetHost(), expiry, include_subdomains,
                           run_loop.QuitClosure());
  run_loop.Run();

  // Navigate to the HTTP URL. It should get upgraded to HTTPS and trigger a
  // fatal certificate error (because of HTTPS) instead of falling back to the
  // HTTPS-First Mode interstitial.
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingSSLInterstitial(contents));

  // Verify that no HFM event histograms were emitted (to check that HFM did not
  // trigger for this navigation at all).
  histograms()->ExpectTotalCount(kEventHistogram, 0);

  // Verify that general navigation request metrics were recorded.
  histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 2);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kHstsUpgraded,
                                  1);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kSecure, 1);
}

// Regression test for crbug.com/40806549. Previously, performing back/forward
// navigations around the HTTPS-First Mode interstitial could cause history
// entries to dropped.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       InterstitialFallbackMaintainsHistory) {
  // This test only applies to HTTPS-First Mode.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL good_https_url = https_server()->GetURL("site1.com", "/defaultresponse");

  // Set up a new test server instance so it can have a custom handler.
  net::EmbeddedTestServer downgrading_server{
      net::EmbeddedTestServer::TYPE_HTTPS};
  // Downgrade by swapping the scheme for HTTP. HTTPS-First Mode will upgrade it
  // back to HTTPS.
  downgrading_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        GURL::Replacements http_downgrade;
        http_downgrade.SetSchemeStr(url::kHttpScheme);
        // The HttpRequest will by default refer to the test server by the
        // loopback address rather than any hostname in the navigation (i.e.,
        // the EmbeddedTestServer has no notion of virtual hosts). This
        // explicitly sets the hostname back to the test host so that this
        // doesn't fail due to the exception for localhost.
        http_downgrade.SetHostStr("site2.com");
        auto redirect_url = request.GetURL().ReplaceComponents(http_downgrade);
        auto response = std::make_unique<net::test_server::BasicHttpResponse>();
        response->set_code(net::HTTP_TEMPORARY_REDIRECT);
        response->AddCustomHeader("Location", redirect_url.spec());
        return response;
      }));
  ASSERT_TRUE(downgrading_server.Start());
  HttpsUpgradesInterceptor::SetHttpPortForTesting(downgrading_server.port());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(downgrading_server.port());

  GURL downgrading_https_url = downgrading_server.GetURL("site2.com", "/");
  GURL::Replacements swap_http_scheme;
  swap_http_scheme.SetSchemeStr(url::kHttpScheme);
  GURL downgrading_http_url =
      downgrading_https_url.ReplaceComponents(swap_http_scheme);

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();

  // Navigate to a "good" HTTPS site.
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, good_https_url));

  // Navigate to the HTTP version of `downgrading_https_url`, which will get
  // upgraded to HTTPS and fail, triggering the HTTPS-First Mode
  // interstitial.
  NavigateToURLWithLinkTransitionBlockUntilNavigationsComplete(
      contents, downgrading_http_url, 1);
  EXPECT_EQ(downgrading_http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

  // Simulate clicking the browser "back" button.
  EXPECT_TRUE(content::HistoryGoBack(contents));
  EXPECT_EQ(good_https_url, contents->GetLastCommittedURL());
  EXPECT_EQ(security_state::SECURE,
            chrome_security_state::GetSecurityLevel(contents));

  // Simulate clicking the browser "forward" button. The HistoryGoForward()
  // call returns `false` because it is an error page.
  EXPECT_FALSE(content::HistoryGoForward(contents));
  EXPECT_EQ(downgrading_http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

  // No forward entry should be present.
  EXPECT_FALSE(contents->GetController().CanGoForward());

  // Simulate clicking the browser "back" button again. Previously this would
  // result in `about:blank` being shown.
  EXPECT_TRUE(content::HistoryGoBack(contents));
  EXPECT_EQ(good_https_url, contents->GetLastCommittedURL());

  // Repeat forward one last time. (Previously the user would no longer be able
  // to go back any more as the history entries were lost.)
  EXPECT_FALSE(content::HistoryGoForward(contents));  // error page -> false
  EXPECT_EQ(downgrading_http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
  EXPECT_TRUE(contents->GetController().CanGoBack());
}

// Tests that if the HttpAllowlist enterprise policy is set, then HTTPS upgrades
// are skipped for hosts in the allowlist. Includes simple hostname, wildcard
// hostname pattern, and bare IP address cases.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       EnterpriseAllowlistDisablesUpgrades) {
  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();

  // Without any policy allowlist, navigate to HTTP URL on foo.com. It *should*
  // get upgraded to HTTPS.
  auto http_url = http_server()->GetURL("foo.com", "/simple.html");
  auto https_url = https_server()->GetURL("foo.com", "/simple.html");
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());

  // Artificially add the pref that gets mapped from the enterprise policy.
  auto* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  auto* prefs = profile->GetPrefs();
  base::ListValue allowlist;
  allowlist.Append("foo.com");
  allowlist.Append("[*.]bar.com");
  allowlist.Append(http_server()->GetIPLiteralString());
  // These cases should not work, but the policy->pref mapping won't immediately
  // reject them.
  allowlist.Append("[*]");
  allowlist.Append("*");
  prefs->SetList(prefs::kHttpAllowlist, std::move(allowlist));

  // Navigate to HTTP URL on foo.com. It should not get upgraded to HTTPS and
  // no interstitial should be shown.
  http_url = http_server()->GetURL("foo.com", "/simple.html");
  https_url = https_server()->GetURL("foo.com", "/simple.html");
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));

  // Navigate to HTTP URL on bar.com. Same result.
  http_url = http_server()->GetURL("bar.com", "/simple.html");
  https_url = https_server()->GetURL("bar.com", "/simple.html");
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));

  // Navigate to HTTP URL on bar.bar.com. Same result as subdomain wildcard
  // was specified.
  http_url = http_server()->GetURL("bar.bar.com", "/simple.html");
  https_url = https_server()->GetURL("bar.bar.com", "/simple.html");
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));

  // Navigate to HTTP URL on foo.foo.com. Subdomains of foo.com should not be
  // considered as being in the allowlist as no wildcard was specified. This
  // should get upgraded to HTTPS.
  http_url = http_server()->GetURL("foo.foo.com", "/simple.html");
  https_url = https_server()->GetURL("foo.foo.com", "/simple.html");
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());

  // Navigate to HTTP URL on baz.com, which is not on the allowlist. Should get
  // upgraded to HTTPS.
  http_url = http_server()->GetURL("baz.com", "/simple.html");
  https_url = https_server()->GetURL("baz.com", "/simple.html");
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());

  // Navigate to HTTP URL on the HTTP test server's IP address. It should not
  // get upgraded to HTTPS and no interstitial should be shown.
  http_url = http_server()->GetURL("/simple.html");
  https_url = https_server()->GetURL("/simple.html");
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
}

// Tests that if the HttpAllowlist enterprise policy is set, then HTTPS upgrades
// and HTTPS-First Mode For Site Engagement checks are skipped for hosts in the
// allowlist.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    EnterpriseAllowlistDisablesHttpsFirstModeForSiteEngagament) {
  // Skip this test when HTTPS-First Mode for Site Engagement isn't enabled.
  if (!IsSiteEngagementHeuristicEnabled()) {
    return;
  }
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  auto* profile = Profile::FromBrowserContext(contents->GetBrowserContext());

  // Without any policy allowlist, navigate to an HTTP URL. It should show the
  // HFM+SE interstitial.
  GURL http_url("http://bad-https.com");
  GURL https_url("https://bad-https.com");
  SetSiteEngagementScore(http_url, kLowSiteEngagementScore);
  SetSiteEngagementScore(https_url, kHighSiteEnagementScore);

  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  MaybeEnableHttpsFirstModeForEngagedSitesAndWait(hfm_service);

  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

  // Artificially add the pref that gets mapped from the enterprise policy.
  auto* prefs = profile->GetPrefs();
  base::ListValue allowlist;
  allowlist.Append("bad-https.com");
  prefs->SetList(prefs::kHttpAllowlist, std::move(allowlist));

  // Navigate to the same URL. It should not get upgraded to HTTPS and
  // no interstitial should be shown.
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
}

IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       EnterprisePolicyDisablesUpgrades) {
  // Disable HTTPS-Upgrades via enterprise policy.
  auto* prefs = browser()->GetProfile()->GetPrefs();
  prefs->SetBoolean(prefs::kHttpsUpgradesEnabled, false);

  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // HTTPS-First Mode should supersede HTTPS-Upgrades and upgrade the
    // navigation despite the HttpsUpgradeMode policy setting.
    EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // If HTTPS-First Mode is not enabled but upgrading is, then the policy
    // should prevent the upgrade.
    EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kAllowlisted, 1);
  }
}

// Test that HTTPS Upgrades are skipped if the "Insecure content" site setting
// is set to "allow".
// MIXED_SCRIPT isn't enabled as a content setting on Android.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_InsecureContentSettingDisablesUpgrades \
  DISABLED_InsecureContentSettingDisablesUpgrades
#else
#define MAYBE_InsecureContentSettingDisablesUpgrades \
  InsecureContentSettingDisablesUpgrades
#endif
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       MAYBE_InsecureContentSettingDisablesUpgrades) {
  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  auto* host_content_settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile);

  // Set insecure content setting to allowed for `http_url`.
  host_content_settings_map->SetContentSettingDefaultScope(
      http_url, GURL(), ContentSettingsType::MIXEDSCRIPT,
      CONTENT_SETTING_ALLOW);

  if (IsStrictInterstitialEnabledForTest()) {
    // If HTTPS-First Mode is enabled, upgrades should still be applied.
    EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // Otherwise, the upgrades should be skipped.
    EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kAllowlisted, 1);
  }

  // Unset the content settings.
  host_content_settings_map->ClearSettingsForOneType(
      ContentSettingsType::MIXEDSCRIPT);

  // Set insecure content setting to allowed for `https_url`.
  HostContentSettingsMapFactory::GetForProfile(profile)
      ->SetContentSettingDefaultScope(https_url, GURL(),
                                      ContentSettingsType::MIXEDSCRIPT,
                                      CONTENT_SETTING_ALLOW);
  if (IsStrictInterstitialEnabledForTest()) {
    // If HTTPS-First Mode is enabled, upgrades should still be applied.
    EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    2);
  } else {
    // Otherwise, the upgrades should be skipped.
    EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kAllowlisted, 2);
  }
}

// Test that HTTPS Upgrades are skipped if the "Insecure content" site setting
// is set to "allow".
// MIXED_SCRIPT isn't enabled as a content setting on Android.
// This test is identical to InsecureContentSettingDisablesUpgrades except it
// sets a high site engagement score for the https URL and checks an additional
// histogram.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_InsecureContentSettingDisablesHFMForEngagedSites \
  DISABLED_InsecureContentSettingDisablesHFMForEngagedSites
#else
#define MAYBE_InsecureContentSettingDisablesHFMForEngagedSites \
  InsecureContentSettingDisablesHFMForEngagedSites
#endif
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       MAYBE_InsecureContentSettingDisablesHFMForEngagedSites) {
  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  auto* host_content_settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile);

  // Setting a high engagement score on the HTTPS URL enables HFM on the site
  // if the HFM+SE feature is enabled, but an Insecure Content entry disables
  // HFM+SE on the site.
  SetSiteEngagementScore(http_url, kLowSiteEngagementScore);
  SetSiteEngagementScore(https_url, kHighSiteEnagementScore);

  // Set insecure content setting to allowed for `http_url`.
  host_content_settings_map->SetContentSettingDefaultScope(
      http_url, GURL(), ContentSettingsType::MIXEDSCRIPT,
      CONTENT_SETTING_ALLOW);

  if (IsStrictInterstitialEnabledForTest()) {
    // If HTTPS-First Mode is fully enabled, upgrades should still be applied.
    EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // Otherwise, the upgrades should be skipped.
    EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kAllowlisted, 1);
  }
  // In both cases, HFM+SE events shouldn't be recorded because of the Insecure
  // content setting.
  histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);

  // Unset the content settings.
  host_content_settings_map->ClearSettingsForOneType(
      ContentSettingsType::MIXEDSCRIPT);

  // Set insecure content setting to allowed for `https_url`.
  HostContentSettingsMapFactory::GetForProfile(profile)
      ->SetContentSettingDefaultScope(https_url, GURL(),
                                      ContentSettingsType::MIXEDSCRIPT,
                                      CONTENT_SETTING_ALLOW);
  if (IsStrictInterstitialEnabledForTest()) {
    // If HTTPS-First Mode is enabled, upgrades should still be applied.
    EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    2);
  } else {
    // Otherwise, the upgrades should be skipped.
    EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kAllowlisted, 2);
  }
  // In both cases, HFM+SE events shouldn't be recorded because of the Insecure
  // content setting.
  histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);
}

// Regression test for crbug.com/40902071. Triggers a navigation where HTTPS
// upgrades applied multiple times across redirects to different sites.
// Should not crash when DCHECKS are enabled.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, crbug1431026) {
  GURL www_bad_https_url =
      https_server()->GetURL("www.bad-https.com", "/simple.html");
  GURL www_http_url =
      http_server()->GetURL("www.bad-https.com", "/simple.html");

  // Configure HTTP and bad-HTTPS URLs which redirect to www. subdomain.
  std::string www_redirect_path =
      base::StrCat({"/server-redirect?", www_http_url.spec()});
  GURL redirecting_bad_https_url =
      https_server()->GetURL("bad-https.com", www_redirect_path);
  GURL redirecting_http_url =
      http_server()->GetURL("bad-https.com", www_redirect_path);

  // A good HTTPS URL which redirects to an HTTP URL, which also redirects.
  GURL initial_redirecting_good_https_url = https_server()->GetURL(
      "good-https.com",
      base::StrCat({"/server-redirect-301?", redirecting_http_url.spec()}));

  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  EXPECT_FALSE(NavigateToURLWithLinkTransition(
      contents, initial_redirecting_good_https_url));

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // Should be showing interstitial on http://bad-https.com/.
    EXPECT_EQ(redirecting_http_url, contents->GetLastCommittedURL());
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
  } else {
    // Either due to no upgrades, or due to fast fallback to HTTP, this should
    // end up on http://www.bad-https.com.
    EXPECT_EQ(www_http_url, contents->GetLastCommittedURL());
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  }
}

// Tests that when the HTTPS-First Mode setting is toggled on or off, the
// HTTP allowlist is cleared.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       TogglingSettingClearsAllowlist) {
  // The allowlist in an Incognito or Isolated Mode window is in-memory only,
  // and is not cleared when the main profile's pref changes.
  // TODO(crbug.com/40937027): Add a test to cover the Incognito allowlisting
  // behavior explicitly.
  if (IsIncognitoOrIsolatedBrowser()) {
    return;
  }

  // Advanced Protection users have HFM enabled regardless of the pref.
  if (https_upgrades_test_type() ==
      HttpsUpgradesTestType::kHttpsFirstModeAdvancedProtection) {
    return;
  }

  auto http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();

  // Start by enabling HTTPS-First Mode.
  SetPref(true);

  // Navigate to a URL that will fail upgrades, and click through the
  // interstitial to add it to the allowlist.
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
  ProceedThroughHttpsFirstModeInterstitial(contents);

  // Disable the HTTPS-First Mode pref. This should clear the allowlist.
  SetPref(false);

  if (InBalancedMode()) {
    EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));

    // Proceed through the interstitial and add the host to the allowlist.
    ProceedThroughHttpsFirstModeInterstitial(contents);
  } else {
    // With HTTPS-Upgrades enabled, navigating again should cause the site to
    // get added back to the allowlist.
    EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));
    EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  }

  // Re-enable the HTTPS-First Mode pref. The allowlist should be cleared again.
  SetPref(true);

  // Navigate to a URL that will fail upgrades, and the interstitial should be
  // shown again as the allowlist was cleared.
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
}

// Main window HTTP allowlist should not apply to Incognito window.
// Regression test for crbug.com/40949400.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       IncognitoHasSeparateAllowlist) {
  // This test only covers the cases of HFM-in-Incognito and
  // HFM-in-Isolated-Mode.
  if (!IsIncognitoOrIsolatedBrowser()) {
    return;
  }
  // In a regular window, add a host to the HTTP allowlist.
  // Note: This is explicitly done with HTTPS-First Mode disabled as that is the
  // specific regression case for crbug.com/40949400, but HTTPS-First Mode and
  // HTTPS-Upgrades may eventually have separate allowlists.
  SetPref(false);
  auto http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  auto* normal_tab = browser()->GetTabStripModel()->GetActiveWebContents();
  EXPECT_TRUE(NavigateToURLWithLinkTransition(normal_tab, http_url));
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(normal_tab));

  // In an Incognito window, navigating to that same host should still trigger
  // the HTTP interstitial, as the allowlist is not inherited.
  auto* incognito_tab =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  EXPECT_FALSE(NavigateToURLWithLinkTransition(incognito_tab, http_url));
  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(incognito_tab));
}

// Tests that URLs typed with an explicit http:// scheme are opted out from
// upgrades.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       URLsTypedWithHttpSchemeNoUpgrades) {
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  OmniboxClient* omnibox_client = BrowserWindow::FromBrowser(GetBrowser())
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  // Simulate the full URL was typed with an http scheme.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::URL_WHAT_YOU_TYPED,
      base::TimeTicks(), false, true, std::u16string(), AutocompleteMatch(),
      AutocompleteMatch());
  nav_observer.Wait();

  if (IsStrictInterstitialEnabledForTest()) {
    // Typed http URLs don't opt out of upgrades in HFM.
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
  } else {
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 1);
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kExplicitHttpScheme, 1);
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  }
}

// Tests that URLs with an explicit http:// scheme are upgraded if they were
// autocompleted.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       URLsAutocompletedWithHttpSchemeAreUpgraded) {
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  OmniboxClient* omnibox_client = BrowserWindow::FromBrowser(GetBrowser())
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  // Simulate the full URL was autocompleted with an http scheme.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::NAVSUGGEST,
      base::TimeTicks(), false, false, std::u16string(), AutocompleteMatch(),
      AutocompleteMatch());
  nav_observer.Wait();

  EXPECT_EQ(https_url, contents->GetLastCommittedURL());
}

// Tests that URLs typed with an explicit http:// scheme that result in an
// opt-out cause the url to be added to the allowlist.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       URLsTypedWithHttpSchemeNoUpgradesAllowlist) {
  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  OmniboxClient* omnibox_client = BrowserWindow::FromBrowser(GetBrowser())
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Site should not yet be in the allowlist.
  EXPECT_FALSE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));

  // Simulate the full URL was typed with an http scheme.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::URL_WHAT_YOU_TYPED,
      base::TimeTicks(), false, true, std::u16string(), AutocompleteMatch(),
      AutocompleteMatch());
  nav_observer.Wait();

  // URL should not have been upgraded, and site should now be in the allowlist.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));
}

// Tests that when a URL typed with an explicit http:// scheme is redirected by
// the server to other hosts, only the host of the originally typed URL is
// added to the allowlist. The exemption applies to the navigation as a whole,
// but server-chosen redirect targets must not be persistently allowlisted.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       URLsTypedWithHttpSchemeAllowlistOnlyInitialHost) {
  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }
  GURL final_url = http_server()->GetURL("baz.com", "/simple.html");
  GURL hop_url =
      http_server()->GetURL("bar.com", "/server-redirect?" + final_url.spec());
  GURL initial_url =
      http_server()->GetURL("foo.com", "/server-redirect?" + hop_url.spec());
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  OmniboxClient* omnibox_client = BrowserWindow::FromBrowser(GetBrowser())
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  auto* storage_partition =
      contents->GetPrimaryMainFrame()->GetStoragePartition();

  // None of the hosts should be in the allowlist yet.
  EXPECT_FALSE(state->IsHttpAllowedForHost("foo.com", storage_partition));
  EXPECT_FALSE(state->IsHttpAllowedForHost("bar.com", storage_partition));
  EXPECT_FALSE(state->IsHttpAllowedForHost("baz.com", storage_partition));

  // Simulate the full URL was typed with an http scheme. The server redirects
  // through bar.com and baz.com.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      initial_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::URL_WHAT_YOU_TYPED,
      base::TimeTicks(), false, true, std::u16string(), AutocompleteMatch(),
      AutocompleteMatch());
  nav_observer.Wait();

  // None of the hops should have been upgraded.
  EXPECT_EQ(final_url, contents->GetLastCommittedURL());

  // The host the user typed should be in the allowlist, but the
  // server-selected redirect targets should not.
  EXPECT_TRUE(state->IsHttpAllowedForHost("foo.com", storage_partition));
  EXPECT_FALSE(state->IsHttpAllowedForHost("bar.com", storage_partition));
  EXPECT_FALSE(state->IsHttpAllowedForHost("baz.com", storage_partition));
}

// Returns a URL loader interceptor that responds to HTTPS URLs with a timeout
// error.
std::unique_ptr<content::URLLoaderInterceptor> MakeTimeoutInterceptor() {
  return std::make_unique<content::URLLoaderInterceptor>(
      base::BindLambdaForTesting(
          [](content::URLLoaderInterceptor::RequestParams* params) {
            if (params->url_request.url.host() == "timeout-https.com") {
              if (params->url_request.url.SchemeIs("https")) {
                network::URLLoaderCompletionStatus status;
                status.error_code = net::ERR_TIMED_OUT;
                params->client->OnComplete(status);
                return true;
              }
              content::URLLoaderInterceptor::WriteResponse(
                  "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                  "<html>Done</html>", params->client.get());
              return true;
            }
            return false;
          }));
}

// Base test fixture for HttpsUpgrades typed schemeless navigation tests.
class HttpsUpgradesTypedSchemelessNavigationTestBase
    : public InProcessBrowserTest {
 public:
  HttpsUpgradesTypedSchemelessNavigationTestBase() = default;
  ~HttpsUpgradesTypedSchemelessNavigationTestBase() override = default;

  void SetUp() override {
    ChromeSecurityBlockingPageFactory::SetEnterpriseManagedForTesting(false);
    InProcessBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
    host_resolver()->AddRule("*", "127.0.0.1");

    scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate());
    net::CertVerifyResult verify_result;
    verify_result.is_issued_by_known_root = false;
    verify_result.verified_cert = cert;
    verify_result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "bad-https.com", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);

    http_server_.AddDefaultHandlers(GetChromeTestDataDir());
    https_server_.AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(http_server_.Start());
    ASSERT_TRUE(https_server_.Start());

    HttpsUpgradesInterceptor::SetHttpsPortForTesting(https_server()->port());
    HttpsUpgradesInterceptor::SetHttpPortForTesting(http_server()->port());
  }

  void TearDownOnMainThread() override {
    HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
    HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    mock_cert_verifier_.SetUpCommandLine(command_line);
  }

  void SetUpInProcessBrowserTestFixture() override {
    mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
  }

  void TearDownInProcessBrowserTestFixture() override {
    mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
  }

  net::EmbeddedTestServer* http_server() { return &http_server_; }
  net::EmbeddedTestServer* https_server() { return &https_server_; }
  base::HistogramTester* histograms() { return &histograms_; }

 protected:
  base::test::ScopedFeatureList feature_list_;

 private:
  net::EmbeddedTestServer http_server_{net::EmbeddedTestServer::TYPE_HTTP};
  net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
  content::ContentMockCertVerifier mock_cert_verifier_;
  base::HistogramTester histograms_;
};

class HttpsUpgradesTypedSchemelessNavigationNoTimeoutFallbackBrowserTest
    : public HttpsUpgradesTypedSchemelessNavigationTestBase {
 public:
  HttpsUpgradesTypedSchemelessNavigationNoTimeoutFallbackBrowserTest() {
    feature_list_.InitWithFeatures(
        /*enabled_features=*/
        {features::kHttpsUpgrades,
         features::kHttpsUpgradesTypedSchemelessNavigationNoTimeoutFallback},
        /*disabled_features=*/{
            features::kHttpsFirstModeV2ForEngagedSites,
            features::kHttpsFirstModeV2ForTypicallySecureUsers,
            features::kHttpsFirstBalancedModeAutoEnable});
  }
};

// Tests that typed schemeless navigations are upgraded to HTTPS, but do NOT
// fallback to HTTP if the upgrade fails due to timeout, when the feature flag
// is enabled.
IN_PROC_BROWSER_TEST_F(
    HttpsUpgradesTypedSchemelessNavigationNoTimeoutFallbackBrowserTest,
    TypedSchemelessNavigationNoTimeoutFallback) {
  // Set up the interceptor to simulate timeout on HTTPS.
  auto interceptor = MakeTimeoutInterceptor();

  // Use a mock host name that will be intercepted.
  GURL http_url = http_server()->GetURL("timeout-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("timeout-https.com", "/simple.html");

  content::WebContents* contents =
      browser()->GetTabStripModel()->GetActiveWebContents();
  OmniboxClient* omnibox_client = BrowserWindow::FromBrowser(browser())
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  // Simulate a typed schemeless navigation.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR),
      AutocompleteMatchType::URL_WHAT_YOU_TYPED, base::TimeTicks(), true, false,
      std::u16string(), AutocompleteMatch(), AutocompleteMatch());
  nav_observer.Wait();

  // The navigation should have been upgraded to HTTPS, and failed there.
  // Since fallback is disabled on timeout, it should NOT have navigated back to
  // HTTP.
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());

  // It should show a net error page (not HFM interstitial or SSL interstitial)
  // because HFM is disabled and it's a timeout.
  EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));

  // Verify metrics.
  histograms()->ExpectBucketCount(
      kNavigationRequestSecurityLevelHistogram,
      NavigationRequestSecurityLevel::kTypedSchemelessUpgraded, 1);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeTimedOut, 1);

  // Standard upgrade metrics should also be recorded.
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeTimedOut, 1);
}

// Tests that typed schemeless navigations upgraded to HTTPS DO fallback to HTTP
// if the upgrade fails due to a cert error, even when the feature flag is
// enabled (timeout restriction).
IN_PROC_BROWSER_TEST_F(
    HttpsUpgradesTypedSchemelessNavigationNoTimeoutFallbackBrowserTest,
    TypedSchemelessNavigationFallbackOnCertError) {
  // Use bad-https.com so that HTTPS upgrade fails with a cert error.
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");

  content::WebContents* contents =
      browser()->GetTabStripModel()->GetActiveWebContents();
  OmniboxClient* omnibox_client = BrowserWindow::FromBrowser(browser())
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  // Simulate a typed schemeless navigation.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR),
      AutocompleteMatchType::URL_WHAT_YOU_TYPED, base::TimeTicks(), true, false,
      std::u16string(), AutocompleteMatch(), AutocompleteMatch());
  nav_observer.Wait();

  // The navigation should have been upgraded to HTTPS, failed (cert error), and
  // fell back to HTTP.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));

  // Verify metrics.
  // Should record kTypedSchemelessUpgraded (since it was eligible at start).
  histograms()->ExpectBucketCount(
      kNavigationRequestSecurityLevelHistogram,
      NavigationRequestSecurityLevel::kTypedSchemelessUpgraded, 1);

  // Standard upgrade metrics should be recorded.
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  // Should NOT record kTypedSchemelessUpgradeTimedOut (since it did not fail
  // due to timeout).
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeSucceeded, 0);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeTimedOut, 0);
}

// Tests that typed schemeless navigations upgraded to HTTPS successfully load
// over HTTPS, and record success metrics, when the feature flag is enabled.
IN_PROC_BROWSER_TEST_F(
    HttpsUpgradesTypedSchemelessNavigationNoTimeoutFallbackBrowserTest,
    TypedSchemelessNavigationSuccess) {
  // Use a host that will succeed on HTTPS (default cert result is OK).
  GURL http_url = http_server()->GetURL("example.com", "/simple.html");
  GURL https_url = https_server()->GetURL("example.com", "/simple.html");

  content::WebContents* contents =
      browser()->GetTabStripModel()->GetActiveWebContents();
  OmniboxClient* omnibox_client = BrowserWindow::FromBrowser(browser())
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  // Simulate a typed schemeless navigation.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR),
      AutocompleteMatchType::URL_WHAT_YOU_TYPED, base::TimeTicks(), true, false,
      std::u16string(), AutocompleteMatch(), AutocompleteMatch());
  nav_observer.Wait();

  // The navigation should have been upgraded to HTTPS, and succeeded.
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));

  // Verify metrics.
  histograms()->ExpectBucketCount(
      kNavigationRequestSecurityLevelHistogram,
      NavigationRequestSecurityLevel::kTypedSchemelessUpgraded, 1);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeSucceeded, 1);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeTimedOut, 0);

  // Standard upgrade metrics.
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeSucceeded, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 0);
}

class HttpsUpgradesTypedSchemelessNavigationWithFallbackBrowserTest
    : public HttpsUpgradesTypedSchemelessNavigationTestBase {
 public:
  HttpsUpgradesTypedSchemelessNavigationWithFallbackBrowserTest() {
    feature_list_.InitWithFeatures(
        /*enabled_features=*/{features::kHttpsUpgrades},
        /*disabled_features=*/{
            features::kHttpsUpgradesTypedSchemelessNavigationNoTimeoutFallback,
            features::kHttpsFirstModeV2ForEngagedSites,
            features::kHttpsFirstModeV2ForTypicallySecureUsers,
            features::kHttpsFirstBalancedModeAutoEnable});
  }
};

// Tests that typed schemeless navigations are upgraded to HTTPS, and DO
// fallback to HTTP if the upgrade fails due to cert error, when the feature
// flag is disabled.
IN_PROC_BROWSER_TEST_F(
    HttpsUpgradesTypedSchemelessNavigationWithFallbackBrowserTest,
    TypedSchemelessNavigationFallbackOnCertError) {
  // Use bad-https.com so that HTTPS upgrade fails with a cert error.
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");

  content::WebContents* contents =
      browser()->GetTabStripModel()->GetActiveWebContents();
  OmniboxClient* omnibox_client = BrowserWindow::FromBrowser(browser())
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  // Simulate a typed schemeless navigation.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR),
      AutocompleteMatchType::URL_WHAT_YOU_TYPED, base::TimeTicks(), true, false,
      std::u16string(), AutocompleteMatch(), AutocompleteMatch());
  nav_observer.Wait();

  // The navigation should have been upgraded to HTTPS, failed, and fell back to
  // HTTP.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));

  // Verify metrics.
  // Should record kUpgraded (standard upgrade).
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kUpgraded, 1);
  histograms()->ExpectBucketCount(
      kNavigationRequestSecurityLevelHistogram,
      NavigationRequestSecurityLevel::kTypedSchemelessUpgraded, 0);

  // Standard upgrade metrics.
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  // Should NOT record kTypedSchemelessUpgrade metrics.
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeAttempted, 0);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeTimedOut, 0);
}

// Tests that typed schemeless navigations are upgraded to HTTPS, and DO
// fallback to HTTP if the upgrade fails due to timeout, when the feature flag
// is disabled.
IN_PROC_BROWSER_TEST_F(
    HttpsUpgradesTypedSchemelessNavigationWithFallbackBrowserTest,
    TypedSchemelessNavigationFallbackOnTimeout) {
  // Set up the interceptor to simulate timeout on HTTPS.
  auto interceptor = MakeTimeoutInterceptor();

  GURL http_url = http_server()->GetURL("timeout-https.com", "/simple.html");

  content::WebContents* contents =
      browser()->GetTabStripModel()->GetActiveWebContents();
  OmniboxClient* omnibox_client = BrowserWindow::FromBrowser(browser())
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  // Simulate a typed schemeless navigation.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR),
      AutocompleteMatchType::URL_WHAT_YOU_TYPED, base::TimeTicks(), true, false,
      std::u16string(), AutocompleteMatch(), AutocompleteMatch());
  nav_observer.Wait();

  // The navigation should have been upgraded to HTTPS, failed (timeout), and
  // fell back to HTTP.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));

  // Verify metrics.
  // Should record kUpgraded (standard upgrade).
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kUpgraded, 1);
  histograms()->ExpectBucketCount(
      kNavigationRequestSecurityLevelHistogram,
      NavigationRequestSecurityLevel::kTypedSchemelessUpgraded, 0);

  // Standard upgrade metrics.
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeTimedOut, 1);

  // Should NOT record kTypedSchemelessUpgrade metrics.
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeAttempted, 0);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeTimedOut, 0);
}

class HttpsUpgradesTypedSchemelessNavigationBalancedModeBrowserTest
    : public HttpsUpgradesTypedSchemelessNavigationTestBase {
 public:
  HttpsUpgradesTypedSchemelessNavigationBalancedModeBrowserTest() {
    feature_list_.InitWithFeatures(
        /*enabled_features=*/
        {features::kHttpsUpgrades,
         features::kHttpsUpgradesTypedSchemelessNavigationNoTimeoutFallback},
        /*disabled_features=*/{
            features::kHttpsFirstModeV2ForEngagedSites,
            features::kHttpsFirstModeV2ForTypicallySecureUsers,
            features::kHttpsFirstBalancedModeAutoEnable});
  }

  void SetUpOnMainThread() override {
    HttpsUpgradesTypedSchemelessNavigationTestBase::SetUpOnMainThread();
    browser()->GetProfile()->GetPrefs()->SetBoolean(
        prefs::kHttpsFirstBalancedMode, true);
  }

  void TearDownOnMainThread() override {
    browser()->GetProfile()->GetPrefs()->ClearPref(
        prefs::kHttpsFirstBalancedMode);
    HttpsUpgradesTypedSchemelessNavigationTestBase::TearDownOnMainThread();
  }
};

// Tests that typed schemeless navigations are upgraded to HTTPS, but do NOT
// fallback to HTTP if the upgrade fails due to timeout, even when HFM Balanced
// Mode is enabled.
IN_PROC_BROWSER_TEST_F(
    HttpsUpgradesTypedSchemelessNavigationBalancedModeBrowserTest,
    TypedSchemelessNavigationNoTimeoutFallback_BalancedMode) {
  // Set up the interceptor to simulate timeout on HTTPS.
  auto interceptor = MakeTimeoutInterceptor();

  GURL http_url = http_server()->GetURL("timeout-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("timeout-https.com", "/simple.html");

  content::WebContents* contents =
      browser()->GetTabStripModel()->GetActiveWebContents();
  OmniboxClient* omnibox_client = BrowserWindow::FromBrowser(browser())
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  // Simulate a typed schemeless navigation.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR),
      AutocompleteMatchType::URL_WHAT_YOU_TYPED, base::TimeTicks(), true, false,
      std::u16string(), AutocompleteMatch(), AutocompleteMatch());
  nav_observer.Wait();

  // The navigation should have been upgraded to HTTPS, and failed there.
  // Since fallback is disabled on timeout, it should NOT have navigated back to
  // HTTP (and should NOT show the Balanced Mode interstitial on fallback).
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());

  // It should show a net error page (no HFM interstitial).
  EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));

  // Verify metrics.
  histograms()->ExpectBucketCount(
      kNavigationRequestSecurityLevelHistogram,
      NavigationRequestSecurityLevel::kTypedSchemelessUpgraded, 1);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeTimedOut, 1);
}

// Tests that typed schemeless navigations upgraded to HTTPS DO fallback to HTTP
// if the upgrade fails due to a cert error, when HFM Balanced Mode is enabled,
// and then they show the HFM Balanced Mode interstitial on the fallback HTTP
// page.
IN_PROC_BROWSER_TEST_F(
    HttpsUpgradesTypedSchemelessNavigationBalancedModeBrowserTest,
    TypedSchemelessNavigationFallback_BalancedMode) {
  // Use bad-https.com so that HTTPS upgrade fails with a cert error.
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");

  content::WebContents* contents =
      browser()->GetTabStripModel()->GetActiveWebContents();
  OmniboxClient* omnibox_client = BrowserWindow::FromBrowser(browser())
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  // Simulate a typed schemeless navigation.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR),
      AutocompleteMatchType::URL_WHAT_YOU_TYPED, base::TimeTicks(), true, false,
      std::u16string(), AutocompleteMatch(), AutocompleteMatch());
  nav_observer.Wait();

  // The navigation should have been upgraded to HTTPS, failed (cert error), and
  // fell back to HTTP.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  // Since Balanced Mode is enabled, falling back to HTTP should show the
  // Balanced Mode interstitial.
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      contents));

  // Verify metrics.
  // Should record kTypedSchemelessUpgraded (since it was eligible at start).
  histograms()->ExpectBucketCount(
      kNavigationRequestSecurityLevelHistogram,
      NavigationRequestSecurityLevel::kTypedSchemelessUpgraded, 1);

  // Standard upgrade metrics.
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  // Should NOT record kTypedSchemelessUpgradeTimedOut (since it did not time
  // out).
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeSucceeded, 0);
  histograms()->ExpectBucketCount(kEventHistogram,
                                  Event::kTypedSchemelessUpgradeTimedOut, 0);
}

// Url used to detect the presence of a captive portal.
constexpr char kCaptivePortalPingUrl[] = "http://captive-portal-ping-url.com/";
// HTTPS version of the same URL.
constexpr char kCaptivePortalPingUrlHttps[] =
    "https://captive-portal-ping-url.com/";

// Returns a URL loader interceptor that responds to HTTPS URLs with a cert
// error and to HTTP URLs with a good response.
std::unique_ptr<content::URLLoaderInterceptor> MakeCaptivePortalInterceptor(
    bool login_page_has_valid_https) {
  return std::make_unique<content::URLLoaderInterceptor>(
      base::BindLambdaForTesting(
          [login_page_has_valid_https](
              content::URLLoaderInterceptor::RequestParams* params) {
            if (params->url_request.url == GURL(kCaptivePortalPingUrl) ||
                (login_page_has_valid_https &&
                 params->url_request.url == GURL(kCaptivePortalPingUrlHttps))) {
              // Return a non-204 response for the captive portal ping URL
              // so that the portal is detected.
              content::URLLoaderInterceptor::WriteResponse(
                  "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                  "<html>Non-204 response to trigger captive portal "
                  "detection</html>",
                  params->client.get());
              return true;
            }

            if (params->url_request.url.SchemeIs("https")) {
              // Fail with an SSL error so that a fallback is triggered.
              network::URLLoaderCompletionStatus status;
              status.error_code = net::ERR_CERT_COMMON_NAME_INVALID;
              status.ssl_info = net::SSLInfo();
              status.ssl_info->cert_status =
                  net::CERT_STATUS_COMMON_NAME_INVALID;
              // The cert doesn't matter.
              status.ssl_info->cert = net::ImportCertFromFile(
                  net::GetTestCertsDirectory(), "ok_cert.pem");
              status.ssl_info->unverified_cert = status.ssl_info->cert;
              params->client->OnComplete(status);
              return true;
            }
            content::URLLoaderInterceptor::WriteResponse(
                "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                "<html>Done</html>", params->client.get());
            return true;
          }));
}

void HttpsUpgradesBrowserTest::EnableCaptivePortalDetection(
    BrowserWindowInterface* browser) {
  captive_portal::CaptivePortalService* captive_portal_service =
      CaptivePortalServiceFactory::GetForProfile(browser->GetProfile());
  captive_portal_service->set_test_url(GURL(kCaptivePortalPingUrl));

  captive_portal::CaptivePortalService::set_state_for_testing(
      captive_portal::CaptivePortalService::NOT_TESTING);
  browser->GetProfile()->GetPrefs()->SetBoolean(
      embedder_support::kAlternateErrorPagesEnabled, true);
}

// Checks that an automatically opened captive portal login page is not upgraded
// to HTTPS unless the interstitial is enabled. The captive portal's login
// page supports https.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    CaptivePortal_LoginPageWithValidSSL_ShouldNotUpgradeUnlessInterstitialEnabled) {
  if (IsIncognitoOrIsolatedBrowser()) {
    return;
  }
  auto interceptor =
      MakeCaptivePortalInterceptor(/*login_page_has_valid_https=*/true);

  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  EnableCaptivePortalDetection(browser());

  auto* tab_strip = GetBrowser()->GetTabStripModel();
  auto* contents = tab_strip->GetActiveWebContents();
  size_t tab_count = tab_strip->count();

  // Go to an HTTPS URL. The navigation will fail and trigger a captive portal
  // detection.
  ui_test_utils::TabAddedWaiter waiter(browser());
  NavigateAndWaitForFallback(contents,
                             GURL("https://ssl-error-for-captive-portal.com/"));
  waiter.Wait();

  // Captive portal login page should not be upgraded.
  content::WebContents* login_page = tab_strip->GetWebContentsAt(tab_count);
  content::WaitForLoadStop(login_page);
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(login_page));

  if (IsStrictInterstitialEnabledForTest()) {
    // If the interstitial is enabled, captive portal login page should also be
    // upgraded to HTTPS.
    EXPECT_EQ(GURL(kCaptivePortalPingUrlHttps),
              login_page->GetLastCommittedURL());

    // Should only attempt an upgrade for the original page.
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 3);
    // The original page serves bad HTTPS, but any HTTPS URL is counted as
    // secure in this histogram. Captive portal login page is valid HTTPS, so
    // it's also counted here.
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 2);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // Captive portal login page should not be upgraded to HTTPS.
    EXPECT_EQ(GURL(kCaptivePortalPingUrl), login_page->GetLastCommittedURL());

    // Should only attempt an upgrade for the original page.
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 2);
    // The original page serves bad HTTPS, but any HTTPS URL is counted as
    // secure in this histogram:
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 1);
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kCaptivePortalLogin, 1);
  }
}

// Same as
// CaptivePortal_LoginPageWithValidSSL_ShouldNotUpgradeUnlessInterstitialEnabled
// but the captive portal's login page serves bad SSL.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    CaptivePortal_LoginPageWithoutValidSSL_ShouldNotUpgradeUnlessInterstitialEnabled) {
  if (IsIncognitoOrIsolatedBrowser()) {
    return;
  }
  auto interceptor =
      MakeCaptivePortalInterceptor(/*login_page_has_valid_https=*/true);

  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  EnableCaptivePortalDetection(browser());

  auto* tab_strip = GetBrowser()->GetTabStripModel();
  auto* contents = tab_strip->GetActiveWebContents();
  size_t tab_count = tab_strip->count();

  // Go to an HTTPS URL. The navigation will fail and trigger a captive portal
  // detection.
  ui_test_utils::TabAddedWaiter waiter(browser());
  NavigateAndWaitForFallback(contents,
                             GURL("https://ssl-error-for-captive-portal.com/"));
  waiter.Wait();

  content::WebContents* login_page = tab_strip->GetWebContentsAt(tab_count);
  content::WaitForLoadStop(login_page);

  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(login_page));

  if (IsStrictInterstitialEnabledForTest()) {
    // If the interstitial is enabled, captive portal login page should also be
    // upgraded to HTTPS.
    EXPECT_EQ(GURL(kCaptivePortalPingUrlHttps),
              login_page->GetLastCommittedURL());

    // Should only attempt an upgrade for the original page.
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 3);
    // The original page serves bad HTTPS, but any HTTPS URL is counted as
    // secure in this histogram. Captive portal login page is valid HTTPS, so
    // it's also counted here.
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 2);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // Captive portal login page should not be upgraded to HTTPS.
    EXPECT_EQ(GURL(kCaptivePortalPingUrl), login_page->GetLastCommittedURL());

    // The original page serves bad HTTPS, but any HTTPS URL is counted as
    // secure in this histogram:
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 1);
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kCaptivePortalLogin, 1);
  }
}

// Tests that UKM fallback reasons are correctly recorded as kCertError when
// the upgrade fails due to a certificate error.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, UKM_CertError) {
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    ProceedThroughHttpsFirstModeInterstitial(contents);
    ExpectUKMEntryWithReason(http_url, BlockingResult::kInterstitialProceed,
                             FallbackReason::kCertError);
  }
}

// Tests that UKM fallback reasons are correctly recorded as kTimerFired when
// the upgrade times out.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, UKM_TimerFired) {
  HttpsUpgradesNavigationThrottle::set_timeout_for_testing(base::TimeDelta());
  net::EmbeddedTestServer timeout_server{net::EmbeddedTestServer::TYPE_HTTPS};
  timeout_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        return std::make_unique<net::test_server::HungResponse>();
      }));
  ASSERT_TRUE(timeout_server.Start());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(timeout_server.port());

  const GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    ProceedThroughHttpsFirstModeInterstitial(contents);
    ExpectUKMEntryWithReason(http_url, BlockingResult::kInterstitialProceed,
                             FallbackReason::kTimerFired);
  }
}

// Tests that UKM fallback reasons are correctly recorded as kRedirectLoop when
// the upgraded HTTPS site redirects back to HTTP.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, UKM_RedirectLoop) {
  net::EmbeddedTestServer downgrading_server{
      net::EmbeddedTestServer::TYPE_HTTPS};
  downgrading_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        GURL::Replacements http_downgrade;
        http_downgrade.SetSchemeStr(url::kHttpScheme);
        http_downgrade.SetHostStr("foo.com");
        auto redirect_url = request.GetURL().ReplaceComponents(http_downgrade);
        auto response = std::make_unique<net::test_server::BasicHttpResponse>();
        response->set_code(net::HTTP_TEMPORARY_REDIRECT);
        response->AddCustomHeader("Location", redirect_url.spec());
        return response;
      }));
  ASSERT_TRUE(downgrading_server.Start());
  HttpsUpgradesInterceptor::SetHttpPortForTesting(downgrading_server.port());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(downgrading_server.port());

  GURL url = downgrading_server.GetURL("foo.com", "/");
  auto* contents = GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
    ProceedThroughHttpsFirstModeInterstitial(contents);

    GURL::Replacements http_scheme;
    http_scheme.SetSchemeStr(url::kHttpScheme);
    GURL http_url = url.ReplaceComponents(http_scheme);

    ExpectUKMEntryWithReason(http_url, BlockingResult::kInterstitialProceed,
                             FallbackReason::kRedirectLoop);
  }
}

// A simple test fixture that constructs a HistogramTester (so that it gets
// initialized before browser startup). Used for testing pref tracking logic.
class HttpsUpgradesPrefsBrowserTest : public InProcessBrowserTest {
 public:
  HttpsUpgradesPrefsBrowserTest() {
    feature_list_.InitWithFeatures(
        /*enabled_features=*/{},
        /*disabled_features=*/{features::kHttpsFirstModeIncognito,
                               features::kHttpsFirstBalancedMode});
  }
  ~HttpsUpgradesPrefsBrowserTest() override = default;

 protected:
  void SetUISetting(HttpsFirstModeSetting setting) {
    extensions::settings_private::GeneratedPrefs prefs(browser()->GetProfile());
    prefs.SetPref(
        kGeneratedHttpsFirstModePref,
        std::make_unique<base::Value>(static_cast<int>(setting)).get());
  }

  bool GetPref() const {
    auto* prefs = browser()->GetProfile()->GetPrefs();
    return prefs->GetBoolean(prefs::kHttpsOnlyModeEnabled);
  }

  base::HistogramTester* histograms() { return &histograms_; }

 private:
  base::test::ScopedFeatureList feature_list_;
  base::HistogramTester histograms_;
};

// Tests that the HTTPS-First Mode state is recorded at startup and when
// changed. This test requires restarting the browser to test the "at startup"
// metric in order for the preference state to be set up before the
// HttpsFirstModeService is created.
IN_PROC_BROWSER_TEST_F(HttpsUpgradesPrefsBrowserTest, PRE_PrefStatesRecorded) {
  // The default pref state is `false`, which should get recorded when the
  // initial browser instance is started here.
  histograms()->ExpectUniqueSample(
      "Security.HttpsFirstMode.SettingEnabledAtStartup2",
      HttpsFirstModeSetting::kDisabled, 1);

  EXPECT_TRUE(variations::IsInSyntheticTrialGroup("HttpsFirstModeClientSetting",
                                                  "Disabled"));

  // Emulate changing the UI setting to Enabled. This should get recorded
  // in the histogram.
  SetUISetting(HttpsFirstModeSetting::kEnabledFull);
  histograms()->ExpectUniqueSample("Security.HttpsFirstMode.SettingChanged2",
                                   HttpsFirstModeSetting::kEnabledFull, 1);
  EXPECT_TRUE(variations::IsInSyntheticTrialGroup("HttpsFirstModeClientSetting",
                                                  "Enabled"));
}

IN_PROC_BROWSER_TEST_F(HttpsUpgradesPrefsBrowserTest, PrefStatesRecorded) {
  // Restarting the browser from the PRE_ test should record the startup setting
  // histogram. Checking the unique count also ensures that other profile
  // types (e.g. the ChromeOS sign-in profile) don't cause double-counting.
  EXPECT_TRUE(GetPref());
  histograms()->ExpectUniqueSample(
      "Security.HttpsFirstMode.SettingEnabledAtStartup2",
      HttpsFirstModeSetting::kEnabledFull, 1);
  EXPECT_TRUE(variations::IsInSyntheticTrialGroup("HttpsFirstModeClientSetting",
                                                  "Enabled"));

  // Open an Incognito window. Startup metrics should not get recorded.
  CreateIncognitoBrowser();
  histograms()->ExpectTotalCount(
      "Security.HttpsFirstMode.SettingEnabledAtStartup2", 1);
}

enum class BalancedModeParam {
  kNotAutoEnabled,
  kAutoEnabled,
};

// A simple test fixture that constructs a HistogramTester (so that it gets
// initialized before browser startup). Used for testing pref tracking logic.
// Variant of HttpsUpgradesPrefsBrowserTest but with the
// HttpsFirstBalancedMode feature enabled.
class HttpsUpgradesBalancedModePrefsBrowserTest
    : public testing::WithParamInterface<BalancedModeParam>,
      public InProcessBrowserTest {
 protected:
  void SetUp() override {
    // Feature flag must be enabled before SetUp() continues.
    switch (GetParam()) {
      case BalancedModeParam::kNotAutoEnabled:
        feature_list()->InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstBalancedMode},
            /*disabled_features=*/{
                features::kHttpsFirstBalancedModeAutoEnable});
        break;

      case BalancedModeParam::kAutoEnabled:
        feature_list()->InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstBalancedMode,
                                  features::kHttpsFirstBalancedModeAutoEnable},
            /*disabled_features=*/{});
        break;
    }
    InProcessBrowserTest::SetUp();
  }

  void SetUISetting(HttpsFirstModeSetting setting) {
    extensions::settings_private::GeneratedPrefs prefs(browser()->GetProfile());
    prefs.SetPref(
        kGeneratedHttpsFirstModePref,
        std::make_unique<base::Value>(static_cast<int>(setting)).get());
  }

  bool GetPref() const {
    auto* prefs = browser()->GetProfile()->GetPrefs();
    return prefs->GetBoolean(prefs::kHttpsFirstBalancedMode);
  }

  base::test::ScopedFeatureList* feature_list() { return &feature_list_; }
  base::HistogramTester* histograms() { return &histograms_; }

 private:
  base::test::ScopedFeatureList feature_list_;
  base::HistogramTester histograms_;
};

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    HttpsUpgradesBalancedModePrefsBrowserTest,
    ::testing::Values(BalancedModeParam::kNotAutoEnabled,
                      BalancedModeParam::kAutoEnabled),
    // Map param to a human-readable string for better test output.
    [](testing::TestParamInfo<BalancedModeParam> input_type) -> std::string {
      switch (input_type.param) {
        case BalancedModeParam::kNotAutoEnabled:
          return "BalancedModeNotAutoEnabled";
        case BalancedModeParam::kAutoEnabled:
          return "BalancedModeAutoEnabled";
      }
    });

// Tests that the HTTPS-First Mode setting is recorded at startup and when
// changed, when the HFM-Balanced-Mode feature flag is enabled. This test
// requires restarting the browser to test the "at startup" metric in order
// for the preference state to be set up before the HttpsFirstModeService is
// created.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBalancedModePrefsBrowserTest,
                       PRE_PrefStatesRecorded) {
  if (GetParam() == BalancedModeParam::kNotAutoEnabled) {
    // The default Balanced Mode pref state is false, which should get recorded
    // when the initial browser instance is started here.
    histograms()->ExpectUniqueSample(
        "Security.HttpsFirstMode.SettingEnabledAtStartup2",
        HttpsFirstModeSetting::kDisabled, 1);

    EXPECT_TRUE(variations::IsInSyntheticTrialGroup(
        "HttpsFirstModeClientSetting", "Disabled"));
  } else if (GetParam() == BalancedModeParam::kAutoEnabled) {
    // The default Balanced Mode pref state is false, but Balanced Mode is auto
    // enabled.
    histograms()->ExpectUniqueSample(
        "Security.HttpsFirstMode.SettingEnabledAtStartup2",
        HttpsFirstModeSetting::kEnabledBalanced, 1);

    EXPECT_TRUE(variations::IsInSyntheticTrialGroup(
        "HttpsFirstModeClientSetting", "Balanced"));
  }

  // Emulate changing the UI setting to Balanced Mode. This should get recorded
  // in the histogram.
  SetUISetting(HttpsFirstModeSetting::kEnabledBalanced);
  EXPECT_TRUE(GetPref());
  histograms()->ExpectUniqueSample("Security.HttpsFirstMode.SettingChanged2",
                                   HttpsFirstModeSetting::kEnabledBalanced, 1);
  EXPECT_TRUE(variations::IsInSyntheticTrialGroup("HttpsFirstModeClientSetting",
                                                  "Balanced"));
}

IN_PROC_BROWSER_TEST_P(HttpsUpgradesBalancedModePrefsBrowserTest,
                       PrefStatesRecorded) {
  // Restarting the browser from the PRE_ test should record the startup setting
  // histogram. Checking the unique count also ensures that other profile
  // types (e.g. the ChromeOS sign-in profile) don't cause double-counting.
  EXPECT_TRUE(GetPref());
  histograms()->ExpectUniqueSample(
      "Security.HttpsFirstMode.SettingEnabledAtStartup2",
      HttpsFirstModeSetting::kEnabledBalanced, 1);
  EXPECT_TRUE(variations::IsInSyntheticTrialGroup("HttpsFirstModeClientSetting",
                                                  "Balanced"));

  // Open an Incognito window. Startup metrics should not get recorded.
  CreateIncognitoBrowser();
  histograms()->ExpectTotalCount(
      "Security.HttpsFirstMode.SettingEnabledAtStartup2", 1);
}

using TypicallySecureUserBrowserTest = InProcessBrowserTest;

IN_PROC_BROWSER_TEST_F(TypicallySecureUserBrowserTest,
                       PRE_RestoreCountsOnStartup_OneNavigation) {
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(browser()->GetProfile());
  hfm_service->IncrementRecentNavigationCount();
}

IN_PROC_BROWSER_TEST_F(TypicallySecureUserBrowserTest,
                       RestoreCountsOnStartup_OneNavigation) {
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(browser()->GetProfile());
  // A single navigation will not be persisted to the pref and won't be
  // restored on startup because navigations are persisted in batches of 10.
  EXPECT_EQ(0u, hfm_service->GetRecentNavigationCount());
}

IN_PROC_BROWSER_TEST_F(TypicallySecureUserBrowserTest,
                       PRE_RestoreCountsOnStartup_TenNavigations) {
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(browser()->GetProfile());
  // Increment repeatedly to force the counts to be persisted to the pref.
  for (size_t i = 0; i < 10; i++) {
    hfm_service->IncrementRecentNavigationCount();
  }
}

IN_PROC_BROWSER_TEST_F(TypicallySecureUserBrowserTest,
                       RestoreCountsOnStartup_TenNavigations) {
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(browser()->GetProfile());
  EXPECT_EQ(10u, hfm_service->GetRecentNavigationCount());
}

// Tests for HFM heuristics without Balanced Mode enabled. These are unusual
// configurations and shouldn't appear in production.
// TODO(crbug.com/349860796): Remove after balanced mode is fully launched.
using HttpsUpgradesHeuristicsWithoutBalancedModeBrowserTest =
    HttpsUpgradesBrowserTest;

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    HttpsUpgradesHeuristicsWithoutBalancedModeBrowserTest,
    ::testing::Values(
        HttpsUpgradesTestType::
            kHttpsFirstModeWithSiteEngagementWithoutBalancedMode));

// Test that Site Engagement Heuristic without Balanced Mode is a no-op.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesHeuristicsWithoutBalancedModeBrowserTest,
    UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristicWithoutBalancedMode_ShouldIgnore) {
  ASSERT_FALSE(IsIncognitoOrIsolatedBrowser() || IsHttpsFirstModePrefEnabled());

  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  content::WebContents* contents =
      GetBrowser()->GetTabStripModel()->GetActiveWebContents();
  Profile* profile = GetBrowser()->GetProfile();
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Set test clock.
  auto clock = std::make_unique<base::SimpleTestClock>();
  auto* clock_ptr = clock.get();
  StatefulSSLHostStateDelegate* chrome_state =
      static_cast<StatefulSSLHostStateDelegate*>(state);
  chrome_state->SetClockForTesting(std::move(clock));

  // Start the clock at standard system time.
  clock_ptr->SetNow(base::Time::NowFromSystemTime());

  // Set site engagement scores so that this site would have HFM enabled if
  // HFM+SE kicked in.
  GURL http_url("http://example.com");
  GURL https_url("https://example.com");

  SetSiteEngagementScore(http_url, kLowSiteEngagementScore);
  SetSiteEngagementScore(https_url, kHighSiteEnagementScore);
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  MaybeEnableHttpsFirstModeForEngagedSitesAndWait(hfm_service);

  // This URL should be upgraded by HTTPS-Upgrades and should fall back to HTTP,
  // but not have HFM auto-enabled on it because balanced mode isn't enabled.
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  EXPECT_EQ(HFMInterstitialType::kNone, GetHFMInterstitialType(contents));

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  // Engagement heuristic shouldn't handle any navigation events.
  histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);

  // Security level histogram should not record kHttpsEnforcedOnHostname.
  histograms()->ExpectBucketCount(
      kNavigationRequestSecurityLevelHistogram,
      NavigationRequestSecurityLevel::kHttpsEnforcedOnHostname, 0);
}

// Minimal test fixture for testing the interaction between the
// SecureOriginAllowlist (set via the command-line switch
// `switches::kUnsafelyTreatInsecureOriginAsSecure`) and HTTPS-First Balanced
// Mode.
class HttpsUpgradesSecureOriginAllowlistBrowserTest
    : public InProcessBrowserTest {
 public:
  HttpsUpgradesSecureOriginAllowlistBrowserTest() {
    feature_list_.InitWithFeatures(
        {features::kHttpsFirstBalancedModeAutoEnable},
        // TODO(crbug.com/351990829): Update these tests to work with the new
        // native dialog UI, and then re-enable this feature.
        {security_interstitials::features::kHttpsFirstDialogUi});
  }
  ~HttpsUpgradesSecureOriginAllowlistBrowserTest() override = default;

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    embedded_test_server()->AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(embedded_test_server()->Start());
    HttpsUpgradesInterceptor::SetHttpPortForTesting(
        embedded_test_server()->port());
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    // This sets a wildcard entry in the allowlist, because we can't specify
    // an exact origin as we don't yet have the embedded test server's port
    // (it isn't started until later).
    command_line->AppendSwitchASCII(
        network::switches::kUnsafelyTreatInsecureOriginAsSecure,
        "*.example.com");
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

IN_PROC_BROWSER_TEST_F(HttpsUpgradesSecureOriginAllowlistBrowserTest,
                       HostInAllowlistExemptedFromHttpsFirstMode) {
  GURL url_in_allowlist =
      embedded_test_server()->GetURL("test.example.com", "/simple.html");
  content::WebContents* contents =
      browser()->GetTabStripModel()->GetActiveWebContents();
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, url_in_allowlist));
  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
}

IN_PROC_BROWSER_TEST_F(HttpsUpgradesSecureOriginAllowlistBrowserTest,
                       HostNotInAllowlistShowWarning) {
  GURL url_not_in_allowlist =
      embedded_test_server()->GetURL("not-example.com", "/simple.html");
  content::WebContents* contents =
      browser()->GetTabStripModel()->GetActiveWebContents();
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, url_not_in_allowlist));
  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
}

// A separate test fixture for Advanced Protection to ensure that HFM triggers
// properly, even if balanced mode is enabled by default.
class HttpsUpgradesAdvancedProtectionBrowserTest : public InProcessBrowserTest {
 public:
  HttpsUpgradesAdvancedProtectionBrowserTest() {
    feature_list_.InitWithFeatures(
        /*enabled_features=*/{features::
                                  kHttpsFirstModeForAdvancedProtectionUsers,
                              features::kHttpsFirstBalancedModeAutoEnable},
        /*disabled_features=*/{
            security_interstitials::features::kHttpsFirstDialogUi});
  }
  ~HttpsUpgradesAdvancedProtectionBrowserTest() override = default;

  void SetUp() override {
    ChromeSecurityBlockingPageFactory::SetEnterpriseManagedForTesting(false);
    InProcessBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    // Enable Advanced Protection for the profile via the testing API
    safe_browsing::AdvancedProtectionStatusManagerFactory::GetForProfile(
        browser()->GetProfile())
        ->SetAdvancedProtectionStatusForTesting(true);

    host_resolver()->AddRule("*", "127.0.0.1");
    http_server_.AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(http_server_.Start());
  }

  net::EmbeddedTestServer* http_server() { return &http_server_; }

 private:
  base::test::ScopedFeatureList feature_list_;
  net::EmbeddedTestServer http_server_{net::EmbeddedTestServer::TYPE_HTTP};
};

// Verifies that Advanced Protection users get HFM warnings for non-default
// ports and it does not get incorrectly bypassed by the Balanced Mode
// exclusion. Regression test for crbug.com/501741117.
IN_PROC_BROWSER_TEST_F(HttpsUpgradesAdvancedProtectionBrowserTest,
                       UrlWithNonDefaultPort_ShouldUpgradeAndShowInterstitial) {
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  EXPECT_NE(http_url.IntPort(), 80);  // Ensure it's not the default port

  auto* contents = browser()->GetTabStripModel()->GetActiveWebContents();

  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));
  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
}

// Test fixture for testing Ask-Before-HTTP fallback delay via FeatureParams.
// Initializes ScopedFeatureList in the constructor before browser startup.
class HttpsUpgradesAskBeforeHttpDelayTest : public InProcessBrowserTest {
 public:
  HttpsUpgradesAskBeforeHttpDelayTest() {
    feature_list_.InitAndEnableFeatureWithParameters(
        features::kHttpsUpgrades, {{"ask-before-http-fallback-delay", "0ms"},
                                   {"fallback-delay", "100s"}});
  }
  ~HttpsUpgradesAskBeforeHttpDelayTest() override = default;

  void SetUpOnMainThread() override {
    // By default allow all hosts on HTTPS.
    mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
    host_resolver()->AddRule("*", "127.0.0.1");

    // bad-https.com will fail HTTPS and fallback to HTTP.
    scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate());
    net::CertVerifyResult verify_result;
    verify_result.is_issued_by_known_root = false;
    verify_result.verified_cert = cert;
    verify_result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "bad-https.com", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);

    http_server_.AddDefaultHandlers(GetChromeTestDataDir());
    https_server_.AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(http_server_.Start());
    ASSERT_TRUE(https_server_.Start());

    HttpsUpgradesInterceptor::SetHttpsPortForTesting(https_server_.port());
    HttpsUpgradesInterceptor::SetHttpPortForTesting(http_server_.port());

    // Enable HFM pref.
    auto* prefs = browser()->GetProfile()->GetPrefs();
    prefs->SetBoolean(prefs::kHttpsOnlyModeEnabled, true);
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    mock_cert_verifier_.SetUpCommandLine(command_line);
  }

  void SetUpInProcessBrowserTestFixture() override {
    mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
  }

  void TearDownInProcessBrowserTestFixture() override {
    mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
  }

  net::EmbeddedTestServer* http_server() { return &http_server_; }
  net::EmbeddedTestServer* https_server() { return &https_server_; }

 private:
  base::test::ScopedFeatureList feature_list_;
  net::EmbeddedTestServer http_server_{net::EmbeddedTestServer::TYPE_HTTP};
  net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
  content::ContentMockCertVerifier mock_cert_verifier_;
};

IN_PROC_BROWSER_TEST_F(HttpsUpgradesAskBeforeHttpDelayTest,
                       FallbackDelayFeatureParam_AskBeforeHttp) {
  // Set up a custom HTTPS server that times out without sending a response.
  net::EmbeddedTestServer timeout_server{net::EmbeddedTestServer::TYPE_HTTPS};
  timeout_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        return std::make_unique<net::test_server::HungResponse>();
      }));
  ASSERT_TRUE(timeout_server.Start());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(timeout_server.port());

  const GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  auto* contents = browser()->GetTabStripModel()->GetActiveWebContents();

  // Navigate to HTTP. It should upgrade to HTTPS and immediately fallback to
  // HTTP and show the interstitial because ask-before-http-fallback-delay is
  // 0ms.
  EXPECT_FALSE(NavigateToURLWithLinkTransition(contents, http_url));

  EXPECT_TRUE(IsShowingHttpsFirstModeInterstitial(contents));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
}

// Test fixture for testing Silent Fallback delay via FeatureParams.
// Initializes ScopedFeatureList in the constructor before browser startup.
// This is the same as HttpsUpgradesAskBeforeHttpDelayTest but with the
// FeatureParams swapped and the HFM pref disabled so this runs with silent
// HTTPS-Upgrades only.
class HttpsUpgradesSilentFallbackDelayTest : public InProcessBrowserTest {
 public:
  HttpsUpgradesSilentFallbackDelayTest() {
    feature_list_.InitAndEnableFeatureWithParameters(
        features::kHttpsUpgrades, {{"fallback-delay", "0ms"},
                                   {"ask-before-http-fallback-delay", "100s"}});
  }
  ~HttpsUpgradesSilentFallbackDelayTest() override = default;

  void SetUpOnMainThread() override {
    // By default allow all hosts on HTTPS.
    mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
    host_resolver()->AddRule("*", "127.0.0.1");

    // bad-https.com will fail HTTPS and fallback to HTTP.
    scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate());
    net::CertVerifyResult verify_result;
    verify_result.is_issued_by_known_root = false;
    verify_result.verified_cert = cert;
    verify_result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "bad-https.com", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);

    http_server_.AddDefaultHandlers(GetChromeTestDataDir());
    https_server_.AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(http_server_.Start());
    ASSERT_TRUE(https_server_.Start());

    HttpsUpgradesInterceptor::SetHttpsPortForTesting(https_server_.port());
    HttpsUpgradesInterceptor::SetHttpPortForTesting(http_server_.port());

    // Disable HFM pref.
    auto* prefs = browser()->GetProfile()->GetPrefs();
    prefs->SetBoolean(prefs::kHttpsOnlyModeEnabled, false);
    prefs->SetBoolean(prefs::kHttpsFirstBalancedMode, false);
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    mock_cert_verifier_.SetUpCommandLine(command_line);
  }

  void SetUpInProcessBrowserTestFixture() override {
    mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
  }

  void TearDownInProcessBrowserTestFixture() override {
    mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
  }

  net::EmbeddedTestServer* http_server() { return &http_server_; }
  net::EmbeddedTestServer* https_server() { return &https_server_; }

 private:
  base::test::ScopedFeatureList feature_list_;
  net::EmbeddedTestServer http_server_{net::EmbeddedTestServer::TYPE_HTTP};
  net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
  content::ContentMockCertVerifier mock_cert_verifier_;
};

IN_PROC_BROWSER_TEST_F(HttpsUpgradesSilentFallbackDelayTest,
                       FallbackDelayFeatureParam_SilentFallback) {
  // Set up a custom HTTPS server that times out without sending a response.
  net::EmbeddedTestServer timeout_server{net::EmbeddedTestServer::TYPE_HTTPS};
  timeout_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        return std::make_unique<net::test_server::HungResponse>();
      }));
  ASSERT_TRUE(timeout_server.Start());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(timeout_server.port());

  const GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  auto* contents = browser()->GetTabStripModel()->GetActiveWebContents();

  // Navigate to HTTP. It should upgrade to HTTPS and immediately fallback to
  // HTTP because fallback-delay is 0ms.
  EXPECT_TRUE(NavigateToURLWithLinkTransition(contents, http_url));

  EXPECT_FALSE(IsShowingHttpsFirstModeInterstitial(contents));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
}

// Fixture for testing interactions between HTTPS-Upgrades and Safe Browsing.
class HttpsUpgradesSafeBrowsingTest : public InProcessBrowserTest {
 public:
  HttpsUpgradesSafeBrowsingTest() {
    feature_list_.InitWithFeatures(
        /*enabled_features=*/{features::kHttpsUpgrades,
                              security_interstitials::features::
                                  kHttpsFirstDialogUi},
        /*disabled_features=*/{});
  }

  void CreatedBrowserMainParts(
      content::BrowserMainParts* browser_main_parts) override {
    InProcessBrowserTest::CreatedBrowserMainParts(browser_main_parts);
    sb_factory_ =
        std::make_unique<safe_browsing::TestSafeBrowsingServiceFactory>();
    fake_db_manager_ =
        base::MakeRefCounted<safe_browsing::FakeSafeBrowsingDatabaseManager>(
            content::GetUIThreadTaskRunner({}));
    sb_factory_->SetTestDatabaseManager(fake_db_manager_.get());
    sb_factory_->SetTestUIManager(
        new safe_browsing::TestSafeBrowsingUIManager());
    safe_browsing::SafeBrowsingService::RegisterFactory(sb_factory_.get());
  }

  void TearDown() override {
    InProcessBrowserTest::TearDown();
    safe_browsing::SafeBrowsingService::RegisterFactory(nullptr);
  }

  void SetUpOnMainThread() override {
    mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
    host_resolver()->AddRule("*", "127.0.0.1");

    http_server_.AddDefaultHandlers(GetChromeTestDataDir());
    https_server_.AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(http_server_.Start());
    ASSERT_TRUE(https_server_.Start());

    HttpsUpgradesInterceptor::SetHttpsPortForTesting(https_server_.port());
    HttpsUpgradesInterceptor::SetHttpPortForTesting(http_server_.port());

    // Enable the HFM pref.
    browser()->GetProfile()->GetPrefs()->SetBoolean(
        prefs::kHttpsOnlyModeEnabled, true);
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    mock_cert_verifier_.SetUpCommandLine(command_line);
  }

  void SetUpInProcessBrowserTestFixture() override {
    mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
  }

  void TearDownInProcessBrowserTestFixture() override {
    mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
  }

 protected:
  base::test::ScopedFeatureList feature_list_;
  std::unique_ptr<safe_browsing::TestSafeBrowsingServiceFactory> sb_factory_;
  scoped_refptr<safe_browsing::FakeSafeBrowsingDatabaseManager>
      fake_db_manager_;
  net::EmbeddedTestServer http_server_{net::EmbeddedTestServer::TYPE_HTTP};
  net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
  content::ContentMockCertVerifier mock_cert_verifier_;
};

// Tests that if a navigation gets upgraded and the resulting URL is blocked by
// Safe Browsing, we don't trigger fallback to HTTP and instead show the Safe
// Browsing interstitial. Regression test for crbug.com/443741921.
// TODO(crbug.com/553440870): Re-enable this test.
IN_PROC_BROWSER_TEST_F(HttpsUpgradesSafeBrowsingTest,
                       DISABLED_SafeBrowsingBlock_ShouldNotTriggerHFM) {
  GURL http_url = http_server_.GetURL("malicious.com", "/simple.html");
  GURL https_url = https_server_.GetURL("malicious.com", "/simple.html");

  // Mark the HTTPS URL as dangerous (malware).
  fake_db_manager_->AddDangerousUrl(
      https_url, safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_MALWARE);

  auto* contents = browser()->GetTabStripModel()->GetActiveWebContents();
  content::TestNavigationObserver nav_observer(contents, 1);

  // Navigate to the HTTP URL.
  EXPECT_FALSE(content::NavigateToURL(contents, http_url));
  nav_observer.Wait();

  // The navigation should have failed because of the SB block.
  EXPECT_FALSE(nav_observer.last_navigation_succeeded());

  // We should be showing an interstitial (the Safe Browsing one).
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingInterstitial(contents));

  // Verify that we are NOT showing the HTTPS-First Mode interstitial.
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          contents));

  // Verify that the browser stayed on the HTTPS URL and did not fallback to
  // HTTP.
  EXPECT_EQ(https_url, contents->GetVisibleURL());
}
