/*
 * Copyright (C) 2020 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_LIBARTBASE_BASE_METRICS_METRICS_H_
#define ART_LIBARTBASE_BASE_METRICS_METRICS_H_

#include <stdint.h>

#include <array>
#include <atomic>
#include <optional>
#include <sstream>
#include <string_view>
#include <thread>
#include <vector>

#include "android-base/logging.h"
#include "base/bit_utils.h"
#include "base/macros.h"
#include "base/time_utils.h"
#include "tinyxml2.h"

#pragma clang diagnostic push
#pragma clang diagnostic error "-Wconversion"

// See README.md in this directory for how to define metrics.

// Metrics reported as Event Metrics.
#define ART_EVENT_METRICS(METRIC)                                   \
  METRIC(ClassLoadingTotalTime, MetricsCounter)                     \
  METRIC(ClassVerificationTotalTime, MetricsCounter)                \
  METRIC(ClassVerificationCount, MetricsCounter)                    \
  METRIC(WorldStopTimeDuringGCAvg, MetricsAverage)                  \
  METRIC(YoungGcCount, MetricsCounter)                              \
  METRIC(FullGcCount, MetricsCounter)                               \
  METRIC(TotalBytesAllocated, MetricsCounter)                       \
  METRIC(TotalGcCollectionTime, MetricsCounter)                     \
  METRIC(YoungGcThroughputAvg, MetricsAverage)                      \
  METRIC(FullGcThroughputAvg, MetricsAverage)                       \
  METRIC(YoungGcTracingThroughputAvg, MetricsAverage)               \
  METRIC(FullGcTracingThroughputAvg, MetricsAverage)                \
  METRIC(JitMethodCompileTotalTime, MetricsCounter)                 \
  METRIC(JitMethodCompileCount, MetricsCounter)                     \
  METRIC(YoungGcCollectionTime, MetricsHistogram, 15, 0, 60'000)    \
  METRIC(FullGcCollectionTime, MetricsHistogram, 15, 0, 60'000)     \
  METRIC(YoungGcThroughput, MetricsHistogram, 15, 0, 10'000)        \
  METRIC(FullGcThroughput, MetricsHistogram, 15, 0, 10'000)         \
  METRIC(YoungGcTracingThroughput, MetricsHistogram, 15, 0, 10'000) \
  METRIC(FullGcTracingThroughput, MetricsHistogram, 15, 0, 10'000)  \
  METRIC(GcWorldStopTime, MetricsCounter)                           \
  METRIC(GcWorldStopCount, MetricsCounter)                          \
  METRIC(YoungGcScannedBytes, MetricsCounter)                       \
  METRIC(YoungGcFreedBytes, MetricsCounter)                         \
  METRIC(YoungGcDuration, MetricsCounter)                           \
  METRIC(FullGcScannedBytes, MetricsCounter)                        \
  METRIC(FullGcFreedBytes, MetricsCounter)                          \
  METRIC(FullGcDuration, MetricsCounter)

// Increasing counter metrics, reported as Value Metrics in delta increments.
#define ART_VALUE_METRICS(METRIC)                              \
  METRIC(GcWorldStopTimeDelta, MetricsDeltaCounter)            \
  METRIC(GcWorldStopCountDelta, MetricsDeltaCounter)           \
  METRIC(YoungGcScannedBytesDelta, MetricsDeltaCounter)        \
  METRIC(YoungGcFreedBytesDelta, MetricsDeltaCounter)          \
  METRIC(YoungGcDurationDelta, MetricsDeltaCounter)            \
  METRIC(FullGcScannedBytesDelta, MetricsDeltaCounter)         \
  METRIC(FullGcFreedBytesDelta, MetricsDeltaCounter)           \
  METRIC(FullGcDurationDelta, MetricsDeltaCounter)             \
  METRIC(JitMethodCompileTotalTimeDelta, MetricsDeltaCounter)  \
  METRIC(JitMethodCompileCountDelta, MetricsDeltaCounter)      \
  METRIC(ClassVerificationTotalTimeDelta, MetricsDeltaCounter) \
  METRIC(ClassVerificationCountDelta, MetricsDeltaCounter)     \
  METRIC(ClassLoadingTotalTimeDelta, MetricsDeltaCounter)      \
  METRIC(TotalBytesAllocatedDelta, MetricsDeltaCounter)        \
  METRIC(TotalGcCollectionTimeDelta, MetricsDeltaCounter)      \
  METRIC(YoungGcCountDelta, MetricsDeltaCounter)               \
  METRIC(FullGcCountDelta, MetricsDeltaCounter)                \
  METRIC(TimeElapsedDelta, MetricsDeltaCounter)

#define ART_METRICS(METRIC) \
  ART_EVENT_METRICS(METRIC) \
  ART_VALUE_METRICS(METRIC)

// A lot of the metrics implementation code is generated by passing one-off macros into ART_COUNTERS
// and ART_HISTOGRAMS. This means metrics.h and metrics.cc are very #define-heavy, which can be
// challenging to read. The alternative was to require a lot of boilerplate code for each new metric
// added, all of which would need to be rewritten if the metrics implementation changed. Using
// macros lets us add new metrics by adding a single line to either ART_COUNTERS or ART_HISTOGRAMS,
// and modifying the implementation only requires changing the implementation once, instead of once
// per metric.

namespace art {

class Runtime;
struct RuntimeArgumentMap;

namespace metrics {
template <typename value_t>
class MetricsBase;
}  // namespace metrics

namespace gc {
class HeapTest_GCMetrics_Test;
}  // namespace gc

namespace metrics {

/**
 * An enumeration of all ART counters and histograms.
 */
