// 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,
    {void Function() work}) {
  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 (work != null) {
      work();
    }

    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;

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

  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.');
  }
}

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