// 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 maxUserTags = 64;

  @Deprecated("Use 'maxUserTags' instead. Will be removed in Dart 3.0.")
  // TODO(bkonyi): We shouldn't be using SCREAMING_CAPS for constants, so this
  // should be removed for Dart 3.0.
  static const MAX_USER_TAGS = maxUserTags;

  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 {
  /// The current set of registered [Metric]s.
  static UnmodifiableMapView<String, Metric> get current =>
      UnmodifiableMapView<String, Metric>(_metrics);
  static final _metrics = <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);
  }
}
