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

// @dart = 2.9

import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import 'dart:async';

/**
 * We represent the current stack trace by an integer. From time to time we
 * increment the variable. This corresponds to a new stack trace.
 */
int stackTrace = 0;
List restoredStackTrace = [];

List events = [];

ZoneCallback<R> debugZoneRegisterCallback<R>(
    Zone self, ZoneDelegate parent, Zone origin, R f()) {
  List savedTrace = [stackTrace]..addAll(restoredStackTrace);
  return parent.registerCallback(origin, () {
    restoredStackTrace = savedTrace;
    return f();
  });
}

ZoneUnaryCallback<R, T> debugZoneRegisterUnaryCallback<R, T>(
    Zone self, ZoneDelegate parent, Zone origin, R f(T arg)) {
  List savedTrace = [stackTrace]..addAll(restoredStackTrace);
  return parent.registerUnaryCallback(origin, (arg) {
    restoredStackTrace = savedTrace;
    return f(arg);
  });
}

T debugZoneRun<T>(Zone self, ZoneDelegate parent, Zone origin, T f()) {
  stackTrace++;
  restoredStackTrace = [];
  return parent.run(origin, f);
}

R debugZoneRunUnary<R, T>(
    Zone self, ZoneDelegate parent, Zone origin, R f(T arg), T arg) {
  stackTrace++;
  restoredStackTrace = [];
  return parent.runUnary(origin, f, arg);
}

List expectedDebugTrace;

void debugUncaughtHandler(
    Zone self, ZoneDelegate parent, Zone origin, error, StackTrace stackTrace) {
  events.add("handling uncaught error $error");
  Expect.listEquals(expectedDebugTrace, restoredStackTrace);
  // Suppress the error and don't propagate to parent.
}

const DEBUG_SPECIFICATION = const ZoneSpecification(
    registerCallback: debugZoneRegisterCallback,
    registerUnaryCallback: debugZoneRegisterUnaryCallback,
    run: debugZoneRun,
    runUnary: debugZoneRunUnary,
    handleUncaughtError: debugUncaughtHandler);

main() {
  Completer done = new Completer();

  // runGuarded calls run, captures the synchronous error (if any) and
  // gives that one to handleUncaughtError.

  Expect.identical(Zone.root, Zone.current);
  Zone forked;
  forked = Zone.current.fork(specification: DEBUG_SPECIFICATION);

  asyncStart();

  int openTests = 0;

  openTests++;
  forked.run(() {
    int forkTrace = stackTrace;
    scheduleMicrotask(() {
      int scheduleMicrotaskTrace = stackTrace;
      scheduleMicrotask(() {
        expectedDebugTrace = [scheduleMicrotaskTrace, forkTrace];
        openTests--;
        if (openTests == 0) {
          done.complete();
        }
        throw "foo";
      });
      expectedDebugTrace = [forkTrace];
      throw "bar";
    });
  });

  Expect.listEquals([], restoredStackTrace);
  Zone forked2 = forked.fork();
  Zone forked3 = forked2.fork();
  int fork2Trace;
  int fork3Trace;
  var f2;
  var globalTrace = stackTrace;
  var f = forked3.bindCallback(() {
    Expect.identical(forked3, Zone.current);
    fork2Trace = stackTrace;
    f2 = forked2.bindCallback(() {
      Expect.identical(forked2, Zone.current);
      Expect.listEquals([fork2Trace, globalTrace], restoredStackTrace);
      fork3Trace = stackTrace;
      openTests--;
      if (openTests == 0) {
        done.complete();
      }
      scheduleMicrotask(() {
        expectedDebugTrace = [fork3Trace, fork2Trace, globalTrace];
        throw "gee";
      });
    });
  });
  openTests++;
  f();
  f2();

  done.future.whenComplete(() {
    // We don't really care for the order.
    events.sort();
    Expect.listEquals([
      "handling uncaught error bar",
      "handling uncaught error foo",
      "handling uncaught error gee"
    ], events);
    asyncEnd();
  });
}
