// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_METRICS_H_
#define RUNTIME_VM_METRICS_H_

#include "vm/allocation.h"

namespace dart {

class Isolate;
class IsolateGroup;
class JSONStream;

// Metrics for each isolate group.
#define ISOLATE_GROUP_METRIC_LIST(V)                                           \
  V(MetricHeapOldUsed, HeapOldUsed, "heap.old.used", kByte)                    \
  V(MaxMetric, HeapOldUsedMax, "heap.old.used.max", kByte)                     \
  V(MetricHeapOldCapacity, HeapOldCapacity, "heap.old.capacity", kByte)        \
  V(MaxMetric, HeapOldCapacityMax, "heap.old.capacity.max", kByte)             \
  V(MetricHeapOldExternal, HeapOldExternal, "heap.old.external", kByte)        \
  V(MetricHeapNewUsed, HeapNewUsed, "heap.new.used", kByte)                    \
  V(MaxMetric, HeapNewUsedMax, "heap.new.used.max", kByte)                     \
  V(MetricHeapNewCapacity, HeapNewCapacity, "heap.new.capacity", kByte)        \
  V(MaxMetric, HeapNewCapacityMax, "heap.new.capacity.max", kByte)             \
  V(MetricHeapNewExternal, HeapNewExternal, "heap.new.external", kByte)        \
  V(MetricHeapUsed, HeapGlobalUsed, "heap.global.used", kByte)                 \
  V(MaxMetric, HeapGlobalUsedMax, "heap.global.used.max", kByte)

// Metrics for each isolate.
#define ISOLATE_METRIC_LIST(V)                                                 \
  V(Metric, RunnableLatency, "isolate.runnable.latency", kMicrosecond)         \
  V(Metric, RunnableHeapSize, "isolate.runnable.heap", kByte)

#define VM_METRIC_LIST(V)                                                      \
  V(MetricIsolateCount, IsolateCount, "vm.isolate.count", kCounter)            \
  V(MetricCurrentRSS, CurrentRSS, "vm.memory.current", kByte)                  \
  V(MetricPeakRSS, PeakRSS, "vm.memory.max", kByte)

class Metric {
 public:
  enum Unit {
    kCounter,
    kByte,
    kMicrosecond,
  };

  Metric();

  static void Init();

  static void Cleanup();

  // Initialize a metric for an isolate.
  void InitInstance(Isolate* isolate,
                    const char* name,
                    const char* description,
                    Unit unit);

  // Initialize a metric for an isolate group.
  void InitInstance(IsolateGroup* isolate_group,
                    const char* name,
                    const char* description,
                    Unit unit);

  // Initialize a metric for the VM.
  void InitInstance(const char* name, const char* description, Unit unit);

  virtual ~Metric();

#ifndef PRODUCT
  void PrintJSON(JSONStream* stream);
#endif  // !PRODUCT

  // Returns a zone allocated string.
  static char* ValueToString(int64_t value, Unit unit);

  // Returns a zone allocated string.
  char* ToString();

  int64_t value() const { return value_; }
  void set_value(int64_t value) { value_ = value; }

  void increment() { value_++; }

  const char* name() const { return name_; }
  const char* description() const { return description_; }
  Unit unit() const { return unit_; }

  // Only non-null for isolate specific metrics.
  Isolate* isolate() const { return isolate_; }

  // Only non-null for isolate group specific metrics.
  IsolateGroup* isolate_group() const { return isolate_group_; }

  static Metric* vm_head() { return vm_list_head_; }

  // Override to get a callback when value is serialized to JSON.
  // Use this for metrics that produce their value on demand.
  virtual int64_t Value() const { return value(); }

 private:
  Isolate* isolate_ = nullptr;
  IsolateGroup* isolate_group_ = nullptr;
  const char* name_ = nullptr;
  const char* description_ = nullptr;
  Unit unit_;
  int64_t value_;

  static Metric* vm_list_head_;
  DISALLOW_COPY_AND_ASSIGN(Metric);
};

// A Metric class that reports the maximum value observed.
// Initial maximum is kMinInt64.
class MaxMetric : public Metric {
 public:
  MaxMetric();

  void SetValue(int64_t new_value);
};

// A Metric class that reports the minimum value observed.
// Initial minimum is kMaxInt64.
class MinMetric : public Metric {
 public:
  MinMetric();

  void SetValue(int64_t new_value);
};

class MetricHeapOldUsed : public Metric {
 public:
  virtual int64_t Value() const;
};

class MetricHeapOldCapacity : public Metric {
 public:
  virtual int64_t Value() const;
};

class MetricHeapOldExternal : public Metric {
 public:
  virtual int64_t Value() const;
};

class MetricHeapNewUsed : public Metric {
 public:
  virtual int64_t Value() const;
};

class MetricHeapNewCapacity : public Metric {
 public:
  virtual int64_t Value() const;
};

class MetricHeapNewExternal : public Metric {
 public:
  virtual int64_t Value() const;
};

class MetricIsolateCount : public Metric {
 public:
  virtual int64_t Value() const;
};

class MetricCurrentRSS : public Metric {
 public:
  virtual int64_t Value() const;
};

class MetricPeakRSS : public Metric {
 public:
  virtual int64_t Value() const;
};

class MetricHeapUsed : public Metric {
 public:
  virtual int64_t Value() const;
};

#if !defined(PRODUCT)
#define VM_METRIC_VARIABLE(type, variable, name, unit)                         \
  extern type vm_metric_##variable;
VM_METRIC_LIST(VM_METRIC_VARIABLE);
#undef VM_METRIC_VARIABLE
#endif  // !defined(PRODUCT)

}  // namespace dart

#endif  // RUNTIME_VM_METRICS_H_
