// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_clock.h"
#include "chrome/browser/engagement/site_engagement_score.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/history/history_test_utils.h"
#include "chrome/browser/lookalikes/lookalike_url_interstitial_page.h"
#include "chrome/browser/lookalikes/lookalike_url_navigation_throttle.h"
#include "chrome/browser/lookalikes/lookalike_url_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/security_interstitials/content/security_interstitial_page.h"
#include "components/security_interstitials/content/security_interstitial_tab_helper.h"
#include "components/security_interstitials/core/metrics_helper.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_navigation_observer.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "ui/base/window_open_disposition.h"

namespace {

using lookalikes::LookalikeUrlNavigationThrottle;
using lookalikes::LookalikeUrlService;
using security_interstitials::MetricsHelper;
using security_interstitials::SecurityInterstitialCommand;
using UkmEntry = ukm::builders::LookalikeUrl_NavigationSuggestion;
using NavigationSuggestionEvent =
    lookalikes::LookalikeUrlNavigationThrottle::NavigationSuggestionEvent;

using MatchType = LookalikeUrlInterstitialPage::MatchType;
using UserAction = LookalikeUrlInterstitialPage::UserAction;

enum class UIStatus {
  kDisabled,
  kEnabledForSiteEngagement,
  kEnabledForSiteEngagementAndTopDomains
};

// An engagement score above MEDIUM.
const int kHighEngagement = 20;

// An engagement score below MEDIUM.
const int kLowEngagement = 1;

// The UMA metric names registered by metrics_helper.
const char kInterstitialDecisionMetric[] = "interstitial.lookalike.decision";
const char kInterstitialInteractionMetric[] =
    "interstitial.lookalike.interaction";

static std::unique_ptr<net::test_server::HttpResponse>
NetworkErrorResponseHandler(const net::test_server::HttpRequest& request) {
  return std::unique_ptr<net::test_server::HttpResponse>(
      new net::test_server::RawHttpResponse("", ""));
}

security_interstitials::SecurityInterstitialPage* GetCurrentInterstitial(
    content::WebContents* web_contents) {
  security_interstitials::SecurityInterstitialTabHelper* helper =
      security_interstitials::SecurityInterstitialTabHelper::FromWebContents(
          web_contents);
  if (!helper) {
    return nullptr;
  }
  return helper->GetBlockingPageForCurrentlyCommittedNavigationForTesting();
}

security_interstitials::SecurityInterstitialPage::TypeID GetInterstitialType(
    content::WebContents* web_contents) {
  security_interstitials::SecurityInterstitialPage* page =
      GetCurrentInterstitial(web_contents);
  if (!page) {
    return nullptr;
  }
  return page->GetTypeForTesting();
}

// Sets the absolute Site Engagement |score| for the testing origin.
void SetEngagementScore(Browser* browser, const GURL& url, double score) {
  SiteEngagementService::Get(browser->profile())
      ->ResetBaseScoreForURL(url, score);
}

bool IsUrlShowing(Browser* browser) {
  return !browser->location_bar_model()->GetFormattedFullURL().empty();
}

// Simulates a link click navigation. We don't use
// ui_test_utils::NavigateToURL(const GURL&) because it simulates the user
// typing the URL, causing the site to have a site engagement score of at
// least LOW.
void NavigateToURL(Browser* browser, const GURL& url) {
  NavigateParams params(browser, url, ui::PAGE_TRANSITION_LINK);
  params.initiator_origin = url::Origin::Create(GURL("about:blank"));
  params.disposition = WindowOpenDisposition::CURRENT_TAB;
  params.is_renderer_initiated = true;
  ui_test_utils::NavigateToURL(&params);
}

// Same as NavigateToUrl, but wait for the load to complete before returning.
void NavigateToURLSync(Browser* browser, const GURL& url) {
  content::TestNavigationObserver navigation_observer(
      browser->tab_strip_model()->GetActiveWebContents(), 1);
  NavigateToURL(browser, url);
  navigation_observer.Wait();
}

// Load given URL and verify that it loaded an interstitial and hid the URL.
void LoadAndCheckInterstitialAt(Browser* browser, const GURL& url) {
  content::WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();

  EXPECT_EQ(nullptr, GetCurrentInterstitial(web_contents));

  NavigateToURLSync(browser, url);
  EXPECT_EQ(LookalikeUrlInterstitialPage::kTypeForTesting,
            GetInterstitialType(web_contents));
  EXPECT_FALSE(IsUrlShowing(browser));
}

void SendInterstitialCommand(content::WebContents* web_contents,
                             SecurityInterstitialCommand command) {
  GetCurrentInterstitial(web_contents)
      ->CommandReceived(base::NumberToString(command));
}

void SendInterstitialCommandSync(Browser* browser,
                                 SecurityInterstitialCommand command) {
  content::WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();

  EXPECT_EQ(LookalikeUrlInterstitialPage::kTypeForTesting,
            GetInterstitialType(web_contents));

  content::TestNavigationObserver navigation_observer(web_contents, 1);
  SendInterstitialCommand(web_contents, command);
  navigation_observer.Wait();

  EXPECT_EQ(nullptr, GetCurrentInterstitial(web_contents));
  EXPECT_TRUE(IsUrlShowing(browser));
}

// Verify that no interstitial is shown, regardless of feature state.
void TestInterstitialNotShown(Browser* browser, const GURL& navigated_url) {
  content::WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();

  NavigateToURLSync(browser, navigated_url);
  EXPECT_EQ(nullptr, GetCurrentInterstitial(web_contents));

  // Navigate to an empty page. This will happen after any
  // LookalikeUrlService tasks, so will effectively wait for those tasks to
  // finish.
  NavigateToURLSync(browser, GURL("about:blank"));
  EXPECT_EQ(nullptr, GetCurrentInterstitial(web_contents));
}

}  // namespace

