// 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 <array>

#include "base/strings/string_number_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/permissions/notifications_engagement_service_factory.h"
#include "chrome/test/base/testing_profile.h"
#include "components/site_engagement/content/site_engagement_service.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace permissions {
constexpr char kEngagementKey[] = "click_count";
constexpr char kDisplayedKey[] = "display_count";
constexpr char kSuspiciousKey[] = "suspicious_count";

class NotificationsEngagementServiceTest : public testing::Test {
 public:
  NotificationsEngagementServiceTest()
      : profile_(std::make_unique<TestingProfile>()) {}

  void SetUp() override;

  NotificationsEngagementServiceTest(
      const NotificationsEngagementServiceTest&) = delete;
  NotificationsEngagementServiceTest& operator=(
      const NotificationsEngagementServiceTest&) = delete;

 protected:
  NotificationsEngagementService* service() {
    return NotificationsEngagementServiceFactory::GetForProfile(profile());
  }

  TestingProfile* profile() { return profile_.get(); }

  content::BrowserTaskEnvironment task_environment_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};

 private:
  std::unique_ptr<TestingProfile> profile_;
};

void NotificationsEngagementServiceTest::SetUp() {
  testing::Test::SetUp();
}

TEST_F(NotificationsEngagementServiceTest,
       NotificationsEngagementContentSetting) {
  auto hosts = std::to_array<GURL>(
      {GURL("https://google.com/"), GURL("https://www.youtube.com/")});

  // Otherwise the test time and the service time will be out of sync and cause
  // the tests to fail.
  task_environment_.FastForwardBy(base::Days(2));

  // Record initial display date to enable comparing dictionaries.
  std::string displayedDate = service()->GetBucketLabel(base::Time::Now());

  HostContentSettingsMap* host_content_settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());

  // Testing the dictionary of URLS
  ContentSettingsForOneType notifications_engagement_setting =
      host_content_settings_map->GetSettingsForOneType(
          ContentSettingsType::NOTIFICATION_INTERACTIONS);
  ASSERT_EQ(0U, notifications_engagement_setting.size());

  // Test that a new Dict entry is added when no entry existed for the given
  // URL.
  service()->RecordNotificationDisplayed(hosts[0]);
  service()->RecordNotificationDisplayed(hosts[0]);
  notifications_engagement_setting =
      host_content_settings_map->GetSettingsForOneType(
          ContentSettingsType::NOTIFICATION_INTERACTIONS);
  ASSERT_EQ(1U, notifications_engagement_setting.size());

  // Advance time to set same URL entries in different dates.
  task_environment_.FastForwardBy(base::Days(8));
  std::string displayedDateLater = service()->GetBucketLabel(base::Time::Now());

  // Test that the same URL entry is not duplicated.
  service()->RecordNotificationDisplayed(hosts[0]);
  service()->RecordNotificationInteraction(hosts[0]);
  notifications_engagement_setting =
      host_content_settings_map->GetSettingsForOneType(
          ContentSettingsType::NOTIFICATION_INTERACTIONS);
  ASSERT_EQ(1U, notifications_engagement_setting.size());

  // Test that different entries are created for different URL.
  service()->RecordNotificationDisplayed(hosts[1]);
  notifications_engagement_setting =
      host_content_settings_map->GetSettingsForOneType(
          ContentSettingsType::NOTIFICATION_INTERACTIONS);
  ASSERT_EQ(2U, notifications_engagement_setting.size());

  // Verify the contents of the |notifications_engagement_setting| for
  // hosts[0].
  base::Value::Dict engagement_dict1;
  base::Value::Dict dict1_entry1;
  dict1_entry1.Set(kDisplayedKey, 2);
  base::Value::Dict dict1_entry2;
  dict1_entry2.Set(kDisplayedKey, 1);
  dict1_entry2.Set(kEngagementKey, 1);
  engagement_dict1.Set(displayedDate, std::move(dict1_entry1));
  engagement_dict1.Set(displayedDateLater, std::move(dict1_entry2));
  base::Value engagement_dict_value1 = base::Value(std::move(engagement_dict1));

  ASSERT_EQ(ContentSettingsPattern::FromURLNoWildcard(hosts[0]),
            notifications_engagement_setting.at(0).primary_pattern);
  ASSERT_EQ(ContentSettingsPattern::Wildcard(),
            notifications_engagement_setting.at(0).secondary_pattern);
  ASSERT_EQ(engagement_dict_value1,
            notifications_engagement_setting.at(0).setting_value);

  // Verify the contents of the |notifications_engagement_setting| for
  // hosts[1].
  base::Value::Dict engagement_dict2;
  base::Value::Dict dict2_entry1;
  dict2_entry1.Set(kDisplayedKey, 1);
  engagement_dict2.Set(displayedDateLater, std::move(dict2_entry1));
  base::Value engagement_dict_value2 = base::Value(std::move(engagement_dict2));

  ASSERT_EQ(ContentSettingsPattern::FromURLNoWildcard(hosts[1]),
            notifications_engagement_setting.at(1).primary_pattern);
  ASSERT_EQ(ContentSettingsPattern::Wildcard(),
            notifications_engagement_setting.at(1).secondary_pattern);
  ASSERT_EQ(engagement_dict_value2,
            notifications_engagement_setting.at(1).setting_value);
}

