// Copyright 2014 The Flutter Authors. 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:flutter/foundation.dart';

class _AsyncScope {
  _AsyncScope(this.creationStack, this.zone);
  final StackTrace creationStack;
  final Zone zone;
}

/// Utility class for all the async APIs in the `flutter_test` library.
///
/// This class provides checking for asynchronous APIs, allowing the library to
/// verify that all the asynchronous APIs are properly `await`ed before calling
/// another.
///
/// For example, it prevents this kind of code:
///
/// ```dart
/// tester.pump(); // forgot to call "await"!
/// tester.pump();
/// ```
///
/// ...by detecting, in the second call to `pump`, that it should actually be:
///
/// ```dart
/// await tester.pump();
/// await tester.pump();
/// ```
///
/// It does this while still allowing nested calls, e.g. so that you can
/// call [expect] from inside callbacks.
///
/// You can use this in your own test functions, if you have some asynchronous
/// functions that must be used with "await". Wrap the contents of the function
/// in a call to TestAsyncUtils.guard(), as follows:
///
/// ```dart
/// Future<void> myTestFunction() => TestAsyncUtils.guard(() async {
///   // ...
/// });
/// ```
class TestAsyncUtils {
  // This class is not meant to be instatiated or extended; this constructor
  // prevents instantiation and extension.
  // ignore: unused_element
  TestAsyncUtils._();
  static const String _className = 'TestAsyncUtils';

  static final List<_AsyncScope> _scopeStack = <_AsyncScope>[];

  /// Calls the given callback in a new async scope. The callback argument is
  /// the asynchronous body of the calling method. The calling method is said to
  /// be "guarded". Nested calls to guarded methods from within the body of this
  /// one are fine, but calls to other guarded methods from outside the body of
  /// this one before this one has finished will throw an exception.
  ///
  /// This method first calls [guardSync].
  static Future<T> guard<T>(Future<T> body()) {
    guardSync();
    final Zone zone = Zone.current.fork(
      zoneValues: <dynamic, dynamic>{
        _scopeStack: true, // so we can recognize this as our own zone
      }
    );
    final _AsyncScope scope = _AsyncScope(StackTrace.current, zone);
    _scopeStack.add(scope);
    final Future<T> result = scope.zone.run<Future<T>>(body);
    T resultValue; // This is set when the body of work completes with a result value.
    Future<T> completionHandler(dynamic error, StackTrace stack) {
      assert(_scopeStack.isNotEmpty);
      assert(_scopeStack.contains(scope));
      bool leaked = false;
      _AsyncScope closedScope;
      final List<DiagnosticsNode> information = <DiagnosticsNode>[];
      while (_scopeStack.isNotEmpty) {
        closedScope = _scopeStack.removeLast();
        if (closedScope == scope)
          break;
        if (!leaked) {
          information.add(ErrorSummary('Asynchronous call to guarded function leaked.'));
          information.add(ErrorHint('You must use "await" with all Future-returning test APIs.'));
          leaked = true;
        }
        final _StackEntry originalGuarder = _findResponsibleMethod(closedScope.creationStack, 'guard', information);
        if (originalGuarder != null) {
          information.add(ErrorDescription(
            'The test API method "${originalGuarder.methodName}" '
            'from class ${originalGuarder.className} '
            'was called from ${originalGuarder.callerFile} '
            'on line ${originalGuarder.callerLine}, '
            'but never completed before its parent scope closed.'
          ));
        }
      }
      if (leaked) {
        if (error != null) {
          information.add(DiagnosticsProperty<dynamic>(
            'An uncaught exception may have caused the guarded function leak. The exception was',
            error,
            style: DiagnosticsTreeStyle.errorProperty,
          ));
          information.add(DiagnosticsStackTrace('The stack trace associated with this exception was', stack));
        }
        throw FlutterError.fromParts(information);
      }
      if (error != null)
        return Future<T>.error(error, stack);
      return Future<T>.value(resultValue);
    }
    return result.then<T>(
      (T value) {
        resultValue = value;
        return completionHandler(null, null);
      },
      onError: completionHandler,
    );
  }

  static Zone get _currentScopeZone {
    Zone zone = Zone.current;
    while (zone != null) {
      if (zone[_scopeStack] == true)
        return zone;
      zone = zone.parent;
    }
    return null;
  }

