// 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_tools/src/base/async_guard.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:quiver/testing/async.dart';

import '../../src/common.dart';

Future<void> asyncError() {
  final Completer<void> completer = Completer<void>();
  final Completer<void> errorCompleter = Completer<void>();
  errorCompleter.completeError('Async Doom', StackTrace.current);
  return completer.future;
}

Future<void> syncError() {
  throw 'Sync Doom';
}

Future<void> syncAndAsyncError() {
  final Completer<void> errorCompleter = Completer<void>();
  errorCompleter.completeError('Async Doom', StackTrace.current);
  throw 'Sync Doom';
}

Future<void> delayedThrow(FakeAsync time) {
  final Future<void> result =
    Future<void>.delayed(const Duration(milliseconds: 10))
      .then((_) {
        throw 'Delayed Doom';
      });
  time.elapse(const Duration(seconds: 1));
  time.flushMicrotasks();
  return result;
}

void main() {
  Completer<void> caughtInZone;
  bool caughtByZone = false;
  bool caughtByHandler = false;
  Zone zone;

  setUp(() {
    caughtInZone = Completer<void>();
    caughtByZone = false;
    caughtByHandler = false;
    zone = Zone.current.fork(specification: ZoneSpecification(
      handleUncaughtError: (
        Zone self,
        ZoneDelegate parent,
        Zone zone,
        Object error,
        StackTrace stackTrace,
      ) {
        caughtByZone = true;
        if (!caughtInZone.isCompleted) {
          caughtInZone.complete();
        }
      },
    ));
  });

  test('asyncError percolates through zone', () async {
    await zone.run(() async {
      try {
        // Completer is required or else we timeout.
        await Future.any(<Future<void>>[asyncError(), caughtInZone.future]);
      } on String {
        caughtByHandler = true;
      }
    });

    expect(caughtByZone, true);
    expect(caughtByHandler, false);
  });

  test('syncAndAsyncError percolates through zone', () async {
    await zone.run(() async {
      try {
        // Completer is required or else we timeout.
        await Future.any(<Future<void>>[syncAndAsyncError(), caughtInZone.future]);
      } on String {
        caughtByHandler = true;
      }
    });

    expect(caughtByZone, true);
    expect(caughtByHandler, true);
  });

  test('syncError percolates through zone', () async {
    await zone.run(() async {
      try {
        await syncError();
      } on String {
        caughtByHandler = true;
      }
    });

    expect(caughtByZone, false);
    expect(caughtByHandler, true);
  });

  test('syncError is caught by asyncGuard', () async {
    await zone.run(() async {
      try {
        await asyncGuard(syncError);
      } on String {
        caughtByHandler = true;
      }
    });

    expect(caughtByZone, false);
    expect(caughtByHandler, true);
  });


  test('asyncError is caught by asyncGuard', () async {
    await zone.run(() async {
      try {
        await asyncGuard(asyncError);
      } on String {
        caughtByHandler = true;
      }
    });

    expect(caughtByZone, false);
    expect(caughtByHandler, true);
  });

  test('asyncAndSyncError is caught by asyncGuard', () async {
    await zone.run(() async {
      try {
        await asyncGuard(syncAndAsyncError);
      } on String {
        caughtByHandler = true;
      }
    });

    expect(caughtByZone, false);
    expect(caughtByHandler, true);
  });

  test('asyncError is missed when catchError is attached too late', () async {
    bool caughtByZone = false;
    bool caughtByHandler = false;
    bool caughtByCatchError = false;

    final Completer<void> completer = Completer<void>();
    await FakeAsync().run((FakeAsync time) {
      unawaited(runZoned(() async {
        final Future<void> f = asyncGuard<void>(() => delayedThrow(time))
          .catchError((Object e, StackTrace s) {
            caughtByCatchError = true;
          });
        try {
          await f;
        } on String {
          caughtByHandler = true;
        }
        if (!completer.isCompleted) {
          completer.complete(null);
        }
      }, onError: (Object e, StackTrace s) {
        caughtByZone = true;
        if (!completer.isCompleted) {
          completer.complete(null);
        }
      }));
      time.elapse(const Duration(seconds: 1));
      time.flushMicrotasks();
      return completer.future;
    });

    expect(caughtByZone, true);
    expect(caughtByHandler, false);
    expect(caughtByCatchError, true);
  });

  test('asyncError is propagated with binary onError', () async {
    bool caughtByZone = false;
    bool caughtByHandler = false;
    bool caughtByOnError = false;

    final Completer<void> completer = Completer<void>();
    await FakeAsync().run((FakeAsync time) {
      unawaited(runZoned(() async {
        final Future<void> f = asyncGuard<void>(
          () => delayedThrow(time),
          onError: (Object e, StackTrace s) {
            caughtByOnError = true;
          },
        );
        try {
          await f;
        } on String {
          caughtByHandler = true;
        }
        if (!completer.isCompleted) {
          completer.complete(null);
        }
      }, onError: (Object e, StackTrace s) {
        caughtByZone = true;
        if (!completer.isCompleted) {
          completer.complete(null);
        }
      }));
      time.elapse(const Duration(seconds: 1));
      time.flushMicrotasks();
      return completer.future;
    });

    expect(caughtByZone, false);
    expect(caughtByHandler, false);
    expect(caughtByOnError, true);
  });

  test('asyncError is propagated with unary onError', () async {
    bool caughtByZone = false;
    bool caughtByHandler = false;
    bool caughtByOnError = false;

    final Completer<void> completer = Completer<void>();
    await FakeAsync().run((FakeAsync time) {
      unawaited(runZoned(() async {
        final Future<void> f = asyncGuard<void>(
          () => delayedThrow(time),
          onError: (Object e) {
            caughtByOnError = true;
          },
        );
        try {
          await f;
        } on String {
          caughtByHandler = true;
        }
        if (!completer.isCompleted) {
          completer.complete(null);
        }
      }, onError: (Object e, StackTrace s) {
        caughtByZone = true;
        if (!completer.isCompleted) {
          completer.complete(null);
        }
      }));
      time.elapse(const Duration(seconds: 1));
      time.flushMicrotasks();
      return completer.future;
    });

    expect(caughtByZone, false);
    expect(caughtByHandler, false);
    expect(caughtByOnError, true);
  });

  test('asyncError is propagated with optional stack trace', () async {
    bool caughtByZone = false;
    bool caughtByHandler = false;
    bool caughtByOnError = false;
    bool nonNullStackTrace = false;

    final Completer<void> completer = Completer<void>();
    await FakeAsync().run((FakeAsync time) {
      unawaited(runZoned(() async {
        final Future<void> f = asyncGuard<void>(
          () => delayedThrow(time),
          onError: (Object e, [StackTrace s]) {
            caughtByOnError = true;
            nonNullStackTrace = s != null;
          },
        );
        try {
          await f;
        } on String {
          caughtByHandler = true;
        }
        if (!completer.isCompleted) {
          completer.complete(null);
        }
      }, onError: (Object e, StackTrace s) {
        caughtByZone = true;
        if (!completer.isCompleted) {
          completer.complete(null);
        }
      }));
      time.elapse(const Duration(seconds: 1));
      time.flushMicrotasks();
      return completer.future;
    });

    expect(caughtByZone, false);
    expect(caughtByHandler, false);
    expect(caughtByOnError, true);
    expect(nonNullStackTrace, true);
  });
}