TEST_F(NotificationsEngagementServiceTest,
       RecordNotificationDisplayedAndInteraction) {
  GURL url1("https://www.google.com/");
  GURL url2("https://www.youtube.com/");
  GURL url3("https://www.permissions.site.com/");

  HostContentSettingsMap* host_content_settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());
  // Test notifications sent within the same day constitute one date entry.

  task_environment_.FastForwardBy(base::Days(2));
  service()->RecordNotificationDisplayed(url1);
  service()->RecordNotificationDisplayed(url1);

  base::Value website_engagement_value1 =
      host_content_settings_map->GetWebsiteSetting(
          url1, GURL(), ContentSettingsType::NOTIFICATION_INTERACTIONS);
  ASSERT_TRUE(website_engagement_value1.is_dict());
  base::Value::Dict& website_engagement_dict1 =
      website_engagement_value1.GetDict();

  ASSERT_EQ(1U, website_engagement_dict1.size());

  // Test notifications sent in different days constitute different entries.
  service()->RecordNotificationDisplayed(url2);

  task_environment_.FastForwardBy(base::Days(14));
  service()->RecordNotificationDisplayed(url2);

  task_environment_.FastForwardBy(base::Days(7));
  service()->RecordNotificationDisplayed(url2);

  base::Value website_engagement_value2 =
      host_content_settings_map->GetWebsiteSetting(
          url2, GURL(), ContentSettingsType::NOTIFICATION_INTERACTIONS);
  ASSERT_TRUE(website_engagement_value2.is_dict());
  base::Value::Dict& website_engagement_dict2 =
      website_engagement_value2.GetDict();

  ASSERT_EQ(3U, website_engagement_dict2.size());

  // Test that display_count and click_count are incremented correctly.
  service()->RecordNotificationDisplayed(url3);
  service()->RecordNotificationDisplayed(url3);

  service()->RecordNotificationInteraction(url3);
  service()->RecordNotificationInteraction(url3);
  service()->RecordNotificationInteraction(url3);

  base::Value website_engagement_value3 =
      host_content_settings_map->GetWebsiteSetting(
          url3, GURL(), ContentSettingsType::NOTIFICATION_INTERACTIONS);
  ASSERT_TRUE(website_engagement_value3.is_dict());
  base::Value::Dict& website_engagement_dict3 =
      website_engagement_value3.GetDict();

  std::string displayedDate = service()->GetBucketLabel(base::Time::Now());
  base::Value* entryForDate = website_engagement_dict3.Find(displayedDate);

  ASSERT_EQ(2, entryForDate->GetDict().FindInt(kDisplayedKey).value());
  ASSERT_EQ(3, entryForDate->GetDict().FindInt(kEngagementKey).value());
}