enum class DatumId {
#define METRIC(name, type, ...) k##name,
  ART_METRICS(METRIC)
#undef METRIC
};

// Names come from PackageManagerServiceCompilerMapping.java
#define REASON_NAME_LIST(V)                                               \
  V(kError, "error")                                                      \
  V(kUnknown, "unknown")                                                  \
  V(kFirstBoot, "first-boot")                                             \
  V(kBootAfterOTA, "boot-after-ota")                                      \
  V(kPostBoot, "post-boot")                                               \
  V(kInstall, "install")                                                  \
  V(kInstallFast, "install-fast")                                         \
  V(kInstallBulk, "install-bulk")                                         \
  V(kInstallBulkSecondary, "install-bulk-secondary")                      \
  V(kInstallBulkDowngraded, "install-bulk-downgraded")                    \
  V(kInstallBulkSecondaryDowngraded, "install-bulk-secondary-downgraded") \
  V(kBgDexopt, "bg-dexopt")                                               \
  V(kABOTA, "ab-ota")                                                     \
  V(kInactive, "inactive")                                                \
  V(kShared, "shared")                                                    \
  V(kInstallWithDexMetadata, "install-with-dex-metadata")                 \
  V(kPrebuilt, "prebuilt")                                                \
  V(kCmdLine, "cmdline")                                                  \
  V(kVdex, "vdex")                                                        \
  V(kBootAfterMainlineUpdate, "boot-after-mainline-update")

// We log compilation reasons as part of the metadata we report. Since elsewhere compilation reasons
// are specified as a string, we define them as an enum here which indicates the reasons that we
// support.
enum class CompilationReason {
#define REASON(kind, name) kind,
  REASON_NAME_LIST(REASON)
#undef REASON
};

#define REASON_NAME(kind, kind_name) \
    case CompilationReason::kind: return kind_name;
#define REASON_FROM_NAME(kind, kind_name) \
    if (name == (kind_name)) { return CompilationReason::kind; }

constexpr const char* CompilationReasonName(CompilationReason reason) {
  switch (reason) {
    REASON_NAME_LIST(REASON_NAME)
  }
}

constexpr CompilationReason CompilationReasonFromName(std::string_view name) {
  REASON_NAME_LIST(REASON_FROM_NAME)
  return CompilationReason::kError;
}

#undef REASON_NAME
#undef REASON_FROM_NAME