class LookalikeUrlNavigationThrottleBrowserTest
    : public InProcessBrowserTest,
      public testing::WithParamInterface<UIStatus> {
 protected:
  void SetUp() override {
    switch (ui_status()) {
      case UIStatus::kDisabled:
        feature_list_.InitAndDisableFeature(
            features::kLookalikeUrlNavigationSuggestionsUI);
        break;

      case UIStatus::kEnabledForSiteEngagement:
        feature_list_.InitAndEnableFeature(
            features::kLookalikeUrlNavigationSuggestionsUI);
        break;

      case UIStatus::kEnabledForSiteEngagementAndTopDomains:
        feature_list_.InitAndEnableFeatureWithParameters(
            features::kLookalikeUrlNavigationSuggestionsUI,
            {{"topsites", "true"}});
    }
    InProcessBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    ASSERT_TRUE(embedded_test_server()->Start());
    test_ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();

    const base::Time kNow = base::Time::FromDoubleT(1000);
    test_clock_.SetNow(kNow);

    LookalikeUrlService* lookalike_service =
        LookalikeUrlService::Get(browser()->profile());
    lookalike_service->SetClockForTesting(&test_clock_);
  }

  GURL GetURL(const char* hostname) const {
    return embedded_test_server()->GetURL(hostname, "/title1.html");
  }

  GURL GetURLWithoutPath(const char* hostname) const {
    return GetURL(hostname).GetWithEmptyPath();
  }

  GURL GetLongRedirect(const char* via_hostname1,
                       const char* via_hostname2,
                       const char* dest_hostname) const {
    GURL dest = GetURL(dest_hostname);
    GURL mid = embedded_test_server()->GetURL(
        via_hostname2, "/server-redirect?" + dest.spec());
    return embedded_test_server()->GetURL(via_hostname1,
                                          "/server-redirect?" + mid.spec());
  }

  // Checks that UKM recorded an event for each URL in |navigated_urls| with the
  // given metric value.
  template <typename T>
  void CheckUkm(const std::vector<GURL>& navigated_urls,
                const std::string& metric_name,
                T metric_value) {
    auto entries = test_ukm_recorder()->GetEntriesByName(UkmEntry::kEntryName);
    ASSERT_EQ(navigated_urls.size(), entries.size());
    int entry_count = 0;
    for (const auto* const entry : entries) {
      test_ukm_recorder()->ExpectEntrySourceHasUrl(entry,
                                                   navigated_urls[entry_count]);
      test_ukm_recorder()->ExpectEntryMetric(entry, metric_name,
                                             static_cast<int>(metric_value));
      entry_count++;
    }
  }

  // Checks that UKM did not record any lookalike URL metrics.
  void CheckNoUkm() {
    EXPECT_TRUE(
        test_ukm_recorder()->GetEntriesByName(UkmEntry::kEntryName).empty());
  }

  // Returns true if the current test parameter should result in showing an
  // interstitial for |expected_event|.
  bool ShouldExpectInterstitial(
      LookalikeUrlNavigationThrottle::NavigationSuggestionEvent expected_event)
      const {
    if (!ui_enabled()) {
      return false;
    }
    if (expected_event == NavigationSuggestionEvent::kMatchSiteEngagement) {
      return true;
    }
    if (expected_event == NavigationSuggestionEvent::kMatchTopSite &&
        ui_status() == UIStatus::kEnabledForSiteEngagementAndTopDomains) {
      return true;
    }
    return false;
  }

  // Tests that the histogram event |expected_event| is recorded. If the UI is
  // enabled, additional events for interstitial display and link click will
  // also be tested.
  void TestMetricsRecordedAndMaybeInterstitialShown(
      Browser* browser,
      const GURL& navigated_url,
      const GURL& expected_suggested_url,
      LookalikeUrlNavigationThrottle::NavigationSuggestionEvent
          expected_event) {
    base::HistogramTester histograms;
    if (!ShouldExpectInterstitial(expected_event)) {
      TestInterstitialNotShown(browser, navigated_url);
      histograms.ExpectTotalCount(
          LookalikeUrlNavigationThrottle::kHistogramName, 1);
      histograms.ExpectBucketCount(
          LookalikeUrlNavigationThrottle::kHistogramName, expected_event, 1);

      return;
    }

    history::HistoryService* const history_service =
        HistoryServiceFactory::GetForProfile(
            browser->profile(), ServiceAccessType::EXPLICIT_ACCESS);
    ui_test_utils::WaitForHistoryToLoad(history_service);

    LoadAndCheckInterstitialAt(browser, navigated_url);
    SendInterstitialCommandSync(browser,
                                SecurityInterstitialCommand::CMD_DONT_PROCEED);
    EXPECT_EQ(expected_suggested_url,
              browser->tab_strip_model()->GetActiveWebContents()->GetURL());

    // Clicking the link in the interstitial should also remove the original
    // URL from history.
    ui_test_utils::HistoryEnumerator enumerator(browser->profile());
    EXPECT_FALSE(base::ContainsValue(enumerator.urls(), navigated_url));

    histograms.ExpectTotalCount(LookalikeUrlNavigationThrottle::kHistogramName,
                                1);
    histograms.ExpectBucketCount(LookalikeUrlNavigationThrottle::kHistogramName,
                                 expected_event, 1);

    histograms.ExpectTotalCount(kInterstitialDecisionMetric, 2);
    histograms.ExpectBucketCount(kInterstitialDecisionMetric,
                                 MetricsHelper::SHOW, 1);
    histograms.ExpectBucketCount(kInterstitialDecisionMetric,
                                 MetricsHelper::DONT_PROCEED, 1);

    histograms.ExpectTotalCount(kInterstitialInteractionMetric, 1);
    histograms.ExpectBucketCount(kInterstitialInteractionMetric,
                                 MetricsHelper::TOTAL_VISITS, 1);
  }

  // Tests that the histogram event |expected_event| is recorded. If the UI is
  // enabled, additional events for interstitial display and dismissal will also
  // be tested.
  void TestHistogramEventsRecordedWhenInterstitialIgnored(
      Browser* browser,
      base::HistogramTester* histograms,
      const GURL& navigated_url,
      LookalikeUrlNavigationThrottle::NavigationSuggestionEvent
          expected_event) {
    if (!ui_enabled()) {
      TestInterstitialNotShown(browser, navigated_url);
      histograms->ExpectTotalCount(
          LookalikeUrlNavigationThrottle::kHistogramName, 1);
      histograms->ExpectBucketCount(
          LookalikeUrlNavigationThrottle::kHistogramName, expected_event, 1);

      return;
    }

    history::HistoryService* const history_service =
        HistoryServiceFactory::GetForProfile(
            browser->profile(), ServiceAccessType::EXPLICIT_ACCESS);
    ui_test_utils::WaitForHistoryToLoad(history_service);

    LoadAndCheckInterstitialAt(browser, navigated_url);

    // Clicking the ignore button in the interstitial should remove the
    // interstitial and navigate to the original URL.
    SendInterstitialCommandSync(browser,
                                SecurityInterstitialCommand::CMD_PROCEED);
    EXPECT_EQ(navigated_url,
              browser->tab_strip_model()->GetActiveWebContents()->GetURL());

    // Clicking the link should cause the original URL to appear in history.
    ui_test_utils::HistoryEnumerator enumerator(browser->profile());
    EXPECT_TRUE(base::ContainsValue(enumerator.urls(), navigated_url));

    histograms->ExpectTotalCount(LookalikeUrlNavigationThrottle::kHistogramName,
                                 1);
    histograms->ExpectBucketCount(
        LookalikeUrlNavigationThrottle::kHistogramName, expected_event, 1);

    histograms->ExpectTotalCount(kInterstitialDecisionMetric, 2);
    histograms->ExpectBucketCount(kInterstitialDecisionMetric,
                                  MetricsHelper::SHOW, 1);
    histograms->ExpectBucketCount(kInterstitialDecisionMetric,
                                  MetricsHelper::PROCEED, 1);

    histograms->ExpectTotalCount(kInterstitialInteractionMetric, 1);
    histograms->ExpectBucketCount(kInterstitialInteractionMetric,
                                  MetricsHelper::TOTAL_VISITS, 1);

    TestInterstitialNotShown(browser, navigated_url);
  }

  ukm::TestUkmRecorder* test_ukm_recorder() { return test_ukm_recorder_.get(); }

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

  virtual bool ui_enabled() const { return GetParam() != UIStatus::kDisabled; }
  virtual UIStatus ui_status() const { return GetParam(); }

 private:
  base::test::ScopedFeatureList feature_list_;
  std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;
  base::SimpleTestClock test_clock_;
};

