// Copyright 2022 The Chromium OS 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 "feature_usage/feature_usage_metrics.h"

#include <base/logging.h>
#include <base/power_monitor/power_monitor.h>
#include <base/power_monitor/power_monitor_device_source.h>
#include <base/run_loop.h>
#include <base/test/task_environment.h>
#include <base/time/clock.h>
#include <base/time/time.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library_mock.h>

namespace feature_usage {

namespace {

const char kTestFeature[] = "TestFeature";
const char kTestMetric[] = "ChromeOS.FeatureUsage.TestFeature";
const char kTestUsetimeMetric[] = "ChromeOS.FeatureUsage.TestFeature.Usetime";
constexpr base::TimeDelta kDefaultUseTime = base::Minutes(10);

}  // namespace

class FeatureUsageMetricsTest : public ::testing::Test,
                                public FeatureUsageMetrics::Delegate {
 public:
  FeatureUsageMetricsTest() {
    if (!base::PowerMonitor::IsInitialized()) {
      base::PowerMonitor::Initialize(
          std::make_unique<base::PowerMonitorDeviceSource>());
    }

    feature_usage_metrics_ = std::make_unique<FeatureUsageMetrics>(
        kTestFeature, this, env_.GetMockClock(), env_.GetMockTickClock());

    feature_usage_metrics_->SetMetricsLibraryForTesting(
        std::make_unique<MetricsLibraryMock>());
  }

  // FeatureUsageMetrics::Delegate:
  bool IsEligible() const override { return is_eligible_; }
  std::optional<bool> IsAccessible() const override { return is_accessible_; }
  bool IsEnabled() const override { return is_enabled_; }

 protected:
  base::test::TaskEnvironment env_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};

  bool is_eligible_ = true;
  std::optional<bool> is_accessible_;
  bool is_enabled_ = true;

  MetricsLibraryMock* GetMetricsLibraryMock() {
    return static_cast<MetricsLibraryMock*>(
        feature_usage_metrics_->metrics_library_for_testing());
  }

  std::unique_ptr<FeatureUsageMetrics> feature_usage_metrics_;
};

TEST_F(FeatureUsageMetricsTest, RecordUsageWithSuccess) {
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEligible),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEnabled),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric,
          static_cast<int>(FeatureUsageMetrics::Event::kUsedWithSuccess),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  feature_usage_metrics_->RecordUsage(/*success=*/true);
}

TEST_F(FeatureUsageMetricsTest, RecordUsageWithFailure) {
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEligible),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEnabled),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric,
          static_cast<int>(FeatureUsageMetrics::Event::kUsedWithFailure),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  feature_usage_metrics_->RecordUsage(/*success=*/false);
}

TEST_F(FeatureUsageMetricsTest, RecordUsetime) {
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEligible),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEnabled),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric,
          static_cast<int>(FeatureUsageMetrics::Event::kUsedWithSuccess),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(*GetMetricsLibraryMock(),
              SendToUMA(kTestUsetimeMetric, kDefaultUseTime.InMilliseconds(),
                        base::Milliseconds(1).InMilliseconds(),
                        base::Hours(1).InMilliseconds(), 100));
  feature_usage_metrics_->RecordUsage(/*success=*/true);
  feature_usage_metrics_->StartSuccessfulUsage();
  env_.FastForwardBy(kDefaultUseTime);
  feature_usage_metrics_->StopSuccessfulUsage();
}

TEST_F(FeatureUsageMetricsTest, RecordLongUsetime) {
  size_t repeated_periods = 4;
  const base::TimeDelta extra_small_use_time = base::Minutes(3);
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEligible),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1))
      .Times(repeated_periods + 1);
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEnabled),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1))
      .Times(repeated_periods + 1);
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric,
          static_cast<int>(FeatureUsageMetrics::Event::kUsedWithSuccess),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(*GetMetricsLibraryMock(),
              SendToUMA(kTestUsetimeMetric,
                        FeatureUsageMetrics::kRepeatedInterval.InMilliseconds(),
                        base::Milliseconds(1).InMilliseconds(),
                        base::Hours(1).InMilliseconds(), 100))
      .Times(repeated_periods);
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendToUMA(kTestUsetimeMetric, extra_small_use_time.InMilliseconds(),
                base::Milliseconds(1).InMilliseconds(),
                base::Hours(1).InMilliseconds(), 100));
  const base::TimeDelta use_time =
      FeatureUsageMetrics::kRepeatedInterval * repeated_periods +
      extra_small_use_time;

  feature_usage_metrics_->RecordUsage(/*success=*/true);
  feature_usage_metrics_->StartSuccessfulUsage();
  env_.FastForwardBy(use_time);
  feature_usage_metrics_->StopSuccessfulUsage();
}

TEST_F(FeatureUsageMetricsTest, PeriodicMetricsTest) {
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEligible),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1))
      .Times(2);
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEnabled),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));

  // Trigger initial periodic metrics report.
  env_.FastForwardBy(FeatureUsageMetrics::kInitialInterval);

  is_enabled_ = false;
  // Trigger repeated periodic metrics report.
  env_.FastForwardBy(FeatureUsageMetrics::kRepeatedInterval);

  is_eligible_ = false;
  // Trigger repeated periodic metrics report.
  env_.FastForwardBy(FeatureUsageMetrics::kRepeatedInterval);
}

