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

library;

import 'dart:async'
    show Future, Zone, ZoneDelegate, ZoneSpecification, runZoned;

import 'metrics.dart';

/// Used to measure where time is spent in the compiler.
///
/// This exposes [measure] and [measureIo], which wrap an action and associate
/// the time spent during that action with this task. Nested measurementsccan be
/// introduced by using [measureSubtask].
// TODO(sigmund): rename to MeasurableTask
abstract class CompilerTask {
  final Measurer _measurer;
  final Stopwatch? _watch;
  final Map<String, GenericTask> _subtasks = {};

  int _asyncCount = 0;

  // Each task has a fixed, lazily computed, ZoneSpecification and zoneValues
  // for [_measureZoned].
  ZoneSpecification? _zoneSpecification;
  Map<Measurer, CompilerTask>? _zoneValues;

  CompilerTask(this._measurer)
    : _watch = _measurer.enableTaskMeasurements ? Stopwatch() : null;

  /// Whether measurement is disabled. The functions [measure] and [measureIo]
  /// only measure time if measurements are enabled.
  bool get _isDisabled => _watch == null;

  /// Name to use for reporting timing information.
  ///
  /// Subclasses should override this with a proper name, otherwise we use the
  /// runtime type of the task.
  String get name => "Unknown task '$runtimeType'";

  bool get isRunning => _watch?.isRunning == true;

  int get timing {
    if (_isDisabled) return 0;
    int total = _watch!.elapsedMilliseconds;
    for (GenericTask subtask in _subtasks.values) {
      total += subtask.timing;
    }
    return total;
  }

  Duration get duration {
    if (_isDisabled) return Duration.zero;
    Duration total = _watch!.elapsed;
    for (GenericTask subtask in _subtasks.values) {
      total += subtask.duration;
    }
    return total;
  }

  /// Perform [action] and measure its runtime (including any asynchronous
  /// callbacks, such as, [Future.then], but excluding code measured by other
  /// tasks).
  T measure<T>(T Function() action) =>
      _isDisabled ? action() : _measureZoned(action);

  /// Helper method that starts measuring with this [CompilerTask], that is,
  /// make this task the currently measured task.
  CompilerTask? _start() {
    if (_isDisabled) return null;
    CompilerTask? previous = _measurer._currentTask;
    _measurer._currentTask = this;
    if (previous != null) previous._watch!.stop();
    // Regardless of whether [previous] is `null` we've returned from the
    // eventloop.
    _measurer.stopAsyncWallClock();
    _watch!.start();
    return previous;
  }

  /// Helper method that stops measuring with this [CompilerTask], that is,
  /// make [previous] the currently measured task.
  void _stop(CompilerTask? previous) {
    if (_isDisabled) return;
    _watch!.stop();
    if (previous != null) {
      previous._watch!.start();
    } else {
      // If there's no previous task, we're about to return control to the
      // event loop. Start counting that as waiting asynchronous I/O.
      _measurer.startAsyncWallClock();
    }
    _measurer._currentTask = previous;
  }

  T _measureZoned<T>(T Function() action) {
    // Using zones, we're able to track asynchronous operations correctly, as
    // our zone will be asked to invoke `then` blocks. Then blocks (the closure
    // passed to runZoned, and other closures) are run via the `run` functions
    // below.

    assert(_watch != null);

    // The current zone is already measuring `this` task.
    if (Zone.current[_measurer] == this) return action();

    return runZoned(
      action,
      zoneValues: _zoneValues ??= {_measurer: this},
      zoneSpecification: _zoneSpecification ??= ZoneSpecification(
        run: _run,
        runUnary: _runUnary,
        runBinary: _runBinary,
      ),
    );
  }

  /// Run [f] in [zone]. Running must be delegated to [parent] to ensure that
  /// various state is set up correctly (in particular that `Zone.current`
  /// has the right value). Since [_measureZoned] can be called recursively
  /// (synchronously), some of the measuring zones we create will be parents
  /// of other measuring zones, but we still need to call through the parent
  /// chain. Consequently, we use a zone value keyed by [_measurer] to see if
  /// we should measure or not when delegating.
  R _run<R>(Zone self, ZoneDelegate parent, Zone zone, R Function() f) {
    if (zone[_measurer] != this) return parent.run(zone, f);
    CompilerTask? previous = _start();
    try {
      return parent.run(zone, f);
    } finally {
      _stop(previous);
    }
  }

  /// Same as [run] except that [f] takes one argument, [arg].
  R _runUnary<R, T>(
    Zone self,
    ZoneDelegate parent,
    Zone zone,
    R Function(T arg) f,
    T arg,
  ) {
    if (zone[_measurer] != this) return parent.runUnary(zone, f, arg);
    CompilerTask? previous = _start();
    try {
      return parent.runUnary(zone, f, arg);
    } finally {
      _stop(previous);
    }
  }