class LookalikeUrlInterstitialPageBrowserTest
    : public LookalikeUrlNavigationThrottleBrowserTest {
 protected:
  bool ui_enabled() const override { return true; }
  UIStatus ui_status() const override {
    return UIStatus::kEnabledForSiteEngagementAndTopDomains;
  }
};

INSTANTIATE_TEST_SUITE_P(
    ,
    LookalikeUrlNavigationThrottleBrowserTest,
    ::testing::Values(UIStatus::kDisabled,
                      UIStatus::kEnabledForSiteEngagement,
                      UIStatus::kEnabledForSiteEngagementAndTopDomains));

// Navigating to a non-IDN shouldn't show an interstitial or record metrics.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       NonIdn_NoMatch) {
  TestInterstitialNotShown(browser(), GetURL("google.com"));
  CheckNoUkm();
}

// Navigating to a domain whose visual representation does not look like a
// top domain shouldn't show an interstitial or record metrics.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       NonTopDomainIdn_NoInterstitial) {
  TestInterstitialNotShown(browser(), GetURL("éxample.com"));
  CheckNoUkm();
}

// If the user has engaged with the domain before, metrics shouldn't be recorded
// and the interstitial shouldn't be shown, even if the domain is visually
// similar to a top domain.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       Idn_TopDomain_EngagedSite_NoMatch) {
  const GURL url = GetURL("googlé.com");
  SetEngagementScore(browser(), url, kHighEngagement);
  TestInterstitialNotShown(browser(), url);
  CheckNoUkm();
}