#define COMPILER_FILTER_REPORTING_LIST(V) \
  V(kError, "error") /* Error (invalid value) condition */ \
  V(kUnknown, "unknown") /* Unknown (not set) condition */ \
  V(kAssumeVerified, "assume-verified") /* Standard compiler filters */ \
  V(kExtract, "extract") \
  V(kVerify, "verify") \
  V(kSpaceProfile, "space-profile") \
  V(kSpace, "space") \
  V(kSpeedProfile, "speed-profile") \
  V(kSpeed, "speed") \
  V(kEverythingProfile, "everything-profile") \
  V(kEverything, "everything") \
  V(kRunFromApk, "run-from-apk") /* Augmented compiler filters as produces by OatFileAssistant#GetOptimizationStatus */ \
  V(kRunFromApkFallback, "run-from-apk-fallback")

// Augmented compiler filter enum, used in the reporting infra.
enum class CompilerFilterReporting {
#define FILTER(kind, name) kind,
  COMPILER_FILTER_REPORTING_LIST(FILTER)
#undef FILTER
};

#define FILTER_NAME(kind, kind_name) \
    case CompilerFilterReporting::kind: return kind_name;
#define FILTER_FROM_NAME(kind, kind_name) \
    if (name == (kind_name)) { return CompilerFilterReporting::kind; }

constexpr const char* CompilerFilterReportingName(CompilerFilterReporting filter) {
  switch (filter) {
    COMPILER_FILTER_REPORTING_LIST(FILTER_NAME)
  }
}

constexpr CompilerFilterReporting CompilerFilterReportingFromName(std::string_view name) {
  COMPILER_FILTER_REPORTING_LIST(FILTER_FROM_NAME)
  return CompilerFilterReporting::kError;
}

#undef FILTER_NAME
#undef FILTER_FROM_NAME

// SessionData contains metadata about a metrics session (basically the lifetime of an ART process).
// This information should not change for the lifetime of the session.
struct SessionData {
  static SessionData CreateDefault();

  static constexpr int64_t kInvalidSessionId = -1;
  static constexpr int32_t kInvalidUserId = -1;

  int64_t session_id;
  int32_t uid;
  CompilationReason compilation_reason;
  CompilerFilterReporting compiler_filter;
};

// MetricsBackends are used by a metrics reporter to write metrics to some external location. For
// example, a backend might write to logcat, or to a file, or to statsd.
class MetricsBackend {
 public:
  virtual ~MetricsBackend() {}

  // Begins an ART metrics session.
  //
  // This is called by the metrics reporter when the runtime is starting up. The session_data
  // includes a session id which is used to correlate any metric reports with the same instance of
  // the ART runtime. Additionally, session_data includes useful metadata such as the package name
  // for this process.
  //
  // It may also be called whenever there is an update to the session metadata (e.g. optimization
  // state).
  virtual void BeginOrUpdateSession(const SessionData& session_data) = 0;

 protected:
  // Called by the metrics reporter to indicate that a new metrics report is starting.
  virtual void BeginReport(uint64_t timestamp_since_start_ms) = 0;

  // Called by the metrics reporter to give the current value of the counter with id counter_type.
  //
  // This will be called multiple times for each counter based on when the metrics reporter chooses
  // to report metrics. For example, the metrics reporter may call this at shutdown or every N
  // minutes. Counters are not reset in between invocations, so the value should represent the
  // total count at the point this method is called.
  virtual void ReportCounter(DatumId counter_type, uint64_t value) = 0;

  // Called by the metrics reporter to report a histogram.
  //
  // This is called similarly to ReportCounter, but instead of receiving a single value, it receives
  // a vector of the value in each bucket. Additionally, the function receives the lower and upper
  // limit for the histogram. Note that these limits are the allowed limits, and not the observed
  // range. Values below the lower limit will be counted in the first bucket, and values above the
  // upper limit will be counted in the last bucket. Backends should store the minimum and maximum
  // values to allow comparisons across module versions, since the minimum and maximum values may
  // change over time.
  virtual void ReportHistogram(DatumId histogram_type,
                               int64_t minimum_value,
                               int64_t maximum_value,
                               const std::vector<uint32_t>& buckets) = 0;

  // Called by the metrics reporter to indicate that the current metrics report is complete.
  virtual void EndReport() = 0;