  /// Same as [run] except that [f] takes two arguments ([a1] and [a2]).
  R _runBinary<R, T1, T2>(
    Zone self,
    ZoneDelegate parent,
    Zone zone,
    R Function(T1 a1, T2 a2) f,
    T1 a1,
    T2 a2,
  ) {
    if (zone[_measurer] != this) return parent.runBinary(zone, f, a1, a2);
    CompilerTask? previous = _start();
    try {
      return parent.runBinary(zone, f, a1, a2);
    } finally {
      _stop(previous);
    }
  }

  /// Asynchronous version of [measure]. Use this when action returns a future
  /// that's truly asynchronous, such I/O. Only one task can use this method
  /// concurrently.
  ///
  /// Note: we assume that this method is used only by the compiler input
  /// provider, but it could be used by other tasks as long as the input
  /// provider will not be called by those tasks.
  Future<T> measureIo<T>(Future<T> Function() action) {
    if (_isDisabled) return action();

    if (_measurer._currentAsyncTask == null) {
      _measurer._currentAsyncTask = this;
    } else if (_measurer._currentAsyncTask != this) {
      throw "Cannot track async task '$name' because"
          " '${_measurer._currentAsyncTask?.name}' is already being tracked.";
    }
    _asyncCount++;
    return measure(action).whenComplete(() {
      _asyncCount--;
      if (_asyncCount == 0) _measurer._currentAsyncTask = null;
    });
  }

  /// Measure the time spent in [action] (if in verbose mode) and accumulate it
  /// under a subtask with the given name.
  T measureSubtask<T>(String name, T Function() action) {
    if (_isDisabled) return action();

    // Use a nested CompilerTask for the measurement to ensure nested [measure]
    // calls work correctly. The subtasks will never themselves have nested
    // subtasks because they are not accessible outside.
    GenericTask subtask = _subtasks[name] ??= GenericTask(name, _measurer);
    return subtask.measure(action);
  }

  /// Asynchronous version of [measureSubtask]. Use this when action returns a
  /// future that's truly asynchronous, such I/O. Only one task can use this
  /// concurrently.
  ///
  /// Note: we assume that this method is used only by the compiler input
  /// provider, but it could be used by other tasks as long as the input
  /// provider will not be called by those tasks.
  Future<T> measureIoSubtask<T>(String name, Future<T> Function() action) {
    if (_isDisabled) return action();

    // Use a nested CompilerTask for the measurement to ensure nested [measure]
    // calls work correctly. The subtasks will never themselves have nested
    // subtasks because they are not accessible outside.
    GenericTask subtask = _subtasks[name] ??= GenericTask(name, _measurer);
    return subtask.measureIo(action);
  }

  Iterable<String> get subtasks => _subtasks.keys;

  int getSubtaskTime(String subtask) => _subtasks[subtask]!.timing;

  bool getSubtaskIsRunning(String subtask) => _subtasks[subtask]!.isRunning;

  /// Returns the metrics for this task.
  Metrics get metrics => Metrics.none();
}

class GenericTask extends CompilerTask {
  @override
  final String name;
  GenericTask(this.name, Measurer measurer) : super(measurer);
}

class GenericTaskWithMetrics extends GenericTask {
  @override
  final Metrics metrics;

  GenericTaskWithMetrics(super.name, super.measurer, this.metrics);
}

class Measurer {
  /// Measures the total runtime from this object was constructed.
  ///
  /// Note: MUST be the first field of this class to ensure [wallclock] is
  /// started before other computations.
  final Stopwatch _wallClock = Stopwatch()..start();

  Duration get elapsedWallClock => _wallClock.elapsed;

  /// Measures gaps between zoned closures due to asynchronicity.
  final Stopwatch _asyncWallClock = Stopwatch();

  Duration get elapsedAsyncWallClock => _asyncWallClock.elapsed;

  /// Whether measurement of tasks is enabled.
  final bool enableTaskMeasurements;

  static int _hashCodeGenerator = 197;

  @override
  final int hashCode = _hashCodeGenerator++;

  @override
  bool operator ==(other) => identical(this, other);

  Measurer({this.enableTaskMeasurements = false});

  /// The currently running task, that is, the task whose [Stopwatch] is
  /// currently running.
  CompilerTask? _currentTask;

  /// The current task which should be charged for asynchronous gaps.
  CompilerTask? _currentAsyncTask;

  /// Start counting the total elapsed time since the compiler started.
  void startWallClock() {
    _wallClock.start();
  }

  /// Start counting the total elapsed time since the compiler started.
  void stopWallClock() {
    _wallClock.stop();
  }

  /// Call this before returning to the eventloop.
  void startAsyncWallClock() {
    if (_currentAsyncTask != null) {
      _currentAsyncTask!._watch?.start();
    } else {
      _asyncWallClock.start();
    }
  }

  /// Call this when the eventloop returns control to us.
  void stopAsyncWallClock() {
    if (_currentAsyncTask != null) {
      _currentAsyncTask!._watch?.stop();
    }
    _asyncWallClock.stop();
  }
}