// Navigate to a domain whose visual representation looks like a top domain.
// This should record metrics. It should also show a lookalike warning
// interstitial if configured via a feature param.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       Idn_TopDomain_Match) {
  const GURL kNavigatedUrl = GetURL("googlé.com");
  const GURL kExpectedSuggestedUrl = GetURLWithoutPath("google.com");
  // Even if the navigated site has a low engagement score, it should be
  // considered for lookalike suggestions.
  SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);

  TestMetricsRecordedAndMaybeInterstitialShown(
      browser(), kNavigatedUrl, kExpectedSuggestedUrl,
      NavigationSuggestionEvent::kMatchTopSite);

  CheckUkm({kNavigatedUrl}, "MatchType", MatchType::kTopSite);
}

// Same as Idn_TopDomain_Match, but this time the domain contains characters
// from different scripts, failing the checks in IDN spoof checker before
// reaching the top domain check. In this case, the end result is the same, but
// the reason we fall back to punycode is different.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       Idn_TopDomainMixedScript_Match) {
  const GURL kNavigatedUrl = GetURL("аррӏе.com");
  const GURL kExpectedSuggestedUrl = GetURLWithoutPath("apple.com");
  // Even if the navigated site has a low engagement score, it should be
  // considered for lookalike suggestions.
  SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);

  TestMetricsRecordedAndMaybeInterstitialShown(
      browser(), kNavigatedUrl, kExpectedSuggestedUrl,
      NavigationSuggestionEvent::kMatchTopSite);

  CheckUkm({kNavigatedUrl}, "MatchType", MatchType::kTopSite);
}

// The navigated domain will fall back to punycode because it fails spoof checks
// in IDN spoof checker, but there won't be an interstitial because the domain
// doesn't match a top domain.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       Punycode_NoMatch) {
  TestInterstitialNotShown(browser(), GetURL("ɴoτ-τoρ-ďoᛖaiɴ.com"));
  CheckNoUkm();
}

// The navigated domain itself is a top domain or a subdomain of a top domain.
// Should not record metrics. The top domain list doesn't contain any IDN, so
// this only tests the case where the subdomains are IDNs.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       TopDomainIdnSubdomain_NoMatch) {
  TestInterstitialNotShown(browser(), GetURL("tést.google.com"));
  CheckNoUkm();

  // blogspot.com is a private registry, so the eTLD+1 of "tést.blogspot.com" is
  // itself, instead of just "blogspot.com". This is different than
  // tést.google.com whose eTLD+1 is google.com, and it should be handled
  // correctly.
  TestInterstitialNotShown(browser(), GetURL("tést.blogspot.com"));
  CheckNoUkm();
}

// Schemes other than HTTP and HTTPS should be ignored.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       TopDomainChromeUrl_NoMatch) {
  TestInterstitialNotShown(browser(), GURL("chrome://googlé.com"));
  CheckNoUkm();
}

// Navigate to a domain within an edit distance of 1 to an engaged domain.
// This should record metrics, but should not show a lookalike warning
// interstitial yet.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       EditDistance_EngagedDomain_Match) {
  base::HistogramTester histograms;
  SetEngagementScore(browser(), GURL("https://test-site.com"), kHighEngagement);

  // The skeleton of this domain is one 1 edit away from the skeleton of
  // test-site.com.
  const GURL kNavigatedUrl = GetURL("best-sité.com");
  // Even if the navigated site has a low engagement score, it should be
  // considered for lookalike suggestions.
  SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);
  // Advance clock to force a fetch of new engaged sites list.
  test_clock()->Advance(base::TimeDelta::FromHours(1));

  TestInterstitialNotShown(browser(), kNavigatedUrl);
  histograms.ExpectTotalCount(LookalikeUrlNavigationThrottle::kHistogramName,
                              1);
  histograms.ExpectBucketCount(
      LookalikeUrlNavigationThrottle::kHistogramName,
      NavigationSuggestionEvent::kMatchEditDistanceSiteEngagement, 1);

  CheckUkm({kNavigatedUrl}, "MatchType",
           MatchType::kEditDistanceSiteEngagement);
}

// Navigate to a domain within an edit distance of 1 to a top domain.
// This should record metrics, but should not show a lookalike warning
// interstitial yet.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       EditDistance_TopDomain_Match) {
  base::HistogramTester histograms;

  // The skeleton of this domain, gooogle.corn, is one 1 edit away from
  // google.corn, the skeleton of google.com.
  const GURL kNavigatedUrl = GetURL("goooglé.com");
  // Even if the navigated site has a low engagement score, it should be
  // considered for lookalike suggestions.
  SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);

  TestInterstitialNotShown(browser(), kNavigatedUrl);
  histograms.ExpectTotalCount(LookalikeUrlNavigationThrottle::kHistogramName,
                              1);
  histograms.ExpectBucketCount(LookalikeUrlNavigationThrottle::kHistogramName,
                               NavigationSuggestionEvent::kMatchEditDistance,
                               1);

  CheckUkm({kNavigatedUrl}, "MatchType", MatchType::kEditDistance);
}

// Tests negative examples for the edit distance.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       EditDistance_TopDomain_NoMatch) {
  // Matches google.com.tr but only differs in registry.
  TestInterstitialNotShown(browser(), GetURL("google.com.tw"));
  CheckNoUkm();

  // Matches bing.com but is a top domain itself.
  TestInterstitialNotShown(browser(), GetURL("ning.com"));
  CheckNoUkm();

  // Matches ask.com but is too short.
  TestInterstitialNotShown(browser(), GetURL("bsk.com"));
  CheckNoUkm();
}