TEST_F(NotificationsEngagementServiceTest, RecordNotificationSuspicious) {
  GURL url1("https://www.suspicious1.site.com/");
  GURL url2("https://www.suspicious2.site.com/");

  HostContentSettingsMap* host_content_settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());

  // Notification interaction with display only.
  task_environment_.FastForwardBy(base::Days(2));
  service()->RecordNotificationDisplayed(url1);
  std::string date0 = service()->GetBucketLabel(base::Time::Now());

  // Simulate initial notification interaction with suspicious warning.
  task_environment_.FastForwardBy(base::Days(2));
  service()->RecordNotificationSuspicious(url1);
  service()->RecordNotificationSuspicious(url1);
  std::string date1 = service()->GetBucketLabel(base::Time::Now());

  // Simulate later notification interaction.
  task_environment_.FastForwardBy(base::Days(5));
  service()->RecordNotificationSuspicious(url1);
  // Add to content setting for different url.
  service()->RecordNotificationSuspicious(url2);
  service()->RecordNotificationSuspicious(url2);
  service()->RecordNotificationSuspicious(url2);
  std::string date2 = service()->GetBucketLabel(base::Time::Now());

  // Verify notification interaction content setting for url 1.
  base::Value url1_notification_interaction =
      host_content_settings_map->GetWebsiteSetting(
          url1, GURL(), ContentSettingsType::NOTIFICATION_INTERACTIONS);
  ASSERT_TRUE(url1_notification_interaction.is_dict());
  base::Value::Dict& url1_notification_interaction_dict =
      url1_notification_interaction.GetDict();
  ASSERT_EQ(3U, url1_notification_interaction_dict.size());
  base::Value* url1_date0_entry =
      url1_notification_interaction_dict.Find(date0);
  ASSERT_EQ(0, url1_date0_entry->GetDict().FindInt(kSuspiciousKey).value_or(0));
  base::Value* url1_date1_entry =
      url1_notification_interaction_dict.Find(date1);
  ASSERT_EQ(2, url1_date1_entry->GetDict().FindInt(kSuspiciousKey).value());
  base::Value* url1_date2_entry =
      url1_notification_interaction_dict.Find(date2);
  ASSERT_EQ(1, url1_date2_entry->GetDict().FindInt(kSuspiciousKey).value_or(0));

  // Verify notification interaction content setting for url 2.
  base::Value url2_notification_interaction =
      host_content_settings_map->GetWebsiteSetting(
          url2, GURL(), ContentSettingsType::NOTIFICATION_INTERACTIONS);
  ASSERT_TRUE(url2_notification_interaction.is_dict());
  base::Value::Dict& url2_notification_interaction_dict =
      url2_notification_interaction.GetDict();
  ASSERT_EQ(1U, url2_notification_interaction_dict.size());
  base::Value* url2_date2_entry =
      url2_notification_interaction_dict.Find(date2);
  ASSERT_EQ(3, url2_date2_entry->GetDict().FindInt(kSuspiciousKey).value());
}

TEST_F(NotificationsEngagementServiceTest,
       RecordNotificationDisplayedAndInteractionReportsUMA) {
  GURL url1("https://url1.test/");
  GURL url2("https://url2.test/");
  GURL url3("https://url3.test/");
  GURL url4("https://url4.test/");
  GURL url5("https://url5.test/");
  GURL url6("https://url6.test/");
  GURL url7("https://url7.test/");
  GURL url8("https://url8.test/");

  {
    base::HistogramTester histogram_tester;
    service()->RecordNotificationDisplayed(url1);
    histogram_tester.ExpectUniqueSample(
        "Notifications.Engagement.Displayed.Volume0", 0, 1);
  }

  {
    site_engagement::SiteEngagementService* site_engagement_service =
        site_engagement::SiteEngagementService::Get(profile());
    site_engagement_service->AddPointsForTesting(url2, 4);

    base::HistogramTester histogram_tester;
    service()->RecordNotificationDisplayed(url2);
    histogram_tester.ExpectUniqueSample(
        "Notifications.Engagement.Displayed.Volume0",
        site_engagement_service->GetScore(url2) * 2, 1);
  }

  {
    base::HistogramTester histogram_tester;
    service()->RecordNotificationDisplayed(url3, 7);
    histogram_tester.ExpectUniqueSample(
        "Notifications.Engagement.Displayed.Volume1", 0, 7);
  }

  {
    base::HistogramTester histogram_tester;
    service()->RecordNotificationDisplayed(url4, 5 * 7);
    histogram_tester.ExpectUniqueSample(
        "Notifications.Engagement.Displayed.Volume5", 0, 5 * 7);
  }

  {
    base::HistogramTester histogram_tester;
    service()->RecordNotificationDisplayed(url5, 10 * 7);
    histogram_tester.ExpectUniqueSample(
        "Notifications.Engagement.Displayed.Volume10", 0, 10 * 7);
  }

  {
    base::HistogramTester histogram_tester;
    service()->RecordNotificationDisplayed(url6, 20 * 7);
    histogram_tester.ExpectUniqueSample(
        "Notifications.Engagement.Displayed.Volume20", 0, 20 * 7);
  }

  {
    base::HistogramTester histogram_tester;
    service()->RecordNotificationDisplayed(url7, 30 * 7);
    histogram_tester.ExpectUniqueSample(
        "Notifications.Engagement.Displayed.VolumeAbove20", 0, 30 * 7);
  }

  {
    base::HistogramTester histogram_tester;
    service()->RecordNotificationInteraction(url8);
    histogram_tester.ExpectUniqueSample(
        "Notifications.Engagement.Clicked.Volume0", 0, 1);
  }
}

