// 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/check.h>
#include <base/files/file_path.h>
#include <base/hash/hash.h>
#include <base/strings/string_util.h>
#include <base/system/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
