// Copyright (c) 2014, 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 "dart:async";
import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";

class Trace {
  String trace = "";
  record(x) {
    trace += x.toString();
  }

  toString() => trace;
}

Stream makeMeAStream() {
  return timedCounter(5);
}

Trace t1 = new Trace();

Future consumeOne() async {
  // Equivalent to await for (x in makeMeAStream()) { ... }
  var s = makeMeAStream();
  var it = new StreamIterator(s);
  while (await it.moveNext()) {
    var x = it.current;
    t1.record(x);
  }
  t1.record("X");
}

Trace t2 = new Trace();

Future consumeTwo() async {
  await for (var x in makeMeAStream()) {
    t2.record(x);
  }
  t2.record("Y");
}

Trace t3 = new Trace();

Future consumeNested() async {
  await for (var x in makeMeAStream()) {
    t3.record(x);
    await for (var y in makeMeAStream()) {
      t3.record(y);
    }
    t3.record("|");
  }
  t3.record("Z");
}

Trace t4 = new Trace();

Future consumeSomeOfInfinite() async {
  int i = 0;
  await for (var x in infiniteStream()) {
    i++;
    if (i > 10) break;
    t4.record(x);
  }
  t4.record("U");
}

main() {
  var f1 = consumeOne();
  t1.record("T1:");

  var f2 = consumeTwo();
  t2.record("T2:");

  var f3 = consumeNested();
  t3.record("T3:");

  var f4 = consumeSomeOfInfinite();
  t4.record("T4:");

  asyncStart();
  Future.wait([f1, f2, f3, f4]).then((_) {
    Expect.equals("T1:12345X", t1.toString());
    Expect.equals("T2:12345Y", t2.toString());
    Expect.equals("T3:112345|212345|312345|412345|512345|Z", t3.toString());
    Expect.equals("T4:12345678910U", t4.toString());
    asyncEnd();
  });
}

// Create a stream that produces numbers [1, 2, ... maxCount]
Stream timedCounter(int maxCount) {
  StreamController controller;
  Timer timer;
  int counter = 0;

  void tick(_) {
    counter++;
    controller.add(counter); // Ask stream to send counter values as event.
    if (counter >= maxCount) {
      timer.cancel();
      controller.close(); //    Ask stream to shut down and tell listeners.
    }
  }

  void startTimer() {
    timer = new Timer.periodic(const Duration(milliseconds: 10), tick);
  }

  void stopTimer() {
    if (timer != null) {
      timer.cancel();
      timer = null;
    }
  }

  controller = new StreamController(
      onListen: startTimer,
      onPause: stopTimer,
      onResume: startTimer,
      onCancel: stopTimer);

  return controller.stream;
}

// Create a stream that produces numbers [1, 2, ... ]
Stream infiniteStream() {
  StreamController controller;
  Timer timer;
  int counter = 0;

  void tick(_) {
    counter++;
    controller.add(counter); // Ask stream to send counter values as event.
  }

  void startTimer() {
    timer = new Timer.periodic(const Duration(milliseconds: 10), tick);
  }

  void stopTimer() {
    if (timer != null) {
      timer.cancel();
      timer = null;
    }
  }

  controller = new StreamController(
      onListen: startTimer,
      onPause: stopTimer,
      onResume: startTimer,
      onCancel: stopTimer);

  return controller.stream;
}
