// Copyright (c) 2020, 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.

// @dart=2.9

import 'dart:async';
import 'dart:io';
import 'dart:math' as math;
import 'dart:typed_data';

/// Measures event loop responsiveness.
///
/// Schedules new timer events, [tickDuration] in the future, and measures how
/// long it takes for these events to actually arrive.
///
/// Runs [numberOfTicks] times before completing with [EventLoopLatencyStats].
Future<EventLoopLatencyStats> measureEventLoopLatency(
    Duration tickDuration, int numberOfTicks) {
  final completer = Completer<EventLoopLatencyStats>();

  final tickDurationInUs = tickDuration.inMicroseconds;
  final buffer = _TickLatencies(numberOfTicks);
  final sw = Stopwatch()..start();
  int lastTimestamp = 0;

  void trigger() {
    final int currentTimestamp = sw.elapsedMicroseconds;

    // Every tick we missed to schedule we'll add with difference to when we
    // would've scheduled it and when we became responsive again.
    bool done = false;
    while (!done && lastTimestamp < (currentTimestamp - tickDurationInUs)) {
      done = !buffer.add(currentTimestamp - lastTimestamp - tickDurationInUs);
      lastTimestamp += tickDurationInUs;
    }

    if (!done) {
      lastTimestamp = currentTimestamp;
      Timer(tickDuration, trigger);
    } else {
      completer.complete(buffer.makeStats());
    }
  }

  Timer(tickDuration, trigger);

  return completer.future;
}

/// Result of the event loop latency measurement.
class EventLoopLatencyStats {
  /// Minimum latency between scheduling a tick and it's arrival (in ms).
  final double minLatency;

  /// Average latency between scheduling a tick and it's arrival (in ms).
  final double avgLatency;

  /// Maximum latency between scheduling a tick and it's arrival (in ms).
  final double maxLatency;

  /// The 50th percentile (median) (in ms).
  final double percentile50th;

  /// The 90th percentile (in ms).
  final double percentile90th;

  /// The 95th percentile (in ms).
  final double percentile95th;

  /// The 99th percentile (in ms).
  final double percentile99th;

  /// The maximum RSS of the process.
  final int maxRss;

  EventLoopLatencyStats(
      this.minLatency,
      this.avgLatency,
      this.maxLatency,
      this.percentile50th,
      this.percentile90th,
      this.percentile95th,
      this.percentile99th,
      this.maxRss);

  void report(String name) {
    print('$name.Min(RunTimeRaw): $minLatency ms.');
    print('$name.Avg(RunTimeRaw): $avgLatency ms.');
    print('$name.Percentile50(RunTimeRaw): $percentile50th ms.');
    print('$name.Percentile90(RunTimeRaw): $percentile90th ms.');
    print('$name.Percentile95(RunTimeRaw): $percentile95th ms.');
    print('$name.Percentile99(RunTimeRaw): $percentile99th ms.');
    print('$name.Max(RunTimeRaw): $maxLatency ms.');
    print('$name.MaxRss(MemoryUse): $maxRss');
  }
}

/// Accumulates tick latencies and makes statistics for it.
class _TickLatencies {
  final Uint64List _timestamps;
  int _index = 0;

  _TickLatencies(int numberOfTicks) : _timestamps = Uint64List(numberOfTicks);

  /// Returns `true` while the buffer has not been filled yet.
  bool add(int latencyInUs) {
    _timestamps[_index++] = latencyInUs;
    return _index < _timestamps.length;
  }

  EventLoopLatencyStats makeStats() {
    if (_index != _timestamps.length) {
      throw 'Buffer has not been fully filled yet.';
    }

    _timestamps.sort();
    final length = _timestamps.length;
    final double avg = _timestamps.fold(0, (int a, int b) => a + b) / length;
    final int min = _timestamps.fold(0x7fffffffffffffff, math.min);
    final int max = _timestamps.fold(0, math.max);
    final percentile50th = _timestamps[50 * length ~/ 100];
    final percentile90th = _timestamps[90 * length ~/ 100];
    final percentile95th = _timestamps[95 * length ~/ 100];
    final percentile99th = _timestamps[99 * length ~/ 100];

    return EventLoopLatencyStats(
        min / 1000,
        avg / 1000,
        max / 1000,
        percentile50th / 1000,
        percentile90th / 1000,
        percentile95th / 1000,
        percentile99th / 1000,
        ProcessInfo.maxRss);
  }
}
