// 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.

import 'dart:async';

import 'package:async/src/future_group.dart';
import 'package:test/test.dart';

import 'utils.dart';

void main() {
  FutureGroup futureGroup;
  setUp(() {
    futureGroup = new FutureGroup();
  });

  group("with no futures", () {
    test("never completes if nothing happens", () async {
      var completed = false;
      futureGroup.future.then((_) => completed = true);

      await flushMicrotasks();
      expect(completed, isFalse);
    });

    test("completes once it's closed", () {
      expect(futureGroup.future, completion(isEmpty));
      futureGroup.close();
    });
  });

  group("with a future that already completed", () {
    test("never completes if nothing happens", () async {
      futureGroup.add(new Future.value());
      await flushMicrotasks();

      var completed = false;
      futureGroup.future.then((_) => completed = true);

      await flushMicrotasks();
      expect(completed, isFalse);
    });

    test("completes once it's closed", () async {
      futureGroup.add(new Future.value());
      await flushMicrotasks();

      expect(futureGroup.future, completes);
      futureGroup.close();
    });

    test("completes to that future's value", () {
      futureGroup.add(new Future.value(1));
      futureGroup.close();
      expect(futureGroup.future, completion(equals([1])));
    });

    test("completes to that future's error, even if it's not closed", () {
      futureGroup.add(new Future.error("error"));
      expect(futureGroup.future, throwsA("error"));
    });
  });

  test("completes once all contained futures complete", () async {
    var completer1 = new Completer();
    var completer2 = new Completer();
    var completer3 = new Completer();

    futureGroup.add(completer1.future);
    futureGroup.add(completer2.future);
    futureGroup.add(completer3.future);
    futureGroup.close();

    var completed = false;
    futureGroup.future.then((_) => completed = true);

    completer1.complete();
    await flushMicrotasks();
    expect(completed, isFalse);

    completer2.complete();
    await flushMicrotasks();
    expect(completed, isFalse);

    completer3.complete();
    await flushMicrotasks();
    expect(completed, isTrue);
  });

  test("completes to the values of the futures in order of addition", () {
    var completer1 = new Completer();
    var completer2 = new Completer();
    var completer3 = new Completer();

    futureGroup.add(completer1.future);
    futureGroup.add(completer2.future);
    futureGroup.add(completer3.future);
    futureGroup.close();

    // Complete the completers in reverse order to prove that that doesn't
    // affect the result order.
    completer3.complete(3);
    completer2.complete(2);
    completer1.complete(1);
    expect(futureGroup.future, completion(equals([1, 2, 3])));
  });

  test("completes to the first error to be emitted, even if it's not closed",
      () {
    var completer1 = new Completer();
    var completer2 = new Completer();
    var completer3 = new Completer();

    futureGroup.add(completer1.future);
    futureGroup.add(completer2.future);
    futureGroup.add(completer3.future);

    completer2.completeError("error 2");
    completer1.completeError("error 1");
    expect(futureGroup.future, throwsA("error 2"));
  });

  group("onIdle:", () {
    test("emits an event when the last pending future completes", () async {
      var idle = false;
      futureGroup.onIdle.listen((_) => idle = true);

      var completer1 = new Completer();
      var completer2 = new Completer();
      var completer3 = new Completer();

      futureGroup.add(completer1.future);
      futureGroup.add(completer2.future);
      futureGroup.add(completer3.future);

      await flushMicrotasks();
      expect(idle, isFalse);
      expect(futureGroup.isIdle, isFalse);

      completer1.complete();
      await flushMicrotasks();
      expect(idle, isFalse);
      expect(futureGroup.isIdle, isFalse);

      completer2.complete();
      await flushMicrotasks();
      expect(idle, isFalse);
      expect(futureGroup.isIdle, isFalse);

      completer3.complete();
      await flushMicrotasks();
      expect(idle, isTrue);
      expect(futureGroup.isIdle, isTrue);
    });

    test("emits an event each time it becomes idle", () async {
      var idle = false;
      futureGroup.onIdle.listen((_) => idle = true);

      var completer = new Completer();
      futureGroup.add(completer.future);

      completer.complete();
      await flushMicrotasks();
      expect(idle, isTrue);
      expect(futureGroup.isIdle, isTrue);

      idle = false;
      completer = new Completer();
      futureGroup.add(completer.future);

      await flushMicrotasks();
      expect(idle, isFalse);
      expect(futureGroup.isIdle, isFalse);

      completer.complete();
      await flushMicrotasks();
      expect(idle, isTrue);
      expect(futureGroup.isIdle, isTrue);
    });

    test("emits an event when the group closes", () async {
      // It's important that the order of events here stays consistent over
      // time, since code may rely on it in subtle ways.
      var idle = false;
      var onIdleDone = false;
      var futureFired = false;

      futureGroup.onIdle.listen(expectAsync1((_) {
        expect(futureFired, isFalse);
        idle = true;
      }), onDone: expectAsync0(() {
        expect(idle, isTrue);
        expect(futureFired, isFalse);
        onIdleDone = true;
      }));

      futureGroup.future.then(expectAsync1((_) {
        expect(idle, isTrue);
        expect(onIdleDone, isTrue);
        futureFired = true;
      }));

      var completer = new Completer();
      futureGroup.add(completer.future);
      futureGroup.close();

      await flushMicrotasks();
      expect(idle, isFalse);
      expect(futureGroup.isIdle, isFalse);

      completer.complete();
      await flushMicrotasks();
      expect(idle, isTrue);
      expect(futureGroup.isIdle, isTrue);
      expect(futureFired, isTrue);
    });
  });
}
