// 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/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()));
}
