// Copyright 2017 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 "components/ntp_snippets/user_classifier.h"

#include <memory>
#include <string>
#include <utility>

#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/time/time.h"
#include "components/ntp_snippets/features.h"
#include "components/ntp_snippets/ntp_snippets_constants.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::DoubleNear;
using testing::Eq;
using testing::Gt;
using testing::Lt;
using testing::SizeIs;

namespace ntp_snippets {
namespace {

char kNowString[] = "2017-03-01 10:45";

class UserClassifierTest : public testing::Test {
 public:
  UserClassifierTest() {
    UserClassifier::RegisterProfilePrefs(test_prefs_.registry());
  }

  UserClassifier* CreateUserClassifier() {
    base::Time now;
    CHECK(base::Time::FromUTCString(kNowString, &now));
    test_clock_.SetNow(now);

    user_classifier_ =
        std::make_unique<UserClassifier>(&test_prefs_, &test_clock_);
    return user_classifier_.get();
  }

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

 private:
  TestingPrefServiceSimple test_prefs_;
  std::unique_ptr<UserClassifier> user_classifier_;
  base::SimpleTestClock test_clock_;

  DISALLOW_COPY_AND_ASSIGN(UserClassifierTest);
};

TEST_F(UserClassifierTest, ShouldBeActiveNtpUserInitially) {
  UserClassifier* user_classifier = CreateUserClassifier();
  EXPECT_THAT(user_classifier->GetUserClass(),
              Eq(UserClassifier::UserClass::ACTIVE_NTP_USER));
}

TEST_F(UserClassifierTest,
       ShouldBecomeActiveSuggestionsConsumerByClickingOften) {
  UserClassifier* user_classifier = CreateUserClassifier();

  // After one click still only an active user.
  user_classifier->OnEvent(UserClassifier::Metric::SUGGESTIONS_USED);
  EXPECT_THAT(user_classifier->GetUserClass(),
              Eq(UserClassifier::UserClass::ACTIVE_NTP_USER));

  // After a few more clicks, become an active consumer.
  for (int i = 0; i < 5; i++) {
    test_clock()->Advance(base::TimeDelta::FromHours(1));
    user_classifier->OnEvent(UserClassifier::Metric::SUGGESTIONS_USED);
  }
  EXPECT_THAT(user_classifier->GetUserClass(),
              Eq(UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER));
}

TEST_F(UserClassifierTest,
       ShouldBecomeActiveSuggestionsConsumerByClickingOftenWithDecreasedParam) {
  // Increase the param to one half.
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      kArticleSuggestionsFeature,
      {{"user_classifier_active_consumer_clicks_at_least_once_per_hours",
        "36"}});
  UserClassifier* user_classifier = CreateUserClassifier();

  // After two clicks still only an active user.
  user_classifier->OnEvent(UserClassifier::Metric::SUGGESTIONS_USED);
  test_clock()->Advance(base::TimeDelta::FromHours(1));
  user_classifier->OnEvent(UserClassifier::Metric::SUGGESTIONS_USED);
  EXPECT_THAT(user_classifier->GetUserClass(),
              Eq(UserClassifier::UserClass::ACTIVE_NTP_USER));

  // One more click to become an active consumer.
  test_clock()->Advance(base::TimeDelta::FromHours(1));
  user_classifier->OnEvent(UserClassifier::Metric::SUGGESTIONS_USED);
  EXPECT_THAT(user_classifier->GetUserClass(),
              Eq(UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER));
}

TEST_F(UserClassifierTest, ShouldBecomeRareNtpUserByNoActivity) {
  UserClassifier* user_classifier = CreateUserClassifier();

  // After two days of waiting still an active user.
  test_clock()->Advance(base::TimeDelta::FromDays(2));
  EXPECT_THAT(user_classifier->GetUserClass(),
              Eq(UserClassifier::UserClass::ACTIVE_NTP_USER));

  // Two more days to become a rare user.
  test_clock()->Advance(base::TimeDelta::FromDays(2));
  EXPECT_THAT(user_classifier->GetUserClass(),
              Eq(UserClassifier::UserClass::RARE_NTP_USER));
}

TEST_F(UserClassifierTest,
       ShouldBecomeRareNtpUserByNoActivityWithDecreasedParam) {
  // Decrease the param to one half.
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      kArticleSuggestionsFeature,
      {{"user_classifier_rare_user_opens_ntp_at_most_once_per_hours", "48"}});
  UserClassifier* user_classifier = CreateUserClassifier();

