// Copyright 2016 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 "chrome/browser/engagement/important_sites_util.h"

#include <memory>
#include <utility>

#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sample_vector.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.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/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/test/bookmark_test_helpers.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/history/core/browser/history_database_params.h"
#include "components/history/core/browser/history_service.h"
#include "components/history/core/test/test_history_database.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/web_contents.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
using BookmarkModel = bookmarks::BookmarkModel;
using ImportantDomainInfo = ImportantSitesUtil::ImportantDomainInfo;

const size_t kNumImportantSites = 5;
base::FilePath g_temp_history_dir;

std::unique_ptr<KeyedService> BuildTestHistoryService(
    content::BrowserContext* context) {
  std::unique_ptr<history::HistoryService> service(
      new history::HistoryService());
  service->Init(history::TestHistoryDatabaseParamsForPath(g_temp_history_dir));
  return std::move(service);
}

// We only need to reproduce the values that we are testing. The values here
// need to match the values in important_sites_util.
enum ImportantReasonForTesting {
  ENGAGEMENT = 0,
  BOOKMARKS = 2,
  NOTIFICATIONS = 4
};

// We only need to reproduce the values that we are testing. The values here
// need to match the values in important_sites_util.
enum CrossedReasonForTesting {
  CROSSED_NOTIFICATIONS_AND_ENGAGEMENT = 3,
  CROSSED_REASON_UNKNOWN = 7,
};

}  // namespace

class ImportantSitesUtilTest : public ChromeRenderViewHostTestHarness {
 public:
  void SetUp() override {
    ChromeRenderViewHostTestHarness::SetUp();
    SiteEngagementScore::SetParamValuesForTesting();
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    g_temp_history_dir = temp_dir_.GetPath();
    HistoryServiceFactory::GetInstance()->SetTestingFactory(
        profile(), &BuildTestHistoryService);
  }

  void AddContentSetting(ContentSettingsType type,
                         ContentSetting setting,
                         const GURL& origin) {
    HostContentSettingsMapFactory::GetForProfile(profile())
        ->SetContentSettingCustomScope(
            ContentSettingsPattern::FromURLNoWildcard(origin),
            ContentSettingsPattern::Wildcard(), type,
            content_settings::ResourceIdentifier(), setting);
    EXPECT_EQ(setting,
              HostContentSettingsMapFactory::GetForProfile(profile())
                  ->GetContentSetting(origin, GURL(), type,
                                      content_settings::ResourceIdentifier()));
  }

  void AddBookmark(const GURL& origin) {
    if (!model_) {
      profile()->CreateBookmarkModel(true);
      model_ = BookmarkModelFactory::GetForBrowserContext(profile());
      bookmarks::test::WaitForBookmarkModelToLoad(model_);
    }

    model_->AddURL(model_->bookmark_bar_node(), 0,
                   base::ASCIIToUTF16(origin.spec()), origin);
  }

  void ExpectImportantResultsEq(
      const std::vector<std::string>& domains,
      const std::vector<GURL>& expected_sorted_origins,
      const std::vector<ImportantDomainInfo>& important_sites) {
    ASSERT_EQ(domains.size(), important_sites.size());
    ASSERT_EQ(expected_sorted_origins.size(), important_sites.size());
    for (size_t i = 0; i < important_sites.size(); i++) {
      EXPECT_EQ(domains[i], important_sites[i].registerable_domain);
      EXPECT_EQ(expected_sorted_origins[i], important_sites[i].example_origin);
    }
  }

  void ExpectImportantResultsEqualUnordered(
      const std::vector<std::string>& domains,
      const std::vector<GURL>& expected_sorted_origins,
      const std::vector<ImportantDomainInfo>& important_sites) {
    ASSERT_EQ(domains.size(), important_sites.size());
    ASSERT_EQ(expected_sorted_origins.size(), important_sites.size());

    std::vector<std::string> actual_domains;
    std::vector<GURL> actual_origins;
    for (size_t i = 0; i < important_sites.size(); i++) {
      actual_domains.push_back(important_sites[i].registerable_domain);
      actual_origins.push_back(important_sites[i].example_origin);
    }
    EXPECT_THAT(actual_domains, testing::UnorderedElementsAreArray(domains));
    EXPECT_THAT(actual_origins,
                testing::UnorderedElementsAreArray(expected_sorted_origins));
  }

 private:
  base::ScopedTempDir temp_dir_;
  BookmarkModel* model_ = nullptr;
};

TEST_F(ImportantSitesUtilTest, TestNoImportantSites) {
  EXPECT_TRUE(ImportantSitesUtil::GetImportantRegisterableDomains(
                  profile(), kNumImportantSites)
                  .empty());
}

