// Copyright 2016 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 "login_manager/cumulative_use_time_metric.h"

#include <limits>

#include <base/bind.h>
#include <base/files/file_util.h>
#include <base/hash.h>
#include <base/json/json_reader.h>
#include <base/json/json_writer.h>
#include <base/values.h>
#include <metrics/metrics_library.h>

namespace login_manager {

namespace {

// Time interval between cumulative use time metric updates.
const int kMetricsUpdateIntervalSeconds = 5 * 60;

// Used to calculate max size of accumulated seconds per UMA upload, which is
// needed to define histogram parameters.
const int kSecondsInADay = 24 * 60 * 60;

// Constants used for the UMA metric representing the accumulated usage time:
const int kAccumulatedActiveTimeBucketCount = 50;
const int kAccumulatedActiveTimeMin = 1;
// Set to expected max time sent to UMA - usage values are sent only if it is
// detected that day index (amount of time in days since base::Time::UnixEpoch)
// has changed at the time metric value is updated. So max elapsed time since
// last update is seconds in a day + metric update interval.
const int kAccumulatedActiveTimeMax =
    kSecondsInADay + kMetricsUpdateIntervalSeconds;

// This should be enough for writing JSON file containing information about
// usage time metric (can be increased if needed).
const size_t kMetricFileSizeLimit = 1024;

// File extension that should be used for the file backing cumulative use time
// metric.
const char kMetricFileExtension[] = "json";

// Keys for for usage metric parameters in the JSON saved in the metrics file.
const char kOsVersionHashKey[] = "os_version_hash";
const char kStartDayKey[] = "start_day";
const char kElapsedMillisecondsKey[] = "elapsed_milliseconds";

}  // namespace

class CumulativeUseTimeMetric::AccumulatedActiveTime {
 public:
  explicit AccumulatedActiveTime(const base::FilePath& metrics_file);

  base::FilePath metrics_file() const { return metrics_file_; }

  base::TimeDelta accumulated_time() const { return accumulated_time_; }

  int start_day() const { return start_day_; }

  // Loads previously persisted metric info from disk and checks if the loaded
  // OS version hash matches |os_version_hash|. If the OS version hashes don't
  // match, resets the accumulated time value and sets the new OS version hash.
  void Init(int os_version_hash);

  // Increases current accumulated usage time by |time|.
  void AddTime(const base::TimeDelta& time);

  // Sets accumulated usage time to |remaining_time|. Sets usage start day to
  // |day|.
  void Reset(const base::TimeDelta& remaining_time, int day);

 private:
  // Methods used to sync usage time parameters to file system.
  bool ReadMetricsFile();
  bool WriteMetricsFile();

  // File path of the file to which current metric info is saved in order to
  // persist metric value across reboots.
  const base::FilePath metrics_file_;

  // Hash of the OS version on which current usage time was accumulated.
  int os_version_hash_{0};

  // Current accumulated usage time.
  base::TimeDelta accumulated_time_;

  // ID of the day on which accumulating current usage time started.
  // The day id is the number of 24-hour periods that passed from
  // Time::UnixEpoch() (though, this class does not directly depend on this).
  int start_day_{0};

