// 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 <utility>

#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;
  }

  // TODO(crbug.com/1054279): use base::JSONReader::ReadDeprecated after uprev
  // to r680000.
  std::unique_ptr<base::Value> data_value(
      base::JSONReader::ReadDeprecated(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