TEST_F(ImportantSitesUtilTest, SourceOrdering) {
  SiteEngagementService* service = SiteEngagementService::Get(profile());
  ASSERT_TRUE(service);

  GURL url1("http://www.google.com/");
  GURL url2("https://www.google.com/");
  GURL url3("https://drive.google.com/");
  GURL url4("https://www.chrome.com/");
  GURL url5("https://www.example.com/");
  GURL url6("https://youtube.com/");
  GURL url7("https://foo.bar/");

  service->ResetBaseScoreForURL(url1, 5);
  service->ResetBaseScoreForURL(url2, 2);  // Below medium engagement (5).
  service->ResetBaseScoreForURL(url3, 7);
  service->ResetBaseScoreForURL(url4, 8);
  service->ResetBaseScoreForURL(url5, 9);
  service->ResetBaseScoreForURL(url6, 1);  // Below the medium engagement (5).
  service->ResetBaseScoreForURL(url7, 11);

  // Here we should have:
  // 1: removed domains below minimum engagement,
  // 2: combined the google.com entries, and
  // 3: sorted by the score.
  std::vector<ImportantDomainInfo> important_sites =
      ImportantSitesUtil::GetImportantRegisterableDomains(profile(),
                                                          kNumImportantSites);
  std::vector<std::string> expected_sorted_domains = {
      "foo.bar", "example.com", "chrome.com", "google.com"};
  std::vector<GURL> expected_sorted_origins = {url7, url5, url4, url3};
  ExpectImportantResultsEq(expected_sorted_domains, expected_sorted_origins,
                           important_sites);

  // Test that notifications get moved to the front.
  AddContentSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_ALLOW,
                    url6);
  // BLOCK'ed sites don't count. We want to make sure we only bump sites that
  // were granted the permsion.
  AddContentSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_BLOCK,
                    url1);

  // Same as above, but the site with notifications should be at the front.
  important_sites = ImportantSitesUtil::GetImportantRegisterableDomains(
      profile(), kNumImportantSites);
  expected_sorted_domains = {"youtube.com", "foo.bar", "example.com",
                             "chrome.com", "google.com"};
  expected_sorted_origins = {url6, url7, url5, url4, url3};
  ExpectImportantResultsEq(expected_sorted_domains, expected_sorted_origins,
                           important_sites);

  // Test that bookmarks move above engagements and below notifications.
  AddBookmark(url1);
  important_sites = ImportantSitesUtil::GetImportantRegisterableDomains(
      profile(), kNumImportantSites);
  expected_sorted_domains = {"youtube.com", "google.com", "foo.bar",
                             "example.com", "chrome.com"};
  expected_sorted_origins = {url6, url3, url7, url5, url4};
  ExpectImportantResultsEq(expected_sorted_domains, expected_sorted_origins,
                           important_sites);
}

TEST_F(ImportantSitesUtilTest, TooManyBookmarks) {
  SiteEngagementService* service = SiteEngagementService::Get(profile());
  ASSERT_TRUE(service);

  GURL url1("http://www.google.com/");
  GURL url2("https://www.google.com/");
  GURL url3("https://drive.google.com/");
  GURL url4("https://www.chrome.com/");
  GURL url5("https://www.example.com/");
  GURL url6("https://youtube.com/");
  GURL url7("https://foo.bar/");

  // Add some as bookmarks.
  AddBookmark(url1);
  AddBookmark(url2);
  AddBookmark(url3);
  AddBookmark(url4);
  AddBookmark(url5);

  // We have just below our limit, so all sites are important (the first three
  // origins collapse, so we end up with 3).
  std::vector<ImportantDomainInfo> important_sites =
      ImportantSitesUtil::GetImportantRegisterableDomains(profile(),
                                                          kNumImportantSites);
  EXPECT_EQ(3u, important_sites.size());

  // Add the rest, which should put us over the limit.
  AddBookmark(url6);
  AddBookmark(url7);
  // Too many bookmarks! Nothing shows up now.
  important_sites = ImportantSitesUtil::GetImportantRegisterableDomains(
      profile(), kNumImportantSites);
  EXPECT_EQ(0u, important_sites.size());

  // If we add some site engagement, they should show up (even though the site
  // engagement score is too low for a signal by itself).
  service->ResetBaseScoreForURL(url1, 2);
  service->ResetBaseScoreForURL(url4, 3);
  service->ResetBaseScoreForURL(url7, 0);

  important_sites = ImportantSitesUtil::GetImportantRegisterableDomains(
      profile(), kNumImportantSites);
  ASSERT_EQ(2u, important_sites.size());
  std::vector<std::string> expected_sorted_domains = {"google.com",
                                                      "chrome.com"};
  std::vector<GURL> expected_sorted_origins = {url1, url4};
  ExpectImportantResultsEqualUnordered(
      expected_sorted_domains, expected_sorted_origins, important_sites);
}