  DISALLOW_COPY_AND_ASSIGN(AccumulatedActiveTime);
};

CumulativeUseTimeMetric::AccumulatedActiveTime::AccumulatedActiveTime(
    const base::FilePath& metrics_file) : metrics_file_(metrics_file) {
}

void CumulativeUseTimeMetric::AccumulatedActiveTime::Init(int os_version_hash) {
  // Read persisted metric data and then compare read OS version hash to
  // |os_version_hash|. If the hashes do not match (or metric file could not be
  // read), accumulated usage time should be reset - the goal of this is to
  // avoid usage time from before version update to be reported as part of the
  // current version usage.
  if (ReadMetricsFile() && os_version_hash == os_version_hash_)
    return;

  os_version_hash_ = os_version_hash;

  // Note that these have to be reset even if reading metric file failed (as
  // some data might have been partially read).
  Reset(base::TimeDelta(), 0);
}

void CumulativeUseTimeMetric::AccumulatedActiveTime::AddTime(
    const base::TimeDelta& time) {
  if (time.is_zero())
    return;

  accumulated_time_ += time;
  WriteMetricsFile();
}

void CumulativeUseTimeMetric::AccumulatedActiveTime::Reset(
    const base::TimeDelta& remaining_time, int day) {
  accumulated_time_ = remaining_time;
  start_day_ = day;
  WriteMetricsFile();
}

bool CumulativeUseTimeMetric::AccumulatedActiveTime::ReadMetricsFile() {
  std::string data_json;
  if (!base::ReadFileToStringWithMaxSize(metrics_file_, &data_json,
                                         kMetricFileSizeLimit)) {
    return false;
  }

  std::unique_ptr<base::Value> data_value(base::JSONReader::Read(data_json));
  if (!data_value.get()) {
    LOG(ERROR) << "Contents of " << metrics_file_.value() << " invalid JSON";
    return false;
  }

  const base::DictionaryValue* data = nullptr;
  if (!data_value->GetAsDictionary(&data)) {
    LOG(ERROR) << "Content of " << metrics_file_.value() << " not a dictionary";
    return false;
  }

  if (!data->GetInteger(kOsVersionHashKey, &os_version_hash_)) {
    LOG(ERROR) << "OS version hash missing in " << metrics_file_.value();
    return false;
  }

  if (!data->GetInteger(kStartDayKey, &start_day_)) {
    LOG(ERROR) << "Start day missing in " << metrics_file_.value();
    return false;
  }

  int elapsed_milliseconds = 0;
  if (!data->GetInteger(kElapsedMillisecondsKey, &elapsed_milliseconds)) {
    LOG(ERROR) << "Elapsed milliseconds missing in " << metrics_file_.value();
    return false;
  }
  accumulated_time_ = base::TimeDelta::FromMilliseconds(elapsed_milliseconds);
  return true;
}

bool CumulativeUseTimeMetric::AccumulatedActiveTime::WriteMetricsFile() {
  base::DictionaryValue data;
  data.SetInteger(kOsVersionHashKey, os_version_hash_);
  data.SetInteger(kStartDayKey, start_day_);
  int64_t elapsed_milliseconds = accumulated_time_.InMilliseconds();
  if (elapsed_milliseconds < 0 ||
      elapsed_milliseconds > std::numeric_limits<int>::max()) {
    LOG(ERROR) << "Elapsed milliseconds not in int bounds: "
               << elapsed_milliseconds;
    // Something is wrong here. Reset the stored amount.
    accumulated_time_ = base::TimeDelta();
    elapsed_milliseconds = 0;
  }
  data.SetInteger(kElapsedMillisecondsKey,
                  static_cast<int>(elapsed_milliseconds));

  std::string data_json;
  if (!base::JSONWriter::Write(data, &data_json)) {
    LOG(ERROR) << "Failed to create JSON string for " << data;
    return false;
  }

  int data_size = data_json.size();
  if (base::WriteFile(metrics_file_, data_json.data(), data_size) !=
          data_size) {
    LOG(ERROR) << "Failed to write metric data to " << metrics_file_.value();
    return false;
  }

  return true;
}

CumulativeUseTimeMetric::CumulativeUseTimeMetric(
    const std::string& metric_name,
    MetricsLibraryInterface* metrics_lib,
    const base::FilePath& metrics_files_dir,
    std::unique_ptr<base::Clock> time_clock,
    std::unique_ptr<base::TickClock> time_tick_clock)
    : metrics_lib_(metrics_lib),
      metric_name_(metric_name),
      accumulated_active_time_(
          new AccumulatedActiveTime(
              metrics_files_dir.AppendASCII(metric_name_)
                               .AddExtension(kMetricFileExtension))),
      time_clock_(std::move(time_clock)),
      time_tick_clock_(std::move(time_tick_clock)) {
}

CumulativeUseTimeMetric::~CumulativeUseTimeMetric() {}

void CumulativeUseTimeMetric::Init(const std::string& os_version_string) {
  accumulated_active_time_->Init(
      static_cast<int>(base::Hash(os_version_string)));

  // Test if there is any persisted accumulated data that should be sent to UMA.
  IncreaseActiveTimeAndSendUmaIfNeeded(base::TimeDelta());

  initialized_ = true;
}

void CumulativeUseTimeMetric::Start() {
  CHECK(initialized_);

  last_update_time_ = time_tick_clock_->NowTicks();
  IncreaseActiveTimeAndSendUmaIfNeeded(base::TimeDelta());

  // Timer will be stopped when this goes out of scope, so Unretained is safe.
  update_stats_timer_.Start(
      FROM_HERE,
      base::TimeDelta::FromSeconds(kMetricsUpdateIntervalSeconds),
      base::Bind(&CumulativeUseTimeMetric::UpdateStats,
                 base::Unretained(this)));
}

void CumulativeUseTimeMetric::Stop() {
  CHECK(initialized_);
  if (!last_update_time_.is_null())
    UpdateStats();

  update_stats_timer_.Stop();
  last_update_time_ = base::TimeTicks();
}

base::TimeDelta CumulativeUseTimeMetric::GetMetricsUpdateCycle() const {
  return base::TimeDelta::FromSeconds(kMetricsUpdateIntervalSeconds);
}

base::TimeDelta CumulativeUseTimeMetric::GetMetricsUploadCycle() const {
  return base::TimeDelta::FromSeconds(kSecondsInADay);
}

base::FilePath CumulativeUseTimeMetric::GetMetricsFileForTest() const {
  return accumulated_active_time_->metrics_file();
}

void CumulativeUseTimeMetric::UpdateStats() {
  base::TimeTicks now = time_tick_clock_->NowTicks();
  const base::TimeDelta elapsed_time = now - last_update_time_;
  last_update_time_ = now;

  IncreaseActiveTimeAndSendUmaIfNeeded(elapsed_time);
}

void CumulativeUseTimeMetric::IncreaseActiveTimeAndSendUmaIfNeeded(
    const base::TimeDelta& additional_time) {
  const int day = (time_clock_->Now() - base::Time::UnixEpoch()).InDays();
  // If not enough time has passed since the metric was last sent, just update
  // the time.
  if (accumulated_active_time_->start_day() == day) {
    accumulated_active_time_->AddTime(additional_time);
    return;
  }

  // If metric has not previously been set, do it now, and make sure initial
  // update is not sent to UMA.
  if (accumulated_active_time_->start_day() == 0 &&
          accumulated_active_time_->accumulated_time().is_zero()) {
    accumulated_active_time_->Reset(additional_time, day);
    return;
  }

  base::TimeDelta accumulated_time =
      accumulated_active_time_->accumulated_time() + additional_time;
  int seconds_to_send = accumulated_time.InSeconds();

  // Avoid sending 0 values to UMA.
  if (seconds_to_send != 0) {
    metrics_lib_->SendToUMA(metric_name_,
                            seconds_to_send,
                            kAccumulatedActiveTimeMin,
                            kAccumulatedActiveTimeMax,
                            kAccumulatedActiveTimeBucketCount);
  }

  // Keep any data unreported due to rounding time to seconds, and set the time
  // accumulation start day to the new value.
  accumulated_active_time_->Reset(
      accumulated_time - base::TimeDelta::FromSeconds(seconds_to_send), day);
}

}  // namespace login_manager