  /// Verifies that there are no guarded methods currently pending (see [guard]).
  ///
  /// If a guarded method is currently pending, and this is not a call nested
  /// from inside that method's body (directly or indirectly), then this method
  /// will throw a detailed exception.
  static void guardSync() {
    if (_scopeStack.isEmpty) {
      // No scopes open, so we must be fine.
      return;
    }
    // Find the current TestAsyncUtils scope zone so we can see if it's the one we expect.
    final Zone zone = _currentScopeZone;
    if (zone == _scopeStack.last.zone) {
      // We're still in the current scope zone. All good.
      return;
    }
    // If we get here, we know we've got a conflict on our hands.
    // We got an async barrier, but the current zone isn't the last scope that
    // we pushed on the stack.
    // Find which scope the conflict happened in, so that we know
    // which stack trace to report the conflict as starting from.
    //
    // For example, if we called an async method A, which ran its body in a
    // guarded block, and in its body it ran an async method B, which ran its
    // body in a guarded block, but we didn't await B, then in A's block we ran
    // an async method C, which ran its body in a guarded block, then we should
    // complain about the call to B then the call to C. BUT. If we called an async
    // method A, which ran its body in a guarded block, and in its body it ran
    // an async method B, which ran its body in a guarded block, but we didn't
    // await A, and then at the top level we called a method D, then we should
    // complain about the call to A then the call to D.
    //
    // In both examples, the scope stack would have two scopes. In the first
    // example, the current zone would be the zone of the _scopeStack[0] scope,
    // and we would want to show _scopeStack[1]'s creationStack. In the second
    // example, the current zone would not be in the _scopeStack, and we would
    // want to show _scopeStack[0]'s creationStack.
    int skipCount = 0;
    _AsyncScope candidateScope = _scopeStack.last;
    _AsyncScope scope;
    do {
      skipCount += 1;
      scope = candidateScope;
      if (skipCount >= _scopeStack.length) {
        if (zone == null)
          break;
        // Some people have reported reaching this point, but it's not clear
        // why. For now, just silently return.
        // TODO(ianh): If we ever get a test case that shows how we reach
        // this point, reduce it and report the error if there is one.
        return;
      }
      candidateScope = _scopeStack[_scopeStack.length - skipCount - 1];
      assert(candidateScope != null);
      assert(candidateScope.zone != null);
    } while (candidateScope.zone != zone);
    assert(scope != null);
    final List<DiagnosticsNode> information = <DiagnosticsNode>[
      ErrorSummary('Guarded function conflict.'),
      ErrorHint('You must use "await" with all Future-returning test APIs.'),
    ];
    final _StackEntry originalGuarder = _findResponsibleMethod(scope.creationStack, 'guard', information);
    final _StackEntry collidingGuarder = _findResponsibleMethod(StackTrace.current, 'guardSync', information);
    if (originalGuarder != null && collidingGuarder != null) {
      final String originalKind = originalGuarder.className == null ? 'function' : 'method';
      String originalName;
      if (originalGuarder.className == null) {
        originalName = '$originalKind (${originalGuarder.methodName})';
        information.add(ErrorDescription(
          'The guarded "${originalGuarder.methodName}" function '
          'was called from ${originalGuarder.callerFile} '
          'on line ${originalGuarder.callerLine}.'
        ));
      } else {
        originalName = '$originalKind (${originalGuarder.className}.${originalGuarder.methodName})';
        information.add(ErrorDescription(
          'The guarded method "${originalGuarder.methodName}" '
          'from class ${originalGuarder.className} '
          'was called from ${originalGuarder.callerFile} '
          'on line ${originalGuarder.callerLine}.'
        ));
      }
      final String again = (originalGuarder.callerFile == collidingGuarder.callerFile) &&
                           (originalGuarder.callerLine == collidingGuarder.callerLine) ?
                           'again ' : '';
      final String collidingKind = collidingGuarder.className == null ? 'function' : 'method';
      String collidingName;
      if ((originalGuarder.className == collidingGuarder.className) &&
          (originalGuarder.methodName == collidingGuarder.methodName)) {
        originalName = originalKind;
        collidingName = collidingKind;
        information.add(ErrorDescription(
          'Then, it '
          'was called ${again}from ${collidingGuarder.callerFile} '
          'on line ${collidingGuarder.callerLine}.'
        ));
      } else if (collidingGuarder.className == null) {
        collidingName = '$collidingKind (${collidingGuarder.methodName})';
        information.add(ErrorDescription(
          'Then, the "${collidingGuarder.methodName}" function '
          'was called ${again}from ${collidingGuarder.callerFile} '
          'on line ${collidingGuarder.callerLine}.'
        ));
      } else {
        collidingName = '$collidingKind (${collidingGuarder.className}.${collidingGuarder.methodName})';
        information.add(ErrorDescription(
          'Then, the "${collidingGuarder.methodName}" method '
          '${originalGuarder.className == collidingGuarder.className ? "(also from class ${collidingGuarder.className})"
                                                                     : "from class ${collidingGuarder.className}"} '
          'was called ${again}from ${collidingGuarder.callerFile} '
          'on line ${collidingGuarder.callerLine}.'
        ));
      }
      information.add(ErrorDescription(
        'The first $originalName '
        'had not yet finished executing at the time that '
        'the second $collidingName '
        'was called. Since both are guarded, and the second was not a nested call inside the first, the '
        'first must complete its execution before the second can be called. Typically, this is achieved by '
        'putting an "await" statement in front of the call to the first.'
      ));
      if (collidingGuarder.className == null && collidingGuarder.methodName == 'expect') {
        information.add(ErrorHint(
          'If you are confident that all test APIs are being called using "await", and '
          'this expect() call is not being called at the top level but is itself being '
          'called from some sort of callback registered before the ${originalGuarder.methodName} '
          'method was called, then consider using expectSync() instead.'
        ));
      }
      information.add(DiagnosticsStackTrace(
        '\nWhen the first $originalName was called, this was the stack',
        scope.creationStack,
      ));
    }
    throw FlutterError.fromParts(information);
  }

  /// Verifies that there are no guarded methods currently pending (see [guard]).
  ///
  /// This is used at the end of tests to ensure that nothing leaks out of the test.
  static void verifyAllScopesClosed() {
    if (_scopeStack.isNotEmpty) {
      final List<DiagnosticsNode> information = <DiagnosticsNode>[
        ErrorSummary('Asynchronous call to guarded function leaked.'),
        ErrorHint('You must use "await" with all Future-returning test APIs.')
      ];
      for (final _AsyncScope scope in _scopeStack) {
        final _StackEntry guarder = _findResponsibleMethod(scope.creationStack, 'guard', information);
        if (guarder != null) {
          information.add(ErrorDescription(
            'The guarded method "${guarder.methodName}" '
            '${guarder.className != null ? "from class ${guarder.className} " : ""}'
            'was called from ${guarder.callerFile} '
            'on line ${guarder.callerLine}, '
            'but never completed before its parent scope closed.'
          ));
        }
      }
      throw FlutterError.fromParts(information);
    }
  }

  static bool _stripAsynchronousSuspensions(String line) {
    return line != '<asynchronous suspension>';
  }

  static _StackEntry _findResponsibleMethod(StackTrace rawStack, String method, List<DiagnosticsNode> information) {
    assert(method == 'guard' || method == 'guardSync');
    final List<String> stack = rawStack.toString().split('\n').where(_stripAsynchronousSuspensions).toList();
    assert(stack.last == '');
    stack.removeLast();
    final RegExp getClassPattern = RegExp(r'^#[0-9]+ +([^. ]+)');
    Match lineMatch;
    int index = -1;
    do { // skip past frames that are from this class
      index += 1;
      assert(index < stack.length);
      lineMatch = getClassPattern.matchAsPrefix(stack[index]);
      assert(lineMatch != null);
      assert(lineMatch.groupCount == 1);
    } while (lineMatch.group(1) == _className);
    // try to parse the stack to find the interesting frame
    if (index < stack.length) {
      final RegExp guardPattern = RegExp(r'^#[0-9]+ +(?:([^. ]+)\.)?([^. ]+)');
      final Match guardMatch = guardPattern.matchAsPrefix(stack[index]); // find the class that called us
      if (guardMatch != null) {
        assert(guardMatch.groupCount == 2);
        final String guardClass = guardMatch.group(1); // might be null
        final String guardMethod = guardMatch.group(2);
        while (index < stack.length) { // find the last stack frame that called the class that called us
          lineMatch = getClassPattern.matchAsPrefix(stack[index]);
          if (lineMatch != null) {
            assert(lineMatch.groupCount == 1);
            if (lineMatch.group(1) == (guardClass ?? guardMethod)) {
              index += 1;
              continue;
            }
          }
          break;
        }
        if (index < stack.length) {
          final RegExp callerPattern = RegExp(r'^#[0-9]+ .* \((.+?):([0-9]+)(?::[0-9]+)?\)$');
          final Match callerMatch = callerPattern.matchAsPrefix(stack[index]); // extract the caller's info
          if (callerMatch != null) {
            assert(callerMatch.groupCount == 2);
            final String callerFile = callerMatch.group(1);
            final String callerLine = callerMatch.group(2);
            return _StackEntry(guardClass, guardMethod, callerFile, callerLine);
          } else {
            // One reason you might get here is if the guarding method was called directly from
            // a 'dart:' API, like from the Future/microtask mechanism, because dart: URLs in the
            // stack trace don't have a column number and so don't match the regexp above.
            information.add(ErrorSummary('(Unable to parse the stack frame of the method that called the method that called $_className.$method(). The stack may be incomplete or bogus.)'));
            information.add(ErrorDescription(stack[index]));
          }
        } else {
          information.add(ErrorSummary('(Unable to find the stack frame of the method that called the method that called $_className.$method(). The stack may be incomplete or bogus.)'));
        }
      } else {
        information.add(ErrorSummary('(Unable to parse the stack frame of the method that called $_className.$method(). The stack may be incomplete or bogus.)'));
        information.add(ErrorDescription(stack[index]));
      }
    } else {
      information.add(ErrorSummary('(Unable to find the method that called $_className.$method(). The stack may be incomplete or bogus.)'));
    }
    return null;
  }
}

class _StackEntry {
  const _StackEntry(this.className, this.methodName, this.callerFile, this.callerLine);
  final String className;
  final String methodName;
  final String callerFile;
  final String callerLine;
}
