// 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/bind.h>
#include <base/callback.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/power_monitor/power_monitor.h>
#include <base/time/clock.h>
#include <base/time/default_clock.h>
#include <base/time/default_tick_clock.h>
#include <base/time/tick_clock.h>
#include <base/time/time.h>
#include <base/timer/timer.h>

namespace feature_usage {

namespace {

constexpr char kFeatureUsageMetricPrefix[] = "ChromeOS.FeatureUsage.";
constexpr char kFeatureUsetimeMetricPostfix[] = ".Usetime";

std::string FeatureToHistogram(const std::string& feature_name) {
  return kFeatureUsageMetricPrefix + feature_name;
}

}  // namespace

std::optional<bool> FeatureUsageMetrics::Delegate::IsAccessible() const {
  return std::nullopt;
}

// First time periodic metrics are reported after 'kInitialInterval` time.
constexpr base::TimeDelta FeatureUsageMetrics::kInitialInterval =
    base::Minutes(1);

// Consecutive reports run every `kRepeatedInterval`
constexpr base::TimeDelta FeatureUsageMetrics::kRepeatedInterval =
    base::Minutes(30);

FeatureUsageMetrics::FeatureUsageMetrics(const std::string& feature_name,
                                         Delegate* const delegate)
    : FeatureUsageMetrics(feature_name,
                          delegate,
                          base::DefaultClock::GetInstance(),
                          base::DefaultTickClock::GetInstance()) {}

FeatureUsageMetrics::FeatureUsageMetrics(const std::string& feature_name,
                                         Delegate* const delegate,
                                         const base::Clock* clock,
                                         const base::TickClock* tick_clock)
    : histogram_name_(FeatureToHistogram(feature_name)),
      delegate_(delegate),
      clock_(clock),
      timer_(tick_clock),
      metrics_lib_(std::make_unique<MetricsLibrary>()) {
  DCHECK(delegate_);

  // Schedule the first run some time in the future to not overload startup
  // flow.
  SetupTimer(kInitialInterval);
  base::PowerMonitor::AddPowerSuspendObserver(this);
}

void FeatureUsageMetrics::SetMetricsLibraryForTesting(
    std::unique_ptr<MetricsLibraryInterface> metrics_lib) {
  metrics_lib_ = std::move(metrics_lib);
}

void FeatureUsageMetrics::SetupTimer(base::TimeDelta delta) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  timer_.Start(FROM_HERE, delta,
               base::BindOnce(&FeatureUsageMetrics::MaybeReportPeriodicMetrics,
                              base::Unretained(this)));
}

FeatureUsageMetrics::~FeatureUsageMetrics() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  base::PowerMonitor::RemovePowerSuspendObserver(this);
  MaybeReportUseTime();
}

void FeatureUsageMetrics::RecordUsage(bool success) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(delegate_->IsEligible());
  DCHECK(delegate_->IsEnabled());
  DCHECK(start_usage_.is_null());
#if DCHECK_IS_ON()
  last_record_usage_outcome_ = success;
#endif
  MaybeReportPeriodicMetrics();

  Event e = success ? Event::kUsedWithSuccess : Event::kUsedWithFailure;
  metrics_lib_->SendEnumToUMA(histogram_name_, e);
}

void FeatureUsageMetrics::RecordUsetime(base::TimeDelta usetime) const {
  metrics_lib_->SendToUMA(histogram_name_ + kFeatureUsetimeMetricPostfix,
                          usetime.InMilliseconds(),
                          base::Milliseconds(1).InMilliseconds(),
                          base::Hours(1).InMilliseconds(), 100);
}

void FeatureUsageMetrics::StartSuccessfulUsage() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(start_usage_.is_null());
#if DCHECK_IS_ON()
  DCHECK(last_record_usage_outcome_.value_or(false))
      << "Start usage must be preceded by RecordUsage(true)";
  last_record_usage_outcome_.reset();
#endif
  start_usage_ = Now();
}

void FeatureUsageMetrics::StopSuccessfulUsage() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!start_usage_.is_null());
#if DCHECK_IS_ON()
  DCHECK(!last_record_usage_outcome_.has_value())
      << "There must be no RecordUsage calls between Start and "
         "StopSuccessfulUsage";
#endif
  MaybeReportUseTime();
  start_usage_ = base::Time();
}

void FeatureUsageMetrics::OnSuspend() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  timer_.AbandonAndStop();
  ReportPeriodicMetrics();
}

void FeatureUsageMetrics::OnResume() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!start_usage_.is_null()) {
    // Do not report usage during suspension.
    start_usage_ = Now();
  }
  SetupTimer(kInitialInterval);
}

void FeatureUsageMetrics::MaybeReportPeriodicMetrics() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!last_time_enabled_reported_.is_null()) {
    const base::TimeDelta delta_since_enabled_reported =
        Now() - last_time_enabled_reported_;
    // Do not report periodic metrics more often than once per
    // `kRepeatedInterval`.
    if (kRepeatedInterval > delta_since_enabled_reported) {
      // This could only happen when `RecordUsage` is called. In that case
      // `IsEnabled` must be true. And because `last_time_enabled_reported_` is
      // not null - `IsEnabled` was already reported recently.
      SetupTimer(kRepeatedInterval - delta_since_enabled_reported);
      return;
    }
  }
  ReportPeriodicMetrics();
}

void FeatureUsageMetrics::ReportPeriodicMetrics() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  bool is_eligible = delegate_->IsEligible();
  bool is_enabled = delegate_->IsEnabled();
  DCHECK(!is_enabled || is_eligible);

  if (is_eligible) {
    metrics_lib_->SendEnumToUMA(histogram_name_, Event::kEligible);
  }

  std::optional<bool> is_accessible = delegate_->IsAccessible();

  if (is_accessible.has_value()) {
    // If accessible must be eligible.
    DCHECK(!is_accessible.value() || is_eligible);

    // If enabled must be accessible
    DCHECK(!is_enabled || is_accessible.value());

    if (is_accessible.value()) {
      metrics_lib_->SendEnumToUMA(histogram_name_, Event::kAccessible);
    }
  }

  if (is_enabled) {
    last_time_enabled_reported_ = Now();
    metrics_lib_->SendEnumToUMA(histogram_name_, Event::kEnabled);
  }

  // If the feature in the active use - it must be enabled.
  DCHECK(start_usage_.is_null() || is_enabled);
  MaybeReportUseTime();

  SetupTimer(kRepeatedInterval);
}

void FeatureUsageMetrics::MaybeReportUseTime() {
  if (start_usage_.is_null())
    return;
  base::TimeDelta use_time = Now() - start_usage_;
  RecordUsetime(use_time);
  start_usage_ = Now();
}

base::Time FeatureUsageMetrics::Now() const {
  return clock_->Now();
}

}  // namespace feature_usage
