// 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.

part of dart.developer;

/// A UserTag can be used to group samples in the
/// [DevTools CPU profiler](https://flutter.dev/docs/development/tools/devtools/cpu-profiler).
abstract class UserTag {
  /// The maximum number of UserTag instances that can be created by a program.
  static const MAX_USER_TAGS = 64;

  external factory UserTag(String label);

  /// Label of [this].
  String get label;

  /// Make [this] the current tag for the isolate. Returns the current tag
  /// before setting.
  UserTag makeCurrent();

  /// The default [UserTag] with label 'Default'.
  external static UserTag get defaultTag;
}

/// Returns the current [UserTag] for the isolate.
external UserTag getCurrentTag();

/// Abstract [Metric] class. Metric names must be unique, are hierarchical,
/// and use periods as separators. For example, 'a.b.c'. Uniqueness is only
/// enforced when a Metric is registered. The name of a metric cannot contain
/// the slash ('/') character.
abstract class Metric {
  /// [name] of this metric.
  final String name;

  /// [description] of this metric.
  final String description;

  Metric(this.name, this.description) {
    if ((name == 'vm') || name.contains('/')) {
      throw new ArgumentError('Invalid Metric name.');
    }
  }

  Map _toJSON();
}

/// A measured value with a min and max. Initial value is min. Value will
/// be clamped to the interval `[min, max]`.
class Gauge extends Metric {
  final double min;
  final double max;

  double _value;
  double get value => _value;
  set value(double v) {
    if (v < min) {
      v = min;
    } else if (v > max) {
      v = max;
    }
    _value = v;
  }

  Gauge(String name, String description, this.min, this.max)
      : _value = min,
        super(name, description) {
    // TODO: When NNBD is complete, delete the following two lines.
    ArgumentError.checkNotNull(min, 'min');
    ArgumentError.checkNotNull(max, 'max');
    if (!(min < max)) throw new ArgumentError('min must be less than max');
  }

  Map _toJSON() {
    var map = {
      'type': 'Gauge',
      'id': 'metrics/$name',
      'name': name,
      'description': description,
      'value': value,
      'min': min,
      'max': max,
    };
    return map;
  }
}

/// A changing value. Initial value is 0.0.
class Counter extends Metric {
  Counter(String name, String description) : super(name, description);

  double _value = 0.0;
  double get value => _value;
  set value(double v) {
    _value = v;
  }

  Map _toJSON() {
    var map = {
      'type': 'Counter',
      'id': 'metrics/$name',
      'name': name,
      'description': description,
      'value': value,
    };
    return map;
  }
}

class Metrics {
  static final Map<String, Metric> _metrics = new Map<String, Metric>();

  /// Register [Metric]s to make them visible to Observatory.
  static void register(Metric metric) {
    // TODO: When NNBD is complete, delete the following line.
    ArgumentError.checkNotNull(metric, 'metric');
    if (_metrics[metric.name] != null) {
      throw new ArgumentError('Registered metrics have unique names');
    }
    _metrics[metric.name] = metric;
  }

  /// Deregister [Metric]s to make them not visible to Observatory.
  static void deregister(Metric metric) {
    // TODO: When NNBD is complete, delete the following line.
    ArgumentError.checkNotNull(metric, 'metric');
    _metrics.remove(metric.name);
  }

  @pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product"))
  static String? _printMetric(String id) {
    var metric = _metrics[id];
    if (metric == null) {
      return null;
    }
    return json.encode(metric._toJSON());
  }

  @pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product"))
  static String _printMetrics() {
    var metrics = [];
    for (var metric in _metrics.values) {
      metrics.add(metric._toJSON());
    }
    var map = {
      'type': 'MetricList',
      'metrics': metrics,
    };
    return json.encode(map);
  }
}