  template <DatumId counter_type, typename T>
  friend class MetricsCounter;
  template <DatumId counter_type, typename T>
  friend class MetricsDeltaCounter;
  template <DatumId histogram_type, size_t num_buckets, int64_t low_value, int64_t high_value>
  friend class MetricsHistogram;
  template <DatumId datum_id, typename T, const T& AccumulatorFunction(const T&, const T&)>
  friend class MetricsAccumulator;
  template <DatumId datum_id, typename T>
  friend class MetricsAverage;
  friend class ArtMetrics;
};

template <typename value_t>
class MetricsBase {
 public:
  virtual void Add(value_t value) = 0;
  virtual ~MetricsBase() { }

 private:
  // Is the metric "null", i.e. never updated or freshly reset?
  // Used for testing purpose only.
  virtual bool IsNull() const = 0;

  ART_FRIEND_TEST(gc::HeapTest, GCMetrics);
};

template <DatumId counter_type, typename T = uint64_t>
class MetricsCounter : public MetricsBase<T> {
 public:
  using value_t = T;
  explicit constexpr MetricsCounter(uint64_t value = 0) : value_{value} {
    // Ensure we do not have any unnecessary data in this class.
    // Adding intptr_t to accommodate vtable, and rounding up to incorporate
    // padding.
    static_assert(RoundUp(sizeof(*this), sizeof(uint64_t))
                  == RoundUp(sizeof(intptr_t) + sizeof(value_t), sizeof(uint64_t)));
  }

  void AddOne() { Add(1u); }
  void Add(value_t value) override {
    value_.fetch_add(value, std::memory_order::memory_order_relaxed);
  }

  void Report(const std::vector<MetricsBackend*>& backends) const {
    for (MetricsBackend* backend : backends) {
      backend->ReportCounter(counter_type, Value());
    }
  }

 protected:
  void Reset() { value_ = 0; }
  value_t Value() const { return value_.load(std::memory_order::memory_order_relaxed); }

 private:
  bool IsNull() const override { return Value() == 0; }

  std::atomic<value_t> value_;
  static_assert(std::atomic<value_t>::is_always_lock_free);

  friend class ArtMetrics;
};

template <DatumId datum_id, typename T = uint64_t>
class MetricsAverage final : public MetricsCounter<datum_id, T> {
 public:
  using value_t = T;
  using count_t = T;
  explicit constexpr MetricsAverage(uint64_t value = 0, uint64_t count = 0) :
      MetricsCounter<datum_id, value_t>(value), count_(count) {
    // Ensure we do not have any unnecessary data in this class.
    // Adding intptr_t to accommodate vtable, and rounding up to incorporate
    // padding.
    static_assert(RoundUp(sizeof(*this), sizeof(uint64_t))
                  == RoundUp(sizeof(intptr_t) + sizeof(value_t) + sizeof(count_t),
                             sizeof(uint64_t)));
  }

  // We use release memory-order here and then acquire in Report() to ensure
  // that at least the non-racy reads/writes to this metric are consistent. This
  // doesn't guarantee the atomicity of the change to both fields, but that
  // may not be desired because:
  // 1. The metric eventually becomes consistent.
  // 2. For sufficiently large count_, a few data points which are off shouldn't
  // make a huge difference to the reporter.
  void Add(value_t value) override {
    MetricsCounter<datum_id, value_t>::Add(value);
    count_.fetch_add(1, std::memory_order::memory_order_release);
  }

  void Report(const std::vector<MetricsBackend*>& backends) const {
    count_t value = MetricsCounter<datum_id, value_t>::Value();
    count_t count = count_.load(std::memory_order::memory_order_acquire);
    // Avoid divide-by-0.
    count_t average_value = count != 0 ? value / count : 0;
    for (MetricsBackend* backend : backends) {
      backend->ReportCounter(datum_id, average_value);
    }
  }

 protected:
  void Reset() {
    count_ = 0;
    MetricsCounter<datum_id, value_t>::Reset();
  }

 private:
  count_t Count() const { return count_.load(std::memory_order::memory_order_relaxed); }

  bool IsNull() const override { return Count() == 0; }

  std::atomic<count_t> count_;
  static_assert(std::atomic<count_t>::is_always_lock_free);

