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

 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_SUITE_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
