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

  auto data_value = base::JSONReader::Read(data_json, base::JSON_PARSE_RFC);
  if (!data_value) {
    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
