// 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,
    );
  }
}
