// 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 dart2js.common.tasks;

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 '${this.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 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 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 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 f(T arg), 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 f(T1 a1, T2 a2), 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> 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 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> 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++;

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