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

import 'dart:async';

import 'package:json_annotation/json_annotation.dart';

import 'clock.dart';

part 'timing.g.dart';

/// The timings of an operation, including its [startTime], [stopTime], and
/// [duration].
@JsonSerializable()
class TimeSlice {
  /// The total duration of this operation, equivalent to taking the difference
  /// between [stopTime] and [startTime].
  Duration get duration => stopTime.difference(startTime);

  final DateTime startTime;

  final DateTime stopTime;

  TimeSlice(this.startTime, this.stopTime);

  factory TimeSlice.fromJson(Map<String, dynamic> json) =>
      _$TimeSliceFromJson(json);

  Map<String, dynamic> toJson() => _$TimeSliceToJson(this);

  @override
  String toString() => '($startTime + $duration)';
}

/// The timings of an async operation, consist of several sync [slices] and
/// includes total [startTime], [stopTime], and [duration].
@JsonSerializable()
class TimeSliceGroup implements TimeSlice {
  final List<TimeSlice> slices;

  @override
  DateTime get startTime => slices.first.startTime;

  @override
  DateTime get stopTime => slices.last.stopTime;

  /// The total duration of this operation, equivalent to taking the difference
  /// between [stopTime] and [startTime].
  @override
  Duration get duration => stopTime.difference(startTime);

  /// Sum of [duration]s of all [slices].
  ///
  /// If some of slices implements [TimeSliceGroup] [innerDuration] will be used
  /// to compute sum.
  Duration get innerDuration => slices.fold(
      Duration.zero,
      (duration, slice) =>
          duration +
          (slice is TimeSliceGroup ? slice.innerDuration : slice.duration));

  TimeSliceGroup(this.slices);

  /// Constructs TimeSliceGroup from JSON representation
  factory TimeSliceGroup.fromJson(Map<String, dynamic> json) =>
      _$TimeSliceGroupFromJson(json);

  @override
  Map<String, dynamic> toJson() => _$TimeSliceGroupToJson(this);

  @override
  String toString() => slices.toString();
}

abstract class TimeTracker implements TimeSlice {
  /// Whether tracking is active.
  ///
  /// Tracking is only active after `isStarted` and before `isFinished`.
  bool get isTracking;

  /// Whether tracking is finished.
  ///
  /// Tracker can't be used as [TimeSlice] before it is finished
  bool get isFinished;

  /// Whether tracking was started.
  ///
  /// Equivalent of `isTracking || isFinished`
  bool get isStarted;

  T track<T>(T Function() action);
}

/// Tracks only sync actions
class SyncTimeTracker implements TimeTracker {
  /// When this operation started, call [_start] to set this.
  @override
  DateTime get startTime => _startTime!;
  DateTime? _startTime;

  /// When this operation stopped, call [_stop] to set this.
  @override
  DateTime get stopTime => _stopTime!;
  DateTime? _stopTime;

  /// Start tracking this operation, must only be called once, before [_stop].
  void _start() {
    assert(_startTime == null && _stopTime == null);
    _startTime = now();
  }

  /// Stop tracking this operation, must only be called once, after [_start].
  void _stop() {
    assert(_startTime != null && _stopTime == null);
    _stopTime = now();
  }

  /// Splits tracker into two slices.
  ///
  /// Returns new [TimeSlice] started on [startTime] and ended now. Modifies
  /// [startTime] of tracker to current time point
  ///
  /// Don't change state of tracker. Can be called only while [isTracking], and
  /// tracker will sill be tracking after call.
  TimeSlice _split() {
    if (!isTracking) {
      throw StateError('Can be only called while tracking');
    }
    final splitPoint = now();
    final prevSlice = TimeSlice(_startTime!, splitPoint);
    _startTime = splitPoint;
    return prevSlice;
  }

  @override
  T track<T>(T Function() action) {
    if (isStarted) {
      throw StateError('Can not be tracked twice');
    }
    _start();
    try {
      return action();
    } finally {
      _stop();
    }
  }

  @override
  bool get isStarted => _startTime != null;

  @override
  bool get isTracking => _startTime != null && _stopTime == null;

  @override
  bool get isFinished => _startTime != null && _stopTime != null;

  @override
  Duration get duration => _stopTime!.difference(_startTime!);

  /// Converts to JSON representation
  ///
  /// Can't be used before [isFinished]
  @override
  Map<String, dynamic> toJson() => _$TimeSliceToJson(this);
}

/// Async actions returning [Future] will be tracked as single sync time span
/// from the beginning of execution till completion of future
class SimpleAsyncTimeTracker extends SyncTimeTracker {
  @override
  T track<T>(T Function() action) {
    if (isStarted) {
      throw StateError('Can not be tracked twice');
    }
    T result;
    _start();
    try {
      result = action();
    } catch (_) {
      _stop();
      rethrow;
    }
    if (result is Future) {
      return result.whenComplete(_stop) as T;
    } else {
      _stop();
      return result;
    }
  }
}

