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

// Test empty stream.
import "package:expect/expect.dart";
import "dart:async";
import 'package:expect/async_helper.dart';

main() async {
  await asyncTest(() async {
    // Is a `const` constructor.
    // Can be called with optional boolean to say whether broadcast or not.
    await asyncTest(() => emptyTest(const Stream<int>.empty(), true));
    await asyncTest(
      () => emptyTest(const Stream<int>.empty(broadcast: true), true),
    );
    await asyncTest(
      () => emptyTest(const Stream<int>.empty(broadcast: false), false),
    );

    // Check that the behavior is consistent with other empty multi-subscription
    // streams.
    await asyncTest(() => emptyTest(Stream<int>.fromIterable(<int>[]), false));
    await asyncTest(
      () =>
          emptyTest((StreamController<int>.broadcast()..close()).stream, true),
    );
    await asyncTest(
      () => emptyTest(Stream<int>.multi((c) => c.close()), false),
    );
  });
  await flushMicrotasks();
}

// Function which fails the test if it gets called.
void unreachable([a, b]) {
  Expect.fail("Unreachable");
}

/// Check that something happens once.
class Checker {
  bool checked = false;
  void check() {
    if (checked) Expect.fail("Checked more than once");
    checked = true;
  }
}

Future<void> emptyTest(Stream<int> s, bool broadcast) async {
  var checker = Checker();
  // Respects type parameter (not a `Stream<Never>`)
  Expect.notType<Stream<String>>(s);

  // Has the expected `isBroadcast`.
  Expect.equals(broadcast, s.isBroadcast);

  StreamSubscription<int> sub = s.listen(
    unreachable,
    onError: unreachable,
    onDone: checker.check,
  );
  // Type parameter of subscription respects stream.
  // Not a `StreamSubscription<Never>`.
  Expect.isFalse(sub is StreamSubscription<String>);

  Expect.isFalse(sub.isPaused);
  // Doesn't do callback immediately in response to listen.
  Expect.isFalse(checker.checked);
  await flushMicrotasks();
  // Completes eventually, after a microtask.
  Expect.isTrue(checker.checked);
  Expect.isFalse(sub.isPaused);

  // Can listen more than once, whether broadcast stream or not.
  checker = Checker();
  StreamSubscription<int> sub2 = s.listen(
    unreachable,
    onError: unreachable,
    onDone: checker.check,
  );
  // Respects pauses.
  sub2.pause();
  Expect.isTrue(sub2.isPaused);
  sub2.pause();
  Expect.isTrue(sub2.isPaused);
  sub2.pause(Future<int>.value(0));
  Expect.isTrue(sub2.isPaused);

  await flushMicrotasks();
  Expect.isTrue(sub2.isPaused);
  Expect.isFalse(checker.checked);

  // Resumes when all pauses resumed.
  sub2.resume();
  Expect.isTrue(sub2.isPaused);
  await flushMicrotasks();
  Expect.isFalse(checker.checked);
  Expect.isTrue(sub2.isPaused);

  sub2.resume();
  Expect.isFalse(sub2.isPaused);
  await flushMicrotasks();
  Expect.isTrue(checker.checked);
  Expect.isFalse(sub2.isPaused);

  // Can't pause after done.
  sub2.pause(Future<int>.value(0));
  Expect.isFalse(sub2.isPaused);
  sub2.pause();
  Expect.isFalse(sub2.isPaused);

  // Respects cancel.
  var sub3 = s.listen(unreachable, onError: unreachable, onDone: unreachable);
  sub3.cancel();
  sub3.onDone(unreachable);
  Expect.isFalse(sub3.isPaused);
  await flushMicrotasks();
  Expect.isFalse(sub3.isPaused);

  // Can't pause after cancel
  sub3.pause();
  Expect.isFalse(sub3.isPaused);
  sub3.pause(Future<int>.value(0));
  Expect.isFalse(sub3.isPaused);
  // No errors.

  // Respects cancel while paused.
  var sub4 = s.listen(unreachable, onError: unreachable, onDone: unreachable);
  sub4.pause();
  sub4.cancel();
  sub4.onDone(unreachable);
  await flushMicrotasks();
  sub4.resume();
  await flushMicrotasks();

  // Check that the stream is zone-aware.
  // Registers onDone callback.
  var log = [];
  late final Zone zone;

  void callback1() {
    // Run in correct zone.
    Expect.equals(zone, Zone.current);
    log.add("don1");
  }

  void callback2() {
    // Run in correct zone.
    Expect.equals(zone, Zone.current);
    log.add("don2");
  }

  zone = Zone.current.fork(
    specification: ZoneSpecification(
      registerCallback: <R>(s, p, z, f) {
        if (f == callback1) log.add("reg1");
        if (f == callback2) log.add("reg2");
        return p.registerCallback<R>(z, f);
      },
      run: <R>(s, p, z, f) {
        if (f == callback1) log.add("run1");
        if (f == callback2) log.add("run2");
        return p.run<R>(z, f);
      },
    ),
  );

  await zone.run(() async {
    var s = Stream<int>.empty();

    var sub = s.listen(unreachable, onError: unreachable, onDone: callback1);
    sub.onDone(callback2);
  });
  await flushMicrotasks();
  Expect.listEquals(["reg1", "reg2", "run2", "don2"], log);
}

Future flushMicrotasks() => new Future.delayed(Duration.zero);