  friend class ArtMetrics;
};

template <DatumId datum_id, typename T = uint64_t>
class MetricsDeltaCounter : public MetricsBase<T> {
 public:
  using value_t = T;

  explicit constexpr MetricsDeltaCounter(uint64_t value = 0) : value_{value} {
    // Ensure we do not have any unnecessary data in this class.
    // Adding intptr_t to accommodate vtable, and rounding up to incorporate
    // padding.
    static_assert(RoundUp(sizeof(*this), sizeof(uint64_t)) ==
                  RoundUp(sizeof(intptr_t) + sizeof(value_t), sizeof(uint64_t)));
  }

  void Add(value_t value) override {
    value_.fetch_add(value, std::memory_order::memory_order_relaxed);
  }
  void AddOne() { Add(1u); }

  void ReportAndReset(const std::vector<MetricsBackend*>& backends) {
    value_t value = value_.exchange(0, std::memory_order::memory_order_relaxed);
    for (MetricsBackend* backend : backends) {
      backend->ReportCounter(datum_id, value);
    }
  }

  void Reset() { value_ = 0; }

 private:
  value_t Value() const { return value_.load(std::memory_order::memory_order_relaxed); }

  bool IsNull() const override { return Value() == 0; }

  std::atomic<value_t> value_;
  static_assert(std::atomic<value_t>::is_always_lock_free);

  friend class ArtMetrics;
};

template <DatumId histogram_type_,
          size_t num_buckets_,
          int64_t minimum_value_,
          int64_t maximum_value_>
class MetricsHistogram final : public MetricsBase<int64_t> {
  static_assert(num_buckets_ >= 1);
  static_assert(minimum_value_ < maximum_value_);

 public:
  using value_t = uint32_t;

  constexpr MetricsHistogram() : buckets_{} {
    // Ensure we do not have any unnecessary data in this class.
    // Adding intptr_t to accommodate vtable, and rounding up to incorporate
    // padding.
    static_assert(RoundUp(sizeof(*this), sizeof(uint64_t))
                  == RoundUp(sizeof(intptr_t) + sizeof(value_t) * num_buckets_, sizeof(uint64_t)));
  }

  void Add(int64_t value) override {
    const size_t i = FindBucketId(value);
    buckets_[i].fetch_add(1u, std::memory_order::memory_order_relaxed);
  }

  void Report(const std::vector<MetricsBackend*>& backends) const {
    for (MetricsBackend* backend : backends) {
      backend->ReportHistogram(histogram_type_, minimum_value_, maximum_value_, GetBuckets());
    }
  }

 protected:
  void Reset() {
    for (auto& bucket : buckets_) {
      bucket = 0;
    }
  }

 private:
  inline constexpr size_t FindBucketId(int64_t value) const {
    // Values below the minimum are clamped into the first bucket.
    if (value <= minimum_value_) {
      return 0;
    }
    // Values above the maximum are clamped into the last bucket.
    if (value >= maximum_value_) {
      return num_buckets_ - 1;
    }
    // Otherise, linearly interpolate the value into the right bucket
    constexpr size_t bucket_width = maximum_value_ - minimum_value_;
    return static_cast<size_t>(value - minimum_value_) * num_buckets_ / bucket_width;
  }

  std::vector<value_t> GetBuckets() const {
    // The loads from buckets_ will all be memory_order_seq_cst, which means they will be acquire
    // loads. This is a stricter memory order than is needed, but this should not be a
    // performance-critical section of code.
    return std::vector<value_t>{buckets_.begin(), buckets_.end()};
  }

  bool IsNull() const override {
    std::vector<value_t> buckets = GetBuckets();
    return std::all_of(buckets.cbegin(), buckets.cend(), [](value_t i) { return i == 0; });
  }

  std::array<std::atomic<value_t>, num_buckets_> buckets_;
  static_assert(std::atomic<value_t>::is_always_lock_free);

  friend class ArtMetrics;
};