TEST_F(ImportantSitesUtilTest, Blacklisting) {
  SiteEngagementService* service = SiteEngagementService::Get(profile());
  ASSERT_TRUE(service);

  GURL url1("http://www.google.com/");
  GURL url2("http://www.gmail.com/");

  // Set a bunch of positive signals.
  service->ResetBaseScoreForURL(url1, 5);
  AddBookmark(url2);
  AddContentSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_ALLOW,
                    url1);

  // Important fetch 1.
  std::vector<ImportantDomainInfo> important_sites =
      ImportantSitesUtil::GetImportantRegisterableDomains(profile(),
                                                          kNumImportantSites);
  std::vector<std::string> expected_sorted_domains = {"google.com",
                                                      "gmail.com"};
  std::vector<GURL> expected_sorted_origins = {url1, url2};
  ExpectImportantResultsEq(expected_sorted_domains, expected_sorted_origins,
                           important_sites);
  ASSERT_EQ(2u, important_sites.size());
  // Record ignore twice.
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), {"gmail.com"}, {important_sites[1].reason_bitfield},
      {"google.com"}, {important_sites[0].reason_bitfield});
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), {"gmail.com"}, {important_sites[1].reason_bitfield},
      {"google.com"}, {important_sites[0].reason_bitfield});

  // Important fetch 2.
  important_sites = ImportantSitesUtil::GetImportantRegisterableDomains(
      profile(), kNumImportantSites);
  ExpectImportantResultsEq(expected_sorted_domains, expected_sorted_origins,
                           important_sites);
  // We shouldn't blacklist after first two times.
  ASSERT_EQ(2u, important_sites.size());

  // Record ignore 3rd time.
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), {"gmail.com"}, {important_sites[1].reason_bitfield},
      {"google.com"}, {important_sites[0].reason_bitfield});

  // Important fetch 3. Google.com should be blacklisted now.
  important_sites = ImportantSitesUtil::GetImportantRegisterableDomains(
      profile(), kNumImportantSites);

  ASSERT_EQ(1u, important_sites.size());
  expected_sorted_domains = {"gmail.com"};
  expected_sorted_origins = {url2};
  ExpectImportantResultsEq(expected_sorted_domains, expected_sorted_origins,
                           important_sites);
}

TEST_F(ImportantSitesUtilTest, BlacklistingReset) {
  SiteEngagementService* service = SiteEngagementService::Get(profile());
  ASSERT_TRUE(service);

  GURL url1("http://www.google.com/");
  GURL url2("http://www.gmail.com/");

  // Set a bunch of positive signals.
  service->ResetBaseScoreForURL(url1, 5);
  AddBookmark(url2);
  AddContentSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_ALLOW,
                    url1);

  // Important fetch 1.
  std::vector<ImportantDomainInfo> important_sites =
      ImportantSitesUtil::GetImportantRegisterableDomains(profile(),
                                                          kNumImportantSites);
  ASSERT_EQ(2u, important_sites.size());
  // Record ignore twice.
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), {"gmail.com"}, {important_sites[1].reason_bitfield},
      {"google.com"}, {important_sites[0].reason_bitfield});
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), {"gmail.com"}, {important_sites[1].reason_bitfield},
      {"google.com"}, {important_sites[0].reason_bitfield});

  // Important fetch, we should still be there.
  important_sites = ImportantSitesUtil::GetImportantRegisterableDomains(
      profile(), kNumImportantSites);
  std::vector<std::string> expected_sorted_domains = {"google.com",
                                                      "gmail.com"};
  std::vector<GURL> expected_sorted_origins = {url1, url2};
  ASSERT_EQ(2u, important_sites.size());
  ExpectImportantResultsEq(expected_sorted_domains, expected_sorted_origins,
                           important_sites);

  // Record NOT ignored.
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), {"google.com", "gmail.com"},
      {important_sites[0].reason_bitfield, important_sites[1].reason_bitfield},
      std::vector<std::string>(), std::vector<int32_t>());

  // Record ignored twice again
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), {"gmail.com"}, {important_sites[1].reason_bitfield},
      {"google.com"}, {important_sites[0].reason_bitfield});
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), {"gmail.com"}, {important_sites[1].reason_bitfield},
      {"google.com"}, {important_sites[0].reason_bitfield});

  // Important fetch, we should still be there.
  important_sites = ImportantSitesUtil::GetImportantRegisterableDomains(
      profile(), kNumImportantSites);
  ExpectImportantResultsEq(expected_sorted_domains, expected_sorted_origins,
                           important_sites);

  // Record ignored 3rd time in a row.
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), {"gmail.com"}, {important_sites[1].reason_bitfield},
      {"google.com"}, {important_sites[0].reason_bitfield});

  // Blacklisted now.
  important_sites = ImportantSitesUtil::GetImportantRegisterableDomains(
      profile(), kNumImportantSites);
  ASSERT_EQ(1u, important_sites.size());
  expected_sorted_domains = {"gmail.com"};
  expected_sorted_origins = {url2};
  ExpectImportantResultsEq(expected_sorted_domains, expected_sorted_origins,
                           important_sites);
}

