/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_SRC_TIMING_LOGGER_H_
#define ART_SRC_TIMING_LOGGER_H_

#include "logging.h"
#include "utils.h"

#include <cmath>
#include <stdint.h>
#include <string>
#include <vector>

namespace art {

class CumulativeLogger;

class TimingLogger {
 public:
  explicit TimingLogger(const char* name, bool precise = false)
      : name_(name), precise_(precise) {
    AddSplit("");
  }

  void AddSplit(const std::string& label) {
    times_.push_back(NanoTime());
    labels_.push_back(label);
  }

  void Dump() const {
    Dump(LOG(INFO));
  }

  void Dump(std::ostream& os) const {
    uint64_t largest_time = 0;
    os << name_ << ": begin\n";
    for (size_t i = 1; i < times_.size(); ++i) {
      uint64_t delta_time = times_[i] - times_[i - 1];
      largest_time = std::max(largest_time, delta_time);
    }
    // Compute which type of unit we will use for printing the timings.
    TimeUnit tu = GetAppropriateTimeUnit(largest_time);
    uint64_t divisor = GetNsToTimeUnitDivisor(tu);
    for (size_t i = 1; i < times_.size(); ++i) {
      uint64_t delta_time = times_[i] - times_[i - 1];
      if (!precise_) {
        // Make the fraction 0.
        delta_time -= delta_time % divisor;
      }
      os << name_ << ": " << std::setw(8) << FormatDuration(delta_time, tu) << " " << labels_[i]
                  << "\n";
    }
    os << name_ << ": end, " << NsToMs(GetTotalNs()) << " ms\n";
  }

  uint64_t GetTotalNs() const {
    return times_.back() - times_.front();
  }

 protected:
  std::string name_;
  bool precise_;
  std::vector<uint64_t> times_;
  std::vector<std::string> labels_;

  friend class CumulativeLogger;
};

class CumulativeLogger {
 public:
  explicit CumulativeLogger(const char* name = "", bool precise = false)
    : name_(name),
      precise_(precise),
      total_time_squared_(0),
      index_(0),
      iterations_(0),
      last_split_(0) {

  }

  void Start() {
    index_ = 0;
    last_split_ = NanoTime();
  }

  void End() {
    iterations_++;
  }

  void AddSplit(const std::string& label) {
    uint64_t cur_time = NanoTime();
    AddPair(label, cur_time - last_split_);
    last_split_ = cur_time;
  }

  void Reset() {
    iterations_ = 0;
    times_.clear();
    labels_.clear();
    times_squared_.clear();
  }

  void AddPair(const std::string& label, uint64_t delta_time) {
    // Convert delta time to microseconds so that we don't overflow our counters.
    delta_time /= kAdjust;
    if (index_ >= times_.size()) {
      times_.push_back(delta_time);
      times_squared_.push_back(delta_time * delta_time);
      labels_.push_back(label);
    } else {
      times_[index_] += delta_time;
      times_squared_[index_] += delta_time * delta_time;
      DCHECK_EQ(labels_[index_], label);
    }
    index_++;
  }

  void AddLogger(const TimingLogger& logger) {
    DCHECK_EQ(logger.times_.size(), logger.labels_.size());
    uint64_t total_time = 0;
    for (size_t i = 1; i < logger.times_.size(); ++i) {
      const uint64_t delta_time = logger.times_[i] - logger.times_[i - 1];
      const std::string& label = logger.labels_[i];
      AddPair(label, delta_time);
      total_time += delta_time;
    }
    total_time /= kAdjust;
    total_time_squared_ += total_time * total_time;
  }

  void Dump() const {
    Dump(LOG(INFO));
  }

  void Dump(std::ostream& os) const {
    os << name_ << ": iterations " << iterations_ << " begin\n";
    //Find which unit we will use for the timing logger.
    uint64_t largest_mean = 0;
    for (size_t i = 0; i < times_.size(); ++i) {
      // Convert back to nanoseconds from microseconds.
      uint64_t mean = times_[i] / iterations_;
      largest_mean = std::max(largest_mean, mean);
    }
    // Convert largest mean back to ns
    TimeUnit tu = GetAppropriateTimeUnit(largest_mean * kAdjust);
    uint64_t divisor = GetNsToTimeUnitDivisor(tu);
    for (size_t i = 0; i < times_.size(); ++i) {
      uint64_t mean_x2 = times_squared_[i] / iterations_;
      uint64_t mean = times_[i] / iterations_;
      uint64_t variance = mean_x2 - (mean * mean);
      uint64_t std_dev = static_cast<uint64_t>(std::sqrt(static_cast<double>(variance)));
      if (!precise_) {
        // Make the fraction 0.
        mean -= mean % divisor;
        std_dev -= std_dev % divisor;
      }
      os << name_ << ": " << std::setw(8)
         << FormatDuration(mean * kAdjust, tu) << " std_dev "
         << FormatDuration(std_dev * kAdjust, tu) << " " << labels_[i] << "\n";
    }
    uint64_t total_mean_x2 = total_time_squared_;
    uint64_t mean_total_ns = GetTotalNs();
    if (iterations_ != 0) {
      total_mean_x2 /= iterations_;
      mean_total_ns /= iterations_;
    }
    uint64_t total_variance = total_mean_x2 - (mean_total_ns * mean_total_ns);
    uint64_t total_std_dev = static_cast<uint64_t>(
        std::sqrt(static_cast<double>(total_variance)));
    os << name_ << ": end, mean " << PrettyDuration(mean_total_ns * kAdjust)
       << " std_dev " << PrettyDuration(total_std_dev * kAdjust) << "\n";
  }

  uint64_t GetTotalNs() const {
    uint64_t total = 0;
    for (size_t i = 0; i < times_.size(); ++i) {
      total += times_[i];
    }
    return total;
  }

 private:
  static const uint64_t kAdjust = 1000;
  std::string name_;
  bool precise_;
  uint64_t total_time_squared_;
  std::vector<uint64_t> times_;
  std::vector<uint64_t> times_squared_;
  std::vector<std::string> labels_;
  size_t index_;
  size_t iterations_;
  uint64_t last_split_;
};

}  // namespace art

#endif  // ART_SRC_TIMING_LOGGER_H_