template <DatumId datum_id, typename T, const T& AccumulatorFunction(const T&, const T&)>
class MetricsAccumulator final : MetricsBase<T> {
 public:
  explicit constexpr MetricsAccumulator(T value = 0) : value_{value} {
    // Ensure we do not have any unnecessary data in this class.
    // Adding intptr_t to accommodate vtable, and rounding up to incorporate
    // padding.
    static_assert(RoundUp(sizeof(*this), sizeof(uint64_t)) ==
                  RoundUp(sizeof(intptr_t) + sizeof(T), sizeof(uint64_t)));
  }

  void Add(T value) override {
    T current = value_.load(std::memory_order::memory_order_relaxed);
    T new_value;
    do {
      new_value = AccumulatorFunction(current, value);
      // If the value didn't change, don't bother storing it.
      if (current == new_value) {
        break;
      }
    } while (!value_.compare_exchange_weak(
        current, new_value, std::memory_order::memory_order_relaxed));
  }

  // Report the metric as a counter, since this has only a single value.
  void Report(MetricsBackend* backend) const {
    backend->ReportCounter(datum_id, static_cast<uint64_t>(Value()));
  }

 protected:
  void Reset() {
    value_ = 0;
  }

 private:
  T Value() const { return value_.load(std::memory_order::memory_order_relaxed); }

  bool IsNull() const override { return Value() == 0; }

  std::atomic<T> value_;

  friend class ArtMetrics;
};

// Base class for formatting metrics into different formats
// (human-readable text, JSON, etc.)
class MetricsFormatter {
 public:
  virtual ~MetricsFormatter() = default;

  virtual void FormatBeginReport(uint64_t timestamp_since_start_ms,
                                 const std::optional<SessionData>& session_data) = 0;
  virtual void FormatEndReport() = 0;
  virtual void FormatReportCounter(DatumId counter_type, uint64_t value) = 0;
  virtual void FormatReportHistogram(DatumId histogram_type,
                                     int64_t low_value,
                                     int64_t high_value,
                                     const std::vector<uint32_t>& buckets) = 0;
  virtual std::string GetAndResetBuffer() = 0;

 protected:
  const std::string version = "1.0";
};

// Formatter outputting metrics in human-readable text format
class TextFormatter : public MetricsFormatter {
 public:
  TextFormatter() = default;

  void FormatBeginReport(uint64_t timestamp_millis,
                         const std::optional<SessionData>& session_data) override;

  void FormatReportCounter(DatumId counter_type, uint64_t value) override;

  void FormatReportHistogram(DatumId histogram_type,
                             int64_t low_value,
                             int64_t high_value,
                             const std::vector<uint32_t>& buckets) override;

  void FormatEndReport() override;

  std::string GetAndResetBuffer() override;

 private:
  std::ostringstream os_;
};

// Formatter outputting metrics in XML format
class XmlFormatter : public MetricsFormatter {
 public:
  XmlFormatter() = default;

  void FormatBeginReport(uint64_t timestamp_millis,
                         const std::optional<SessionData>& session_data) override;

  void FormatReportCounter(DatumId counter_type, uint64_t value) override;

  void FormatReportHistogram(DatumId histogram_type,
                             int64_t low_value,
                             int64_t high_value,
                             const std::vector<uint32_t>& buckets) override;

  void FormatEndReport() override;

  std::string GetAndResetBuffer() override;

 private:
  tinyxml2::XMLDocument document_;
};

// A backend that writes metrics to a string.
// The format of the metrics' output is delegated
// to the MetricsFormatter class.
//
// This is used as a base for LogBackend and FileBackend.
class StringBackend : public MetricsBackend {
 public:
  explicit StringBackend(std::unique_ptr<MetricsFormatter> formatter);

  void BeginOrUpdateSession(const SessionData& session_data) override;

  void BeginReport(uint64_t timestamp_millis) override;

  void ReportCounter(DatumId counter_type, uint64_t value) override;

  void ReportHistogram(DatumId histogram_type,
                       int64_t low_value,
                       int64_t high_value,
                       const std::vector<uint32_t>& buckets) override;

  void EndReport() override;

  std::string GetAndResetBuffer();

 private:
  std::unique_ptr<MetricsFormatter> formatter_;
  std::optional<SessionData> session_data_;
};