TEST_F(NotificationsEngagementServiceTest,
       RecordNotificationSuspiciousReportsUMA) {
  GURL url("https://url.test/");

  base::HistogramTester histogram_tester;
  service()->RecordNotificationSuspicious(url);
  histogram_tester.ExpectUniqueSample(
      "Notifications.Engagement.Suspicious.Volume0", 0, 1);
}

TEST_F(NotificationsEngagementServiceTest, EraseStaleEntries) {
  GURL url("https://www.google.com/");

  // Test that only entries older than 30 days are deleted.
  task_environment_.FastForwardBy(base::Days(10950));
  service()->RecordNotificationDisplayed(url);
  task_environment_.FastForwardBy(base::Days(31));
  service()->RecordNotificationDisplayed(url);

  task_environment_.FastForwardBy(base::Days(8));
  service()->RecordNotificationDisplayed(url);

  HostContentSettingsMap* host_content_settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());

  base::Value::Dict website_engagement =
      host_content_settings_map
          ->GetWebsiteSetting(url, GURL(),
                              ContentSettingsType::NOTIFICATION_INTERACTIONS)
          .GetDict()
          .Clone();

  // Stale entries should be erased, when a new display/interaction is
  // recorded.
  ASSERT_EQ(2u, website_engagement.size());
}

TEST_F(NotificationsEngagementServiceTest,
       GetSuspiciousNotificationCountForPeriod) {
  GURL url("https://www.suspicious.site.com/");
  HostContentSettingsMap* host_content_settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());

  // Record suspicious notifications over several days.
  task_environment_.FastForwardBy(base::Days(2));
  service()->RecordNotificationSuspicious(url);
  service()->RecordNotificationSuspicious(url);

  task_environment_.FastForwardBy(base::Days(5));
  service()->RecordNotificationSuspicious(url);

  task_environment_.FastForwardBy(base::Days(10));
  service()->RecordNotificationSuspicious(url);
  service()->RecordNotificationSuspicious(url);
  service()->RecordNotificationSuspicious(url);

  task_environment_.FastForwardBy(base::Days(1));
  service()->RecordNotificationSuspicious(url);
  service()->RecordNotificationSuspicious(url);

  base::Value website_engagement_value =
      host_content_settings_map->GetWebsiteSetting(
          url, GURL(), ContentSettingsType::NOTIFICATION_INTERACTIONS);
  ASSERT_TRUE(website_engagement_value.is_dict());
  base::Value::Dict& website_engagement_dict =
      website_engagement_value.GetDict();

  // No lookback period.
  EXPECT_EQ(
      NotificationsEngagementService::GetSuspiciousNotificationCountForPeriod(
          website_engagement_dict, 0),
      0);
  // Lookback period of 1 day.
  EXPECT_EQ(
      NotificationsEngagementService::GetSuspiciousNotificationCountForPeriod(
          website_engagement_dict, 1),
      2);

  // Lookback period of 7 days.
  EXPECT_EQ(
      NotificationsEngagementService::GetSuspiciousNotificationCountForPeriod(
          website_engagement_dict, 7),
      5);

  // Long lookback period.
  EXPECT_EQ(
      NotificationsEngagementService::GetSuspiciousNotificationCountForPeriod(
          website_engagement_dict, 12),
      6);
  // Lookback period that includes all recorded suspicious
  // notifications.
  EXPECT_EQ(
      NotificationsEngagementService::GetSuspiciousNotificationCountForPeriod(
          website_engagement_dict, 30),
      8);
}