  // After one days of waiting still an active user.
  test_clock()->Advance(base::TimeDelta::FromDays(1));
  EXPECT_THAT(user_classifier->GetUserClass(),
              Eq(UserClassifier::UserClass::ACTIVE_NTP_USER));

  // One more day to become a rare user.
  test_clock()->Advance(base::TimeDelta::FromDays(1));
  EXPECT_THAT(user_classifier->GetUserClass(),
              Eq(UserClassifier::UserClass::RARE_NTP_USER));
}

class UserClassifierMetricTest
    : public UserClassifierTest,
      public ::testing::WithParamInterface<
          std::pair<UserClassifier::Metric, std::string>> {
 public:
  UserClassifierMetricTest() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(UserClassifierMetricTest);
};

TEST_P(UserClassifierMetricTest, ShouldDecreaseEstimateAfterEvent) {
  UserClassifier::Metric metric = GetParam().first;
  UserClassifier* user_classifier = CreateUserClassifier();

  // The initial event does not decrease the estimate.
  user_classifier->OnEvent(metric);

  for (int i = 0; i < 10; i++) {
    test_clock()->Advance(base::TimeDelta::FromHours(1));
    double old_metric = user_classifier->GetEstimatedAvgTime(metric);
    user_classifier->OnEvent(metric);
    EXPECT_THAT(user_classifier->GetEstimatedAvgTime(metric), Lt(old_metric));
  }
}

TEST_P(UserClassifierMetricTest, ShouldReportToUmaOnEvent) {
  UserClassifier::Metric metric = GetParam().first;
  const std::string& histogram_name = GetParam().second;
  base::HistogramTester histogram_tester;
  UserClassifier* user_classifier = CreateUserClassifier();

  user_classifier->OnEvent(metric);
  EXPECT_THAT(histogram_tester.GetAllSamples(histogram_name), SizeIs(1));
}

TEST_P(UserClassifierMetricTest, ShouldConvergeTowardsPattern) {
  UserClassifier::Metric metric = GetParam().first;
  UserClassifier* user_classifier = CreateUserClassifier();

  // Have the pattern of an event every five hours and start changing it towards
  // an event every 10 hours.
  for (int i = 0; i < 100; i++) {
    test_clock()->Advance(base::TimeDelta::FromHours(5));
    user_classifier->OnEvent(metric);
  }
  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(metric),
              DoubleNear(5.0, 0.1));
  for (int i = 0; i < 3; i++) {
    test_clock()->Advance(base::TimeDelta::FromHours(10));
    user_classifier->OnEvent(metric);
  }
  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(metric), Gt(5.5));
  for (int i = 0; i < 100; i++) {
    test_clock()->Advance(base::TimeDelta::FromHours(10));
    user_classifier->OnEvent(metric);
  }
  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(metric),
              DoubleNear(10.0, 0.1));
}

TEST_P(UserClassifierMetricTest, ShouldIgnoreSubsequentEventsForHalfAnHour) {
  UserClassifier::Metric metric = GetParam().first;
  UserClassifier* user_classifier = CreateUserClassifier();

  // The initial event
  user_classifier->OnEvent(metric);
  // Subsequent events get ignored for the next 30 minutes.
  for (int i = 0; i < 5; i++) {
    test_clock()->Advance(base::TimeDelta::FromMinutes(5));
    double old_metric = user_classifier->GetEstimatedAvgTime(metric);
    user_classifier->OnEvent(metric);
    EXPECT_THAT(user_classifier->GetEstimatedAvgTime(metric), Eq(old_metric));
  }
  // An event 30 minutes after the initial event is finally not ignored.
  test_clock()->Advance(base::TimeDelta::FromMinutes(5));
  double old_metric = user_classifier->GetEstimatedAvgTime(metric);
  user_classifier->OnEvent(metric);
  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(metric), Lt(old_metric));
}

