// Copyright 2019 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 "kerberos/kerberos_metrics.h"

#include <utility>

#include <base/files/file_util.h>
#include <base/strings/stringprintf.h>
#include <base/time/clock.h>
#include "base/time/default_clock.h"

namespace kerberos {

namespace {

// Prefix for all UMA stats.
constexpr char kKerberos[] = "Kerberos.";

// Prefix for Kerberos.Result.<method name> stats.
constexpr char kResult[] = "Result.";

// Stat for the result of a ValidateConfig call.
constexpr char kValidateConfigErrorCode[] = "ValidateConfigErrorCode";

// Stat for counting user types, see |UserType|.
constexpr char kDailyActiveUsers[] = "DailyActiveUsers";

// Prefix for UMA stats that are counting accounts.
constexpr char kNumberOfAccounts[] = "NumberOfAccounts.";

// Stat names for counting accounts, prefixed by "Kerberos.NumberOfAccounts.".
constexpr char kTotal[] = "Total";
constexpr char kManaged[] = "Managed";
constexpr char kUnmanaged[] = "Unmanaged";
constexpr char kRememberedPassword[] = "RememberedPassword";
constexpr char kUseLoginPassword[] = "UseLoginPassword";

// Max number of accounts for UMA stats.
constexpr int kMaxAccounts = 10;

// Used to rate limit some UMA stats to once a day.
constexpr char kDailyReportTimeFile[] = "daily_report_timestamp";

// User type to be sent to Kerberos.DailyActiveUsers. These values (except
// UserType::kCount, which should be last) are persisted to logs. Entries should
// not be renumbered and numeric values should never be reused.
enum class UserType { kManaged = 0, kUnmanaged = 1, kCount = 2 };

}  // namespace

KerberosMetrics::KerberosMetrics(const base::FilePath& storage_dir)
    : kerberos_(kKerberos),
      acquire_tgt_timer_(kerberos_ + "AcquireKerberosTgtTime",
                         1 /* min 1 millisecond */,
                         20000 /* max 20 seconds */,
                         50 /* bucket count */),
      daily_report_time_path_(storage_dir.Append(kDailyReportTimeFile)),
      clock_(std::make_unique<base::DefaultClock>()) {
  chromeos_metrics::TimerReporter::set_metrics_lib(&metrics_lib_);
}

KerberosMetrics::~KerberosMetrics() {
  chromeos_metrics::TimerReporter::set_metrics_lib(nullptr);
}

void KerberosMetrics::StartAcquireTgtTimer() {
  DCHECK(!acquire_tgt_timer_.HasStarted());
  acquire_tgt_timer_.Start();
}

void KerberosMetrics::StopAcquireTgtTimerAndReport() {
  DCHECK(acquire_tgt_timer_.HasStarted());
  acquire_tgt_timer_.Stop();
  acquire_tgt_timer_.ReportMilliseconds();
}

void KerberosMetrics::ReportDBusCallResult(const char* method_name,
                                           ErrorType error) {
  metrics_lib_.SendEnumToUMA(kerberos_ + kResult + method_name,
                             static_cast<int>(error),
                             static_cast<int>(ERROR_COUNT));
}

void KerberosMetrics::ReportValidateConfigErrorCode(ConfigErrorCode code) {
  metrics_lib_.SendEnumToUMA(kerberos_ + kValidateConfigErrorCode,
                             static_cast<int>(code),
                             static_cast<int>(CONFIG_ERROR_COUNT));
}

bool KerberosMetrics::ShouldReportDailyUsageStats() {
  const base::Time now = clock_->Now();

  base::File::Info info;
  if (!base::GetFileInfo(daily_report_time_path_, &info)) {
    // Create the file. Don't skew stats if something goes wrong. Note that
    // base::TouchFile bails if the file doesn't exist!
    const bool res =
        base::WriteFile(daily_report_time_path_, nullptr, 0) == 0 &&
        base::TouchFile(daily_report_time_path_, now, now);
    if (!res)
      LOG(WARNING) << "Failed to touch " << daily_report_time_path_.value();
    return res;
  }

  // Be sure to gracefully handle the case when the clock is moved backwards.
  const base::Time last_file_time = info.last_modified;
  int days_elapsed = (now - last_file_time).InDays();
  if (days_elapsed == 0)
    return false;

  // Don't set the new file time to |now|. This would result in an average
  // frequency of less than one day.
  base::Time new_time =
      last_file_time + days_elapsed * base::TimeDelta::FromDays(1);
  const bool res = base::TouchFile(daily_report_time_path_, new_time, new_time);
  if (!res)
    LOG(WARNING) << "Failed to touch " << daily_report_time_path_.value();

  // Don't report if time goes backwards (but do reset the file time!).
  return days_elapsed > 0;
}

void KerberosMetrics::ReportDailyUsageStats(int total_count,
                                            int managed_count,
                                            int unmanaged_count,
                                            int remembered_password_count,
                                            int use_login_password_count) {
  // TODO(https://crbug.com/984552): Send the proper user type once unmanaged
  // users can use this feature.
  metrics_lib_.SendEnumToUMA(kerberos_ + kDailyActiveUsers,
                             static_cast<int>(UserType::kManaged),
                             static_cast<int>(UserType::kCount));

  SendAccountCount(kTotal, total_count);
  SendAccountCount(kManaged, managed_count);
  SendAccountCount(kUnmanaged, unmanaged_count);
  SendAccountCount(kRememberedPassword, remembered_password_count);
  SendAccountCount(kUseLoginPassword, use_login_password_count);
}

void KerberosMetrics::SetClockForTesting(std::unique_ptr<base::Clock> clock) {
  clock_ = std::move(clock);
}

void KerberosMetrics::SendAccountCount(const char* name, int count) {
  metrics_lib_.SendToUMA(kerberos_ + kNumberOfAccounts + name, count, 1,
                         kMaxAccounts, kMaxAccounts + 1);
}

}  // namespace kerberos