// Disabled, due to http://go/crb/1407635.
TEST_F(NotificationsEngagementServiceTest, DISABLED_GetBucketLabel) {
  base::Time date1, date2, date3, date4;
  base::Time expected_date1, expected_date2, expected_date3, expected_date4;

  ASSERT_TRUE(base::Time::FromString("23 Oct 2009 11:30 GMT", &date1));
  ASSERT_TRUE(
      base::Time::FromString("2009-10-23 00:00:00.000 GMT", &expected_date1));
  ASSERT_EQ(NotificationsEngagementService::GetBucketLabel(date1),
            base::NumberToString(expected_date1.base::Time::ToTimeT()));
  std::string label1 = NotificationsEngagementService::GetBucketLabel(date1);
  ASSERT_EQ(label1, base::NumberToString(expected_date1.base::Time::ToTimeT()));
  std::optional<base::Time> begin1 =
      NotificationsEngagementService::ParsePeriodBeginFromBucketLabel(label1);
  ASSERT_TRUE(begin1.has_value());
  EXPECT_EQ(label1,
            NotificationsEngagementService::GetBucketLabel(begin1.value()));

  ASSERT_TRUE(base::Time::FromString("Mon Oct 15 12:45 PDT 2007", &date2));
  ASSERT_TRUE(
      base::Time::FromString("2007-10-15 00:00:00.000 GMT", &expected_date2));
  ASSERT_EQ(NotificationsEngagementService::GetBucketLabel(date2),
            base::NumberToString(expected_date2.base::Time::ToTimeT()));
  std::string label2 = NotificationsEngagementService::GetBucketLabel(date2);
  ASSERT_EQ(label2, base::NumberToString(expected_date2.base::Time::ToTimeT()));
  std::optional<base::Time> begin2 =
      NotificationsEngagementService::ParsePeriodBeginFromBucketLabel(label2);
  ASSERT_TRUE(begin2.has_value());
  EXPECT_EQ(label2,
            NotificationsEngagementService::GetBucketLabel(begin2.value()));

  ASSERT_TRUE(base::Time::FromString("Mon Jan 01 13:59:58 +0100 1973", &date3));
  ASSERT_TRUE(
      base::Time::FromString("1973-01-01 00:00:00.000 GMT", &expected_date3));
  ASSERT_EQ(NotificationsEngagementService::GetBucketLabel(date3),
            base::NumberToString(expected_date3.base::Time::ToTimeT()));
  std::string label3 = NotificationsEngagementService::GetBucketLabel(date3);
  ASSERT_EQ(label3, base::NumberToString(expected_date3.base::Time::ToTimeT()));
  std::optional<base::Time> begin3 =
      NotificationsEngagementService::ParsePeriodBeginFromBucketLabel(label3);
  ASSERT_TRUE(begin3.has_value());
  EXPECT_EQ(label3,
            NotificationsEngagementService::GetBucketLabel(begin3.value()));

  ASSERT_TRUE(base::Time::FromString("Wed Mar 23 04:38:58 -1000 2022", &date4));
  ASSERT_TRUE(
      base::Time::FromString("2022-03-23 00:00:00.000 GMT", &expected_date4));
  std::string label4 = NotificationsEngagementService::GetBucketLabel(date4);
  ASSERT_EQ(label4, base::NumberToString(expected_date4.base::Time::ToTimeT()));
  std::optional<base::Time> begin4 =
      NotificationsEngagementService::ParsePeriodBeginFromBucketLabel(label4);
  ASSERT_TRUE(begin4.has_value());
  EXPECT_EQ(label4,
            NotificationsEngagementService::GetBucketLabel(begin4.value()));
}
}  // namespace permissions