// Tests negative examples for the edit distance with engaged sites.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       EditDistance_SiteEngagement_NoMatch) {
  SetEngagementScore(browser(), GURL("https://test-site.com.tr"),
                     kHighEngagement);
  SetEngagementScore(browser(), GURL("https://1234.com"), kHighEngagement);
  SetEngagementScore(browser(), GURL("https://gooogle.com"), kHighEngagement);
  // Advance clock to force a fetch of new engaged sites list.
  test_clock()->Advance(base::TimeDelta::FromHours(1));

  // Matches test-site.com.tr but only differs in registry.
  TestInterstitialNotShown(browser(), GetURL("test-site.com.tw"));
  CheckNoUkm();

  // Matches gooogle.com but is a top domain itself.
  TestInterstitialNotShown(browser(), GetURL("google.com"));
  CheckNoUkm();

  // Matches 1234.com but is too short.
  TestInterstitialNotShown(browser(), GetURL("123.com"));
  CheckNoUkm();
}

// Test that the heuristics are triggered even with net errors.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       NetError_SiteEngagement_Interstitial) {
  // Create a test server that returns invalid responses.
  net::EmbeddedTestServer custom_test_server;
  custom_test_server.RegisterRequestHandler(
      base::BindRepeating(&NetworkErrorResponseHandler));
  ASSERT_TRUE(custom_test_server.Start());

  SetEngagementScore(browser(), GURL("http://site1.com"), kHighEngagement);
  // Advance clock to force a fetch of new engaged sites list.
  test_clock()->Advance(base::TimeDelta::FromHours(1));

  TestMetricsRecordedAndMaybeInterstitialShown(
      browser(), custom_test_server.GetURL("sité1.com", "/title1.html"),
      custom_test_server.GetURL("site1.com", "/"),
      NavigationSuggestionEvent::kMatchSiteEngagement);
}

// Same as NetError_SiteEngagement_Interstitial, but triggered by a top domain.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       NetError_TopDomain_Interstitial) {
  // Create a test server that returns invalid responses.
  net::EmbeddedTestServer custom_test_server;
  custom_test_server.RegisterRequestHandler(
      base::BindRepeating(&NetworkErrorResponseHandler));
  ASSERT_TRUE(custom_test_server.Start());

  TestMetricsRecordedAndMaybeInterstitialShown(
      browser(), GetURL("googlé.com"), GetURLWithoutPath("google.com"),
      NavigationSuggestionEvent::kMatchTopSite);
}

// Verify that, after dismissing a lookalike warning when enabled, the user
// sees a net error when applicable.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       NetError_SiteEngagement_NetErrorAfterDismiss) {
  // Create a test server that returns invalid responses.
  net::EmbeddedTestServer custom_test_server;
  custom_test_server.RegisterRequestHandler(
      base::BindRepeating(&NetworkErrorResponseHandler));
  ASSERT_TRUE(custom_test_server.Start());

  SetEngagementScore(browser(), GURL("http://site1.com"), kHighEngagement);
  // Advance clock to force a fetch of new engaged sites list.
  test_clock()->Advance(base::TimeDelta::FromHours(1));
  NavigateToURLSync(browser(),
                    custom_test_server.GetURL("sité1.com", "/title1.html"));
  if (ui_enabled()) {
    SendInterstitialCommandSync(browser(),
                                SecurityInterstitialCommand::CMD_PROCEED);
  }

  EXPECT_GE(ui_test_utils::FindInPage(
                browser()->tab_strip_model()->GetActiveWebContents(),
                base::ASCIIToUTF16("ERR_EMPTY_RESPONSE"), true, true, nullptr,
                nullptr),
            1);
}

// Same as NetError_SiteEngagement_NetErrorAfterDismiss, but navigates to a top
// domain instead.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       NetError_TopDomain_NetErrorAfterDismiss) {
  // Create a test server that returns invalid responses.
  net::EmbeddedTestServer custom_test_server;
  custom_test_server.RegisterRequestHandler(
      base::BindRepeating(&NetworkErrorResponseHandler));
  ASSERT_TRUE(custom_test_server.Start());

  NavigateToURLSync(browser(),
                    custom_test_server.GetURL("googlé.com", "/title1.html"));
  if (ShouldExpectInterstitial(NavigationSuggestionEvent::kMatchTopSite)) {
    SendInterstitialCommandSync(browser(),
                                SecurityInterstitialCommand::CMD_PROCEED);
  }

  EXPECT_GE(ui_test_utils::FindInPage(
                browser()->tab_strip_model()->GetActiveWebContents(),
                base::ASCIIToUTF16("ERR_EMPTY_RESPONSE"), true, true, nullptr,
                nullptr),
            1);
}