/// No-op implementation of [SyncTimeTracker] that does nothing.
class NoOpTimeTracker implements TimeTracker {
  static final sharedInstance = NoOpTimeTracker();

  @override
  Duration get duration =>
      throw UnsupportedError('Unsupported in no-op implementation');

  @override
  DateTime get startTime =>
      throw UnsupportedError('Unsupported in no-op implementation');

  @override
  DateTime get stopTime =>
      throw UnsupportedError('Unsupported in no-op implementation');

  @override
  bool get isStarted =>
      throw UnsupportedError('Unsupported in no-op implementation');

  @override
  bool get isTracking =>
      throw UnsupportedError('Unsupported in no-op implementation');

  @override
  bool get isFinished =>
      throw UnsupportedError('Unsupported in no-op implementation');

  @override
  T track<T>(T Function() action) => action();

  @override
  Map<String, dynamic> toJson() =>
      throw UnsupportedError('Unsupported in no-op implementation');
}

/// Track all async execution as disjoint time [slices] in ascending order.
///
/// Can [track] both async and sync actions.
/// Can exclude time of tested trackers.
///
/// If tracked action spawns some dangled async executions behavior is't
/// defined. Tracked might or might not track time of such executions
class AsyncTimeTracker extends TimeSliceGroup implements TimeTracker {
  final bool trackNested;

  static const _zoneKey = #timing_AsyncTimeTracker;

  AsyncTimeTracker({this.trackNested = true}) : super([]);

  T _trackSyncSlice<T>(ZoneDelegate parent, Zone zone, T Function() action) {
    // Ignore dangling runs after tracker completes
    if (isFinished) {
      return action();
    }

    final isNestedRun = slices.isNotEmpty &&
        slices.last is SyncTimeTracker &&
        (slices.last as SyncTimeTracker).isTracking;
    final isExcludedNestedTrack = !trackNested && zone[_zoneKey] != this;

    // Exclude nested sync tracks
    if (isNestedRun && isExcludedNestedTrack) {
      final timer = slices.last as SyncTimeTracker;
      // Split already tracked time into new slice.
      // Replace tracker in slices.last with splitted slice, to indicate for
      // recursive calls that we not tracking.
      slices.last = parent.run(zone, timer._split);
      try {
        return action();
      } finally {
        // Split tracker again and discard slice from nested tracker
        parent.run(zone, timer._split);
        // Add tracker back to list of slices and continue tracking
        slices.add(timer);
      }
    }

    // Exclude nested async tracks
    if (isExcludedNestedTrack) {
      return action();
    }

    // Split time slices in nested sync runs
    if (isNestedRun) {
      return action();
    }

    final timer = SyncTimeTracker();
    slices.add(timer);

    // Pass to parent zone, in case of overwritten clock
    return parent.runUnary(zone, timer.track, action);
  }

  static final asyncTimeTrackerZoneSpecification = ZoneSpecification(
    run: <R>(Zone self, ZoneDelegate parent, Zone zone, R Function() f) {
      final tracker = self[_zoneKey] as AsyncTimeTracker;
      return tracker._trackSyncSlice(parent, zone, () => parent.run(zone, f));
    },
    runUnary: <R, T>(Zone self, ZoneDelegate parent, Zone zone, R Function(T) f,
        T arg) {
      final tracker = self[_zoneKey] as AsyncTimeTracker;
      return tracker._trackSyncSlice(
          parent, zone, () => parent.runUnary(zone, f, arg));
    },
    runBinary: <R, T1, T2>(Zone self, ZoneDelegate parent, Zone zone,
        R Function(T1, T2) f, T1 arg1, T2 arg2) {
      final tracker = self[_zoneKey] as AsyncTimeTracker;
      return tracker._trackSyncSlice(
          parent, zone, () => parent.runBinary(zone, f, arg1, arg2));
    },
  );

  @override
  T track<T>(T Function() action) {
    if (isStarted) {
      throw StateError('Can not be tracked twice');
    }
    _tracking = true;
    final result = runZoned(action,
        zoneSpecification: asyncTimeTrackerZoneSpecification,
        zoneValues: {_zoneKey: this});
    if (result is Future) {
      return result
          // Break possible sync processing of future completion, so slice
          // trackers can be finished
          .whenComplete(Future.value)
          .whenComplete(() => _tracking = false) as T;
    } else {
      _tracking = false;
      return result;
    }
  }

  bool? _tracking;

  @override
  bool get isStarted => _tracking != null;

  @override
  bool get isFinished => _tracking == false;

  @override
  bool get isTracking => _tracking == true;
}