// A backend that writes metrics in human-readable format to the log (i.e. logcat).
class LogBackend : public StringBackend {
 public:
  explicit LogBackend(std::unique_ptr<MetricsFormatter> formatter,
                      android::base::LogSeverity level);

  void BeginReport(uint64_t timestamp_millis) override;
  void EndReport() override;

 private:
  android::base::LogSeverity level_;
};

// A backend that writes metrics to a file.
class FileBackend : public StringBackend {
 public:
  explicit FileBackend(std::unique_ptr<MetricsFormatter> formatter,
                       const std::string& filename);

  void BeginReport(uint64_t timestamp_millis) override;
  void EndReport() override;

 private:
  std::string filename_;
};

/**
 * AutoTimer simplifies time-based metrics collection.
 *
 * Several modes are supported. In the default case, the timer starts immediately and stops when it
 * goes out of scope. Example:
 *
 *     {
 *       AutoTimer timer{metric};
 *       DoStuff();
 *       // timer stops and updates metric automatically here.
 *     }
 *
 * You can also stop the timer early:
 *
 *     timer.Stop();
 *
 * Finally, you can choose to not automatically start the timer at the beginning by passing false as
 * the second argument to the constructor:
 *
 *     AutoTimer timer{metric, false};
 *     DoNotTimeThis();
 *     timer.Start();
 *     TimeThis();
 *
 * Manually started timers will still automatically stop in the destructor, but they can be manually
 * stopped as well.
 *
 * Note that AutoTimer makes calls to MicroTime(), so this may not be suitable on critical paths, or
 * in cases where the counter needs to be started and stopped on different threads.
 */
template <typename Metric>
class AutoTimer {
 public:
  explicit AutoTimer(Metric* metric, bool autostart = true)
      : running_{false}, start_time_microseconds_{}, metric_{metric} {
    if (autostart) {
      Start();
    }
  }

  ~AutoTimer() {
    if (running_) {
      Stop();
    }
  }

  void Start() {
    DCHECK(!running_);
    running_ = true;
    start_time_microseconds_ = MicroTime();
  }

  // Stops a running timer. Returns the time elapsed since starting the timer in microseconds.
  uint64_t Stop() {
    DCHECK(running_);
    uint64_t stop_time_microseconds = MicroTime();
    running_ = false;

    uint64_t elapsed_time = stop_time_microseconds - start_time_microseconds_;
    metric_->Add(static_cast<typename Metric::value_t>(elapsed_time));
    return elapsed_time;
  }

 private:
  bool running_;
  uint64_t start_time_microseconds_;
  Metric* metric_;
};

/**
 * This struct contains all of the metrics that ART reports.
 */
class ArtMetrics {
 public:
  ArtMetrics();

  void ReportAllMetricsAndResetValueMetrics(const std::vector<MetricsBackend*>& backends);
  void DumpForSigQuit(std::ostream& os);

  // Resets all metrics to their initial value. This is intended to be used after forking from the
  // zygote so we don't attribute parent values to the child process.
  void Reset();

#define METRIC_ACCESSORS(name, Kind, ...)                                        \
  Kind<DatumId::k##name, ##__VA_ARGS__>* name() { return &name##_; } \
  const Kind<DatumId::k##name, ##__VA_ARGS__>* name() const { return &name##_; }
  ART_METRICS(METRIC_ACCESSORS)
#undef METRIC_ACCESSORS

 private:
  uint64_t beginning_timestamp_;
  uint64_t last_report_timestamp_;

#define METRIC(name, Kind, ...) Kind<DatumId::k##name, ##__VA_ARGS__> name##_;
  ART_METRICS(METRIC)
#undef METRIC
};

// Returns a human readable name for the given DatumId.
std::string DatumName(DatumId datum);

// We also log the thread type for metrics so we can distinguish things that block the UI thread
// from things that happen on the background thread. This enum keeps track of what thread types we
// support.
enum class ThreadType {
  kMain,
  kBackground,
};

}  // namespace metrics
}  // namespace art

#pragma clang diagnostic pop  // -Wconversion

#endif  // ART_LIBARTBASE_BASE_METRICS_METRICS_H_