TEST_F(ImportantSitesUtilTest, Metrics) {
  SiteEngagementService* service = SiteEngagementService::Get(profile());
  ASSERT_TRUE(service);
  base::HistogramTester histogram_tester;

  GURL url1("http://www.google.com/");
  service->ResetBaseScoreForURL(url1, 5);
  AddContentSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_ALLOW,
                    url1);

  GURL url2("http://www.youtube.com/");
  AddBookmark(url2);

  GURL url3("http://www.bad.com/");
  AddBookmark(url3);

  std::vector<ImportantDomainInfo> important_sites =
      ImportantSitesUtil::GetImportantRegisterableDomains(profile(),
                                                          kNumImportantSites);

  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), {"google.com", "youtube.com"},
      {important_sites[0].reason_bitfield, important_sites[1].reason_bitfield},
      {"bad.com"}, {important_sites[2].reason_bitfield});

  EXPECT_THAT(
      histogram_tester.GetAllSamples("Storage.ImportantSites.CBDChosenReason"),
      testing::ElementsAre(base::Bucket(ENGAGEMENT, 1),
                           base::Bucket(BOOKMARKS, 1),
                           base::Bucket(NOTIFICATIONS, 1)));

  EXPECT_THAT(
      histogram_tester.GetAllSamples("Storage.ImportantSites.CBDIgnoredReason"),
      testing::ElementsAre(base::Bucket(BOOKMARKS, 1)));

  // Bookmarks are "unknown", as they were added after the crossed reasons.
  EXPECT_THAT(histogram_tester.GetAllSamples(
                  "Storage.BlacklistedImportantSites.Reason"),
              testing::ElementsAre(
                  base::Bucket(CROSSED_NOTIFICATIONS_AND_ENGAGEMENT, 1),
                  base::Bucket(CROSSED_REASON_UNKNOWN, 1)));
}

TEST_F(ImportantSitesUtilTest, DialogBlacklisting) {
  SiteEngagementService* service = SiteEngagementService::Get(profile());
  ASSERT_TRUE(service);

  GURL url1("http://www.google.com/");
  GURL url2("http://www.yahoo.com/");

  // Set a bunch of positive signals.
  service->ResetBaseScoreForURL(url2, 5);
  AddBookmark(url1);
  AddContentSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_ALLOW,
                    url1);

  // Start off not disabled.
  EXPECT_FALSE(ImportantSitesUtil::IsDialogDisabled(profile()));

  // Important fetch 1.
  std::vector<ImportantDomainInfo> important_sites =
      ImportantSitesUtil::GetImportantRegisterableDomains(profile(),
                                                          kNumImportantSites);
  std::vector<std::string> expected_sorted_domains = {"google.com",
                                                      "yahoo.com"};
  std::vector<GURL> expected_sorted_origins = {url1, url2};
  ExpectImportantResultsEq(expected_sorted_domains, expected_sorted_origins,
                           important_sites);
  ASSERT_EQ(2u, important_sites.size());
  // Ignore all sites 2 times.
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), std::vector<std::string>(), std::vector<int32_t>(),
      {"google.com", "yahoo.com"},
      {important_sites[0].reason_bitfield, important_sites[1].reason_bitfield});
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), std::vector<std::string>(), std::vector<int32_t>(),
      {"google.com", "yahoo.com"},
      {important_sites[0].reason_bitfield, important_sites[1].reason_bitfield});

  // Still not disabled...
  EXPECT_FALSE(ImportantSitesUtil::IsDialogDisabled(profile()));

  // Ignore 3rd time.
  ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
      profile(), std::vector<std::string>(), std::vector<int32_t>(),
      {"google.com", "yahoo.com"},
      {important_sites[0].reason_bitfield, important_sites[1].reason_bitfield});

  // Items should still be present.
  important_sites = ImportantSitesUtil::GetImportantRegisterableDomains(
      profile(), kNumImportantSites);
  ExpectImportantResultsEq(expected_sorted_domains, expected_sorted_origins,
                           important_sites);

  // Dialog should be blacklisted.
  EXPECT_TRUE(ImportantSitesUtil::IsDialogDisabled(profile()));
}
