// 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/histogram_tester.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 "components/variations/variations_params_manager.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.
  variations::testing::VariationParamsManager variation_params(
      kArticleSuggestionsFeature.name,
      {{"user_classifier_active_consumer_clicks_at_least_once_per_hours",
        "36"}},
      {kArticleSuggestionsFeature.name});
  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.
  variations::testing::VariationParamsManager variation_params(
      kArticleSuggestionsFeature.name,
      {{"user_classifier_rare_user_opens_ntp_at_most_once_per_hours", "48"}},
      {kArticleSuggestionsFeature.name});
  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() : UserClassifierTest() {}

 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.
  variations::testing::VariationParamsManager variation_params(
      kArticleSuggestionsFeature.name, {{"user_classifier_min_hours", "1.0"}},
      {kArticleSuggestionsFeature.name});
  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.
  variations::testing::VariationParamsManager variation_params(
      kArticleSuggestionsFeature.name, {{"user_classifier_max_hours", "72"}},
      {kArticleSuggestionsFeature.name});
  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_CASE_P(
    ,  // An empty prefix for the parametrized tests names (no need to
       // distinguish the only instance we make here).
    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
