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

// Test that async functions don't zone-register their callbacks for each
// await. Async functions should register their callback once in the beginning
// and then reuse it for all awaits in their body.
// This has two advantages: it is faster, when there are several awaits (on
// the Future class from dart:async), and it avoids zone-nesting when tracing
// stacktraces.
// See http://dartbug.com/23394 for more information.

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

gee(i) async {
  return await i;
}

bar() async* {
  var i = 0;
  while (true) yield await gee(i++);
}

awaitForTest() async {
  var sum = 0;
  await for (var x in bar().take(100)) {
    sum += x;
  }
  Expect.equals(4950, sum);
}

awaitTest() async {
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  await null;
  return await 499;
}

runTests() async {
  await awaitTest();
  await awaitForTest();
}

var depth = 0;

var depthIncreases = 0;

increaseDepth() {
  depthIncreases++;
  depth++;
  // The async/await code should not register callbacks recursively in the
  // then-calls. As such the depth should never grow too much. We don't want
  // to commit to a specific value, since implementations still have some
  // room in how async/await is implemented, but 20 should be safe.
  Expect.isTrue(depth < 20);
}

ZoneCallback<R> registerCallback<R>(
    Zone self, ZoneDelegate parent, Zone zone, R f()) {
  var oldDepth = depth;
  increaseDepth();
  return parent.registerCallback(zone, () {
    depth = oldDepth;
    return f();
  });
}

ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(
    Zone self, ZoneDelegate parent, Zone zone, R f(T arg)) {
  var oldDepth = depth;
  increaseDepth();
  return parent.registerUnaryCallback(zone, (x) {
    depth = oldDepth;
    return f(x);
  });
}

ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(
    Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2)) {
  var oldDepth = depth;
  increaseDepth();
  return parent.registerBinaryCallback(zone, (x, y) {
    depth = oldDepth;
    return f(x, y);
  });
}

void sm(Zone self, ZoneDelegate parent, Zone zone, f) {
  var oldDepth = depth;
  increaseDepth();
  return parent.scheduleMicrotask(zone, () {
    depth = oldDepth;
    return f();
  });
}

main() {
  asyncStart();
  var desc = new ZoneSpecification(
      registerCallback: registerCallback,
      registerUnaryCallback: registerUnaryCallback,
      registerBinaryCallback: registerBinaryCallback,
      scheduleMicrotask: sm);
  var future = runZoned(runTests, zoneSpecification: desc);
  future.then((_) => asyncEnd());
}
