// Copyright 2018 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 "metrics/cumulative_metrics.h"

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/strings/string_util.h>
#include <base/sys_info.h>
#include <memory>
#include <utility>

using base::FilePath;
using base::Time;

namespace chromeos_metrics {
namespace {

constexpr char kValidNameCharacters[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789_.";

}  // namespace

CumulativeMetrics::CumulativeMetrics(const FilePath& backing_dir,
                                     const std::vector<std::string>& names,
                                     base::TimeDelta update_period,
                                     Callback update_callback,
                                     base::TimeDelta accumulation_period,
                                     Callback cycle_end_callback)
    : backing_dir_(backing_dir),
      update_period_(update_period),
      accumulation_period_(accumulation_period) {
  int64_t new_version_hash = 0;

  PersistentInteger persistent_version_hash(backing_dir.Append("version.hash"));
  update_callback_ = std::move(update_callback);
  cycle_end_callback_ = std::move(cycle_end_callback);

  cycle_start_.reset(new PersistentInteger(backing_dir.Append("cycle.start")));
  last_update_time_ = base::TimeTicks::Now();

  // Associate |names| with accumulated values (which may already exist from
  // previous sessions).
  for (const auto& name : names) {
    CHECK(base::ContainsOnlyChars(name, kValidNameCharacters))
        << "bad cumulative metrics name \"" << name << "\"";
    values_.emplace(
        name, std::make_unique<PersistentInteger>(backing_dir.Append(name)));
  }

  // Check version hash.  This only needs to happen at init time because we
  // assume that the OS version cannot be bumped without restarting the daemon.
  std::string version;
  if (base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_VERSION", &version)) {
    new_version_hash = base::Hash(version);
  } else {
    LOG(ERROR) << "cannot find CHROMEOS_RELEASE_VERSION";
  }

  // Check if current cycle has expired.
  bool new_cycle_has_started = ProcessCycleEnd();

  // On a version change that's not at the end of a cycle, discard the
  // currently accumulating quantities, because the samples would be incorrect.
  // Then start a new cycle.
  int64_t old_version_hash = persistent_version_hash.Get();

  if (old_version_hash != new_version_hash) {
    persistent_version_hash.Set(new_version_hash);
    if (!new_cycle_has_started) {
      // OS version has changed.  Reset accumulators.
      for (const auto& kv : values_) {
        kv.second->GetAndClear();
      }
      // Reset start time.
      base::TimeDelta wall_time = Time::Now() - Time::UnixEpoch();
      cycle_start_->Set(wall_time.InMicroseconds());
    }
  }

  timer_.Start(FROM_HERE, update_period_, this, &CumulativeMetrics::Update);
}

bool CumulativeMetrics::ProcessCycleEnd() {
  base::TimeDelta wall_time = Time::Now() - Time::UnixEpoch();
  base::TimeDelta cycle_start =
      base::TimeDelta::FromMicroseconds(cycle_start_->Get());
  if (wall_time - cycle_start > accumulation_period_) {
    cycle_start_->Set(wall_time.InMicroseconds());
    return true;
  }
  return false;
}

base::TimeDelta CumulativeMetrics::ActiveTimeSinceLastUpdate() const {
  return base::TimeTicks::Now() - last_update_time_;
}

void CumulativeMetrics::Update() {
  update_callback_.Run(this);

  if (ProcessCycleEnd()) {
    cycle_end_callback_.Run(this);
    for (const auto& kv : values_) {
      kv.second->GetAndClear();
    }
  }

  last_update_time_ = base::TimeTicks::Now();
}

void CumulativeMetrics::PanicFromBadName(const char* action,
                                         const std::string& name) const {
  LOG(FATAL) << "cannot execute action \"" << action << "\": unknown name \""
             << name << "\"";
}

PersistentInteger* CumulativeMetrics::Find(const std::string& name) const {
  const auto iter = values_.find(name);
  if (iter == values_.end())
    return nullptr;
  return iter->second.get();
}

int64_t CumulativeMetrics::Get(const std::string& name) const {
  PersistentInteger* pip = Find(name);
  if (pip != nullptr)
    return pip->Get();
  PanicFromBadName("GET", name);
  return 0;
}

void CumulativeMetrics::Set(const std::string& name, int64_t value) {
  PersistentInteger* pip = Find(name);
  if (pip != nullptr) {
    pip->Set(value);
  } else {
    PanicFromBadName("SET", name);
  }
}

void CumulativeMetrics::Add(const std::string& name, int64_t value) {
  PersistentInteger* pip = Find(name);
  if (pip != nullptr) {
    pip->Add(value);
  } else {
    PanicFromBadName("ADD", name);
  }
}

void CumulativeMetrics::Max(const std::string& name, int64_t value) {
  PersistentInteger* pip = Find(name);
  if (pip != nullptr) {
    pip->Max(value);
  } else {
    PanicFromBadName("MAX", name);
  }
}

int64_t CumulativeMetrics::GetAndClear(const std::string& name) {
  PersistentInteger* pip = Find(name);
  if (pip != nullptr)
    return pip->GetAndClear();
  PanicFromBadName("GETANDCLEAR", name);
  return 0;
}

}  // namespace chromeos_metrics
