// 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(nullable: false)
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(nullable: false)
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(List<TimeSlice> 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');
    }
    var _now = now();
    var prevSlice = TimeSlice(_startTime, _now);
    _startTime = _now;
    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();
    }

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

    // Exclude nested sync tracks
    if (isNestedRun && isExcludedNestedTrack) {
      var 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 that was spend in 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();
    }

    var 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) {
      var 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) {
      var 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) {
      var 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;
    var 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;
}