TEST_P(UserClassifierMetricTest,
       ShouldIgnoreSubsequentEventsWithIncreasedLimit) {
  UserClassifier::Metric metric = GetParam().first;
  // Increase the min_hours to 1.0, i.e. 60 minutes.
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      kArticleSuggestionsFeature, {{"user_classifier_min_hours", "1.0"}});
  UserClassifier* user_classifier = CreateUserClassifier();

  // The initial event
  user_classifier->OnEvent(metric);
  // Subsequent events get ignored for the next 60 minutes.
  for (int i = 0; i < 11; i++) {
    test_clock()->Advance(base::TimeDelta::FromMinutes(5));
    double old_metric = user_classifier->GetEstimatedAvgTime(metric);
    user_classifier->OnEvent(metric);
    EXPECT_THAT(user_classifier->GetEstimatedAvgTime(metric), Eq(old_metric));
  }
  // An event 60 minutes after the initial event is finally not ignored.
  test_clock()->Advance(base::TimeDelta::FromMinutes(5));
  double old_metric = user_classifier->GetEstimatedAvgTime(metric);
  user_classifier->OnEvent(metric);
  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(metric), Lt(old_metric));
}

TEST_P(UserClassifierMetricTest, ShouldCapDelayBetweenEvents) {
  UserClassifier::Metric metric = GetParam().first;
  UserClassifier* user_classifier = CreateUserClassifier();

  // The initial event
  user_classifier->OnEvent(metric);
  // Wait for an insane amount of time
  test_clock()->Advance(base::TimeDelta::FromDays(365));
  user_classifier->OnEvent(metric);
  double metric_after_a_year = user_classifier->GetEstimatedAvgTime(metric);

  // Now repeat the same with s/one year/one week.
  user_classifier->ClearClassificationForDebugging();
  user_classifier->OnEvent(metric);
  test_clock()->Advance(base::TimeDelta::FromDays(7));
  user_classifier->OnEvent(metric);

  // The results should be the same.
  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(metric),
              Eq(metric_after_a_year));
}

TEST_P(UserClassifierMetricTest,
       ShouldCapDelayBetweenEventsWithDecreasedLimit) {
  UserClassifier::Metric metric = GetParam().first;
  // Decrease the max_hours to 72, i.e. 3 days.
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      kArticleSuggestionsFeature, {{"user_classifier_max_hours", "72"}});
  UserClassifier* user_classifier = CreateUserClassifier();

  // The initial event
  user_classifier->OnEvent(metric);
  // Wait for an insane amount of time
  test_clock()->Advance(base::TimeDelta::FromDays(365));
  user_classifier->OnEvent(metric);
  double metric_after_a_year = user_classifier->GetEstimatedAvgTime(metric);

  // Now repeat the same with s/one year/two days.
  user_classifier->ClearClassificationForDebugging();
  user_classifier->OnEvent(metric);
  test_clock()->Advance(base::TimeDelta::FromDays(3));
  user_classifier->OnEvent(metric);

  // The results should be the same.
  EXPECT_THAT(user_classifier->GetEstimatedAvgTime(metric),
              Eq(metric_after_a_year));
}

INSTANTIATE_TEST_SUITE_P(
    NTP,
    UserClassifierMetricTest,
    testing::Values(
        std::make_pair(UserClassifier::Metric::NTP_OPENED,
                       "NewTabPage.UserClassifier.AverageHoursToOpenNTP"),
        std::make_pair(
            UserClassifier::Metric::SUGGESTIONS_SHOWN,
            "NewTabPage.UserClassifier.AverageHoursToShowSuggestions"),
        std::make_pair(
            UserClassifier::Metric::SUGGESTIONS_USED,
            "NewTabPage.UserClassifier.AverageHoursToUseSuggestions")));

}  // namespace
}  // namespace ntp_snippets