// Navigate to a domain whose visual representation looks like a domain with a
// site engagement score above a certain threshold. This should record metrics.
// It should also show lookalike warning interstitial if configured via
// a feature param.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       Idn_SiteEngagement_Match) {
  const char* const kEngagedSites[] = {
      "http://site1.com", "http://www.site2.com", "http://sité3.com",
      "http://www.sité4.com"};

  for (const char* const kSite : kEngagedSites) {
    SetEngagementScore(browser(), GURL(kSite), kHighEngagement);
  }

  // The domains here should not be private domains (e.g. site.test), otherwise
  // they might test the wrong thing. Also note that site5.com is in the top
  // domain list, so it shouldn't be used here.
  const struct SiteEngagementTestCase {
    const char* const navigated;
    const char* const suggested;
  } kSiteEngagementTestCases[] = {
      {"sité1.com", "site1.com"},
      {"mail.www.sité1.com", "site1.com"},
      // Same as above two but ending with dots.
      {"sité1.com.", "site1.com"},
      {"mail.www.sité1.com.", "site1.com"},

      // These should match since the comparison uses eTLD+1s.
      {"sité2.com", "site2.com"},
      {"mail.sité2.com", "site2.com"},

      {"síté3.com", "sité3.com"},
      {"mail.síté3.com", "sité3.com"},

      {"síté4.com", "sité4.com"},
      {"mail.síté4.com", "sité4.com"},
  };

  std::vector<GURL> ukm_urls;
  for (const auto& test_case : kSiteEngagementTestCases) {
    const GURL kNavigatedUrl = GetURL(test_case.navigated);
    const GURL kExpectedSuggestedUrl = GetURLWithoutPath(test_case.suggested);

    // Even if the navigated site has a low engagement score, it should be
    // considered for lookalike suggestions.
    SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);
    // Advance the clock to force LookalikeUrlService to fetch a new engaged
    // site list.
    test_clock()->Advance(base::TimeDelta::FromHours(1));

    TestMetricsRecordedAndMaybeInterstitialShown(
        browser(), kNavigatedUrl, kExpectedSuggestedUrl,
        NavigationSuggestionEvent::kMatchSiteEngagement);

    ukm_urls.push_back(kNavigatedUrl);
    CheckUkm(ukm_urls, "MatchType", MatchType::kSiteEngagement);
  }
}

// Tests negative examples for all heuristics.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       NonUniqueDomains_NoMatch) {
  // Unknown registry.
  TestInterstitialNotShown(browser(), GetURL("google.cóm"));
  CheckNoUkm();

  // Engaged site is localhost, navigated site has unknown registry. This
  // is intended to test that nonunique domains in the engaged site list is
  // filtered out. However, it doesn't quite test that: We'll bail out early
  // because the navigated site has unknown registry (and not because there is
  // no engaged nonunique site).
  SetEngagementScore(browser(), GURL("http://localhost6.localhost"),
                     kHighEngagement);
  test_clock()->Advance(base::TimeDelta::FromHours(1));
  // The skeleton of this URL is localhost6.localpost which is at one edit
  // distance from localhost6.localhost. We use localpost here to prevent an
  // early return in LookalikeUrlNavigationThrottle::HandleThrottleRequest().
  TestInterstitialNotShown(browser(), GURL("http://localhóst6.localpost"));
  CheckNoUkm();
}

// Navigate to a domain whose visual representation looks both like a domain
// with a site engagement score and also a top domain. This should record
// metrics for a site engagement match because of the order of checks. It should
// also show lookalike warning interstitial if configured via a feature param.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       Idn_SiteEngagementAndTopDomain_Match) {
  const GURL kNavigatedUrl = GetURL("googlé.com");
  const GURL kExpectedSuggestedUrl = GetURLWithoutPath("google.com");
  SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);
  SetEngagementScore(browser(), kExpectedSuggestedUrl, kHighEngagement);

  // Advance the clock to force LookalikeUrlService to fetch a new engaged
  // site list.
  test_clock()->Advance(base::TimeDelta::FromHours(1));

  TestMetricsRecordedAndMaybeInterstitialShown(
      browser(), kNavigatedUrl, kExpectedSuggestedUrl,
      NavigationSuggestionEvent::kMatchSiteEngagement);

  CheckUkm({kNavigatedUrl}, "MatchType", MatchType::kSiteEngagement);
}

// Similar to Idn_SiteEngagement_Match, but tests a single domain. Also checks
// that the list of engaged sites in incognito and the main profile don't affect
// each other.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       Idn_SiteEngagement_Match_Incognito) {
  const GURL kNavigatedUrl = GetURL("sité1.com");
  const GURL kEngagedUrl = GetURLWithoutPath("site1.com");

  // Set high engagement scores in the main profile and low engagement scores
  // in incognito. Main profile should record metrics, incognito shouldn't.
  Browser* incognito = CreateIncognitoBrowser();
  LookalikeUrlService::Get(incognito->profile())
      ->SetClockForTesting(test_clock());
  SetEngagementScore(browser(), kEngagedUrl, kHighEngagement);
  SetEngagementScore(incognito, kEngagedUrl, kLowEngagement);

  std::vector<GURL> ukm_urls;
  // Main profile should record metrics because there are engaged sites.
  {
    // Advance the clock to force LookalikeUrlService to fetch a new engaged
    // site list.
    test_clock()->Advance(base::TimeDelta::FromHours(1));
    TestMetricsRecordedAndMaybeInterstitialShown(
        browser(), kNavigatedUrl, kEngagedUrl,
        NavigationSuggestionEvent::kMatchSiteEngagement);

    ukm_urls.push_back(kNavigatedUrl);
    CheckUkm(ukm_urls, "MatchType", MatchType::kSiteEngagement);
  }

  // Incognito shouldn't record metrics because there are no engaged sites.
  {
    base::HistogramTester histograms;
    test_clock()->Advance(base::TimeDelta::FromHours(1));
    TestInterstitialNotShown(incognito, kNavigatedUrl);
    histograms.ExpectTotalCount(LookalikeUrlNavigationThrottle::kHistogramName,
                                0);
  }

  // Now reverse the scores: Set low engagement in the main profile and high
  // engagement in incognito.
  SetEngagementScore(browser(), kEngagedUrl, kLowEngagement);
  SetEngagementScore(incognito, kEngagedUrl, kHighEngagement);

  // Incognito should start recording metrics and main profile should stop.
  {
    test_clock()->Advance(base::TimeDelta::FromHours(1));

    TestMetricsRecordedAndMaybeInterstitialShown(
        incognito, kNavigatedUrl, kEngagedUrl,
        NavigationSuggestionEvent::kMatchSiteEngagement);
    ukm_urls.push_back(kNavigatedUrl);
    CheckUkm(ukm_urls, "MatchType", MatchType::kSiteEngagement);
  }

  // Main profile shouldn't record metrics because there are no engaged sites.
  {
    base::HistogramTester histograms;
    test_clock()->Advance(base::TimeDelta::FromHours(1));
    TestInterstitialNotShown(browser(), kNavigatedUrl);
    histograms.ExpectTotalCount(LookalikeUrlNavigationThrottle::kHistogramName,
                                0);
  }
}