TEST_F(FeatureUsageMetricsTest, PeriodicWithAccessibleMetricsTest) {
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEligible),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1))
      .Times(3);
  EXPECT_CALL(*GetMetricsLibraryMock(),
              SendEnumToUMA(
                  kTestMetric,
                  static_cast<int>(FeatureUsageMetrics::Event::kAccessible),
                  static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1))
      .Times(2);
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEnabled),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  is_accessible_ = true;
  // Trigger initial periodic metrics report.
  env_.FastForwardBy(FeatureUsageMetrics::kInitialInterval);

  is_enabled_ = false;
  // Trigger repeated periodic metrics report.
  env_.FastForwardBy(FeatureUsageMetrics::kRepeatedInterval);

  is_accessible_ = false;
  // Trigger repeated periodic metrics report.
  env_.FastForwardBy(FeatureUsageMetrics::kRepeatedInterval);

  is_eligible_ = false;
  // Trigger repeated periodic metrics report.
  env_.FastForwardBy(FeatureUsageMetrics::kRepeatedInterval);
}

TEST_F(FeatureUsageMetricsTest, ReportUseTimeOnShutdown) {
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEligible),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEnabled),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric,
          static_cast<int>(FeatureUsageMetrics::Event::kUsedWithSuccess),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(*GetMetricsLibraryMock(),
              SendToUMA(kTestUsetimeMetric, kDefaultUseTime.InMilliseconds(),
                        base::Milliseconds(1).InMilliseconds(),
                        base::Hours(1).InMilliseconds(), 100));
  feature_usage_metrics_->RecordUsage(/*success=*/true);
  feature_usage_metrics_->StartSuccessfulUsage();
  env_.FastForwardBy(kDefaultUseTime);
  feature_usage_metrics_.reset();
}

TEST_F(FeatureUsageMetricsTest, ReportPeriodicOnSuspend) {
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEligible),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEnabled),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  base::PowerMonitorDeviceSource::HandleSystemSuspending();
  base::RunLoop().RunUntilIdle();

  // Undo global changes.
  base::PowerMonitorDeviceSource::HandleSystemResumed();
}

TEST_F(FeatureUsageMetricsTest, ReportUseTimeOnSuspend) {
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEligible),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1))
      .Times(2);
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEnabled),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1))
      .Times(2);
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric,
          static_cast<int>(FeatureUsageMetrics::Event::kUsedWithSuccess),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(*GetMetricsLibraryMock(),
              SendToUMA(kTestUsetimeMetric, kDefaultUseTime.InMilliseconds(),
                        base::Milliseconds(1).InMilliseconds(),
                        base::Hours(1).InMilliseconds(), 100));
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendToUMA(kTestUsetimeMetric, 0, base::Milliseconds(1).InMilliseconds(),
                base::Hours(1).InMilliseconds(), 100));
  feature_usage_metrics_->RecordUsage(/*success=*/true);
  feature_usage_metrics_->StartSuccessfulUsage();
  env_.FastForwardBy(kDefaultUseTime);

  base::PowerMonitorDeviceSource::HandleSystemSuspending();
  base::RunLoop().RunUntilIdle();

  // Undo global changes.
  base::PowerMonitorDeviceSource::HandleSystemResumed();
}

TEST_F(FeatureUsageMetricsTest, SuspensionTimeNotReported) {
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEligible),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1))
      .Times(3);
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric, static_cast<int>(FeatureUsageMetrics::Event::kEnabled),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1))
      .Times(3);
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendEnumToUMA(
          kTestMetric,
          static_cast<int>(FeatureUsageMetrics::Event::kUsedWithSuccess),
          static_cast<int>(FeatureUsageMetrics::Event::kMaxValue) + 1));
  EXPECT_CALL(*GetMetricsLibraryMock(),
              SendToUMA(kTestUsetimeMetric, kDefaultUseTime.InMilliseconds(),
                        base::Milliseconds(1).InMilliseconds(),
                        base::Hours(1).InMilliseconds(), 100));
  EXPECT_CALL(*GetMetricsLibraryMock(),
              SendToUMA(kTestUsetimeMetric,
                        FeatureUsageMetrics::kInitialInterval.InMilliseconds(),
                        base::Milliseconds(1).InMilliseconds(),
                        base::Hours(1).InMilliseconds(), 100));
  EXPECT_CALL(
      *GetMetricsLibraryMock(),
      SendToUMA(kTestUsetimeMetric,
                kDefaultUseTime.InMilliseconds() -
                    FeatureUsageMetrics::kInitialInterval.InMilliseconds(),
                base::Milliseconds(1).InMilliseconds(),
                base::Hours(1).InMilliseconds(), 100));
  feature_usage_metrics_->RecordUsage(/*success=*/true);
  feature_usage_metrics_->StartSuccessfulUsage();
  env_.FastForwardBy(kDefaultUseTime);
  base::PowerMonitorDeviceSource::HandleSystemSuspending();
  base::RunLoop().RunUntilIdle();

  // Time during suspension must not be reported.
  env_.AdvanceClock(FeatureUsageMetrics::kRepeatedInterval * 1.33);

  base::PowerMonitorDeviceSource::HandleSystemResumed();
  base::RunLoop().RunUntilIdle();

  env_.FastForwardBy(kDefaultUseTime);
  feature_usage_metrics_->StopSuccessfulUsage();
}

}  // namespace feature_usage