// Test that navigations to a site with a high engagement score shouldn't
// record metrics or show interstitial.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       Idn_SiteEngagement_Match_IgnoreHighlyEngagedSite) {
  base::HistogramTester histograms;
  SetEngagementScore(browser(), GURL("http://site-not-in-top-domain-list.com"),
                     kHighEngagement);
  const GURL high_engagement_url = GetURL("síte-not-ín-top-domaín-líst.com");
  SetEngagementScore(browser(), high_engagement_url, kHighEngagement);
  TestInterstitialNotShown(browser(), high_engagement_url);
  histograms.ExpectTotalCount(LookalikeUrlNavigationThrottle::kHistogramName,
                              0);
}

// Test that an engaged site with a scheme other than HTTP or HTTPS should be
// ignored.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       Idn_SiteEngagement_IgnoreChromeUrl) {
  base::HistogramTester histograms;
  SetEngagementScore(browser(),
                     GURL("chrome://site-not-in-top-domain-list.com"),
                     kHighEngagement);
  const GURL low_engagement_url("http://síte-not-ín-top-domaín-líst.com");
  SetEngagementScore(browser(), low_engagement_url, kLowEngagement);
  TestInterstitialNotShown(browser(), low_engagement_url);
  histograms.ExpectTotalCount(LookalikeUrlNavigationThrottle::kHistogramName,
                              0);
}

// IDNs with a single label should be properly handled. There are two cases
// where this might occur:
// 1. The navigated URL is an IDN with a single label.
// 2. One of the engaged sites is an IDN with a single label.
// Neither of these should cause a crash.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       IdnWithSingleLabelShouldNotCauseACrash) {
  base::HistogramTester histograms;

  // Case 1: Navigating to an IDN with a single label shouldn't cause a crash.
  TestInterstitialNotShown(browser(), GetURL("é"));

  // Case 2: An IDN with a single label with a site engagement score shouldn't
  // cause a crash.
  SetEngagementScore(browser(), GURL("http://tést"), kHighEngagement);
  TestInterstitialNotShown(browser(), GetURL("tést.com"));

  histograms.ExpectTotalCount(LookalikeUrlNavigationThrottle::kHistogramName,
                              0);
  CheckNoUkm();
}

// Ensure that dismissing the interstitial works, and the result is remembered
// in the current tab.  This should record metrics on the first visit, but not
// the second.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       Interstitial_Dismiss) {
  base::HistogramTester histograms;

  const GURL kNavigatedUrl = GetURL("sité1.com");
  const GURL kEngagedUrl = GetURL("site1.com");
  SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);
  SetEngagementScore(browser(), kEngagedUrl, kHighEngagement);

  TestHistogramEventsRecordedWhenInterstitialIgnored(
      browser(), &histograms, kNavigatedUrl,
      NavigationSuggestionEvent::kMatchSiteEngagement);

  CheckUkm({kNavigatedUrl}, "MatchType", MatchType::kSiteEngagement);
}

// Navigate to lookalike domains that redirect to benign domains and ensure that
// we display an interstitial along the way.
IN_PROC_BROWSER_TEST_F(LookalikeUrlInterstitialPageBrowserTest,
                       Interstitial_CapturesRedirects) {
  {
    // Verify it works when the lookalike domain is the first in the chain
    const GURL kNavigatedUrl =
        GetLongRedirect("googlé.com", "example.net", "example.com");
    SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);
    LoadAndCheckInterstitialAt(browser(), kNavigatedUrl);
  }

  // LoadAndCheckInterstitialAt assumes there's not an interstitial already
  // showing (since otherwise it can't be sure that the navigation caused it).
  NavigateToURLSync(browser(), GetURL("example.com"));

  {
    // ...or when it's later in the chain
    const GURL kNavigatedUrl =
        GetLongRedirect("example.net", "googlé.com", "example.com");
    SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);
    LoadAndCheckInterstitialAt(browser(), kNavigatedUrl);
  }

  NavigateToURLSync(browser(), GetURL("example.com"));

  {
    // ...or when it's last in the chain
    const GURL kNavigatedUrl =
        GetLongRedirect("example.net", "example.com", "googlé.com");
    SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);
    LoadAndCheckInterstitialAt(browser(), kNavigatedUrl);
  }
}

// Verify that the user action in UKM is recorded properly when the interstitial
// is not shown.
IN_PROC_BROWSER_TEST_P(LookalikeUrlNavigationThrottleBrowserTest,
                       UkmRecordedWhenNoInterstitialShown) {
  // UI tests are handled explicitly below.
  if (ui_enabled())
    return;

  const GURL navigated_url = GetURL("googlé.com");
  TestInterstitialNotShown(browser(), navigated_url);
  CheckUkm({navigated_url}, "UserAction", UserAction::kInterstitialNotShown);
}

// Verify that the user action in UKM is recorded even when we navigate away
// from the interstitial without interacting with it.
IN_PROC_BROWSER_TEST_F(LookalikeUrlInterstitialPageBrowserTest,
                       UkmRecordedAfterNavigateAway) {
  const GURL navigated_url = GetURL("googlé.com");
  const GURL subsequent_url = GetURL("example.com");

  LoadAndCheckInterstitialAt(browser(), navigated_url);
  NavigateToURLSync(browser(), subsequent_url);
  CheckUkm({navigated_url}, "UserAction", UserAction::kCloseOrBack);
}

// Verify that the user action in UKM is recorded properly when the user accepts
// the navigation suggestion.
IN_PROC_BROWSER_TEST_F(LookalikeUrlInterstitialPageBrowserTest,
                       UkmRecordedAfterSuggestionAccepted) {
  const GURL navigated_url = GetURL("googlé.com");

  LoadAndCheckInterstitialAt(browser(), navigated_url);
  SendInterstitialCommandSync(browser(),
                              SecurityInterstitialCommand::CMD_DONT_PROCEED);
  CheckUkm({navigated_url}, "UserAction", UserAction::kAcceptSuggestion);
}

// Verify that the user action in UKM is recorded properly when the user ignores
// the navigation suggestion.
IN_PROC_BROWSER_TEST_F(LookalikeUrlInterstitialPageBrowserTest,
                       UkmRecordedAfterSuggestionIgnored) {
  const GURL navigated_url = GetURL("googlé.com");

  LoadAndCheckInterstitialAt(browser(), navigated_url);
  SendInterstitialCommandSync(browser(),
                              SecurityInterstitialCommand::CMD_PROCEED);
  CheckUkm({navigated_url}, "UserAction", UserAction::kClickThrough);
}

// Verify that the URL shows normally on pages after a lookalike interstitial.
IN_PROC_BROWSER_TEST_F(LookalikeUrlInterstitialPageBrowserTest,
                       UrlShownAfterInterstitial) {
  LoadAndCheckInterstitialAt(browser(), GetURL("googlé.com"));

  // URL should be showing again when we navigate to a normal URL
  NavigateToURLSync(browser(), GetURL("example.com"));
  EXPECT_TRUE(IsUrlShowing(browser()));
}

// Verify that bypassing warnings in the main profile does not affect incognito.
IN_PROC_BROWSER_TEST_F(LookalikeUrlInterstitialPageBrowserTest,
                       MainProfileDoesNotAffectIncognito) {
  const GURL kNavigatedUrl = GetURL("googlé.com");

  // Set low engagement scores in the main profile and in incognito.
  Browser* incognito = CreateIncognitoBrowser();
  SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);
  SetEngagementScore(incognito, kNavigatedUrl, kLowEngagement);

  LoadAndCheckInterstitialAt(browser(), kNavigatedUrl);
  // PROCEEDing will disable the interstitial on subsequent navigations
  SendInterstitialCommandSync(browser(),
                              SecurityInterstitialCommand::CMD_PROCEED);

  LoadAndCheckInterstitialAt(incognito, kNavigatedUrl);
}

// Verify that bypassing warnings in incognito does not affect the main profile.
IN_PROC_BROWSER_TEST_F(LookalikeUrlInterstitialPageBrowserTest,
                       IncognitoDoesNotAffectMainProfile) {
  const GURL kNavigatedUrl = GetURL("sité1.com");
  const GURL kEngagedUrl = GetURL("site1.com");

  // Set engagement scores in the main profile and in incognito.
  Browser* incognito = CreateIncognitoBrowser();
  SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);
  SetEngagementScore(incognito, kNavigatedUrl, kLowEngagement);
  SetEngagementScore(browser(), kEngagedUrl, kHighEngagement);
  SetEngagementScore(incognito, kEngagedUrl, kHighEngagement);

  LoadAndCheckInterstitialAt(incognito, kNavigatedUrl);
  // PROCEEDing will disable the interstitial on subsequent navigations
  SendInterstitialCommandSync(incognito,
                              SecurityInterstitialCommand::CMD_PROCEED);

  LoadAndCheckInterstitialAt(browser(), kNavigatedUrl);
}

// Verify reloading the page does not result in dismissing an interstitial.
// Regression test for crbug/941886.
IN_PROC_BROWSER_TEST_F(LookalikeUrlInterstitialPageBrowserTest,
                       RefreshDoesntDismiss) {
  // Verify it works when the lookalike domain is the first in the chain
  const GURL kNavigatedUrl =
      GetLongRedirect("googlé.com", "example.net", "example.com");

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement);
  LoadAndCheckInterstitialAt(browser(), kNavigatedUrl);

  content::TestNavigationObserver navigation_observer(web_contents);
  chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
  navigation_observer.Wait();

  EXPECT_EQ(LookalikeUrlInterstitialPage::kTypeForTesting,
            GetInterstitialType(web_contents));
  EXPECT_FALSE(IsUrlShowing(browser()));
}
