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

@TestOn('vm')
library;

import 'dart:async';

import 'package:pub/src/error_group.dart';
import 'package:test/test.dart';

late ErrorGroup errorGroup;

// TODO(nweiz): once there's a global error handler, we should test that it does
// and does not get called at appropriate times. See issue 5958.
//
// One particular thing we should test that has no tests now is that a stream
// that has a subscription added and subsequently canceled counts as having no
// listeners.

void main() {
  group('with no futures or streams', () {
    setUp(() {
      errorGroup = ErrorGroup();
    });

    test('should pass signaled errors to .done', () {
      expect(errorGroup.done, throwsFormatException);
      errorGroup.signalError(const FormatException());
    });

    test("shouldn't allow additional futures or streams once an error has been "
        'signaled', () {
      expect(errorGroup.done, throwsFormatException);
      errorGroup.signalError(const FormatException());

      expect(
        () => errorGroup.registerFuture(Future<void>.value()),
        throwsStateError,
      );
      expect(
        () => errorGroup.registerStream(
          StreamController<void>(sync: true).stream,
        ),
        throwsStateError,
      );
    });
  });

  group('with a single future', () {
    late Completer completer;
    late Future future;

    setUp(() {
      errorGroup = ErrorGroup();
      completer = Completer();
      future = errorGroup.registerFuture(completer.future);
    });

    test('should pass through a value from the future', () {
      expect(future, completion(equals('value')));
      expect(errorGroup.done, completes);
      completer.complete('value');
    });

    test("shouldn't allow additional futures or streams once .done has "
        'been called', () {
      completer.complete('value');

      expect(
        completer.future.then(
          (_) => errorGroup.registerFuture(Future<void>.value()),
        ),
        throwsStateError,
      );
      expect(
        completer.future.then(
          (_) => errorGroup.registerStream(
            StreamController<void>(sync: true).stream,
          ),
        ),
        throwsStateError,
      );
    });

    test('should pass through an exception from the future if it has a '
        'listener', () {
      expect(future, throwsFormatException);
      // errorGroup shouldn't top-level the exception
      completer.completeError(const FormatException());
    });

    test('should notify the error group of an exception from the future even '
        'if it has a listener', () {
      expect(future, throwsFormatException);
      expect(errorGroup.done, throwsFormatException);
      completer.completeError(const FormatException());
    });

    test('should pass a signaled exception to the future if it has a listener '
        'and should ignore a subsequent value from that future', () {
      expect(future, throwsFormatException);
      // errorGroup shouldn't top-level the exception
      errorGroup.signalError(const FormatException());
      completer.complete('value');
    });

    test('should pass a signaled exception to the future if it has a listener '
        'and should ignore a subsequent exception from that future', () {
      expect(future, throwsFormatException);
      // errorGroup shouldn't top-level the exception
      errorGroup.signalError(const FormatException());
      completer.completeError(ArgumentError());
    });

    test('should notify the error group of a signaled exception even if the '
        'future has a listener', () {
      expect(future, throwsFormatException);
      expect(errorGroup.done, throwsFormatException);
      errorGroup.signalError(const FormatException());
    });

    test('should complete .done if the future receives a value even if the '
        "future doesn't have a listener", () {
      expect(errorGroup.done, completes);
      completer.complete('value');

      // A listener added afterwards should receive the value
      expect(errorGroup.done.then((_) => future), completion(equals('value')));
    });

    test('should pipe an exception from the future to .done if the future '
        "doesn't have a listener", () {
      expect(errorGroup.done, throwsFormatException);
      completer.completeError(const FormatException());

      // A listener added afterwards should receive the exception
      expect(
        errorGroup.done.catchError((_) {
          expect(future, throwsFormatException);
        }),
        completes,
      );
    });

    test("should pass a signaled exception to .done if the future doesn't have "
        'a listener', () {
      expect(errorGroup.done, throwsFormatException);
      errorGroup.signalError(const FormatException());

      // A listener added afterwards should receive the exception
      expect(
        errorGroup.done.catchError((_) {
          completer.complete('value'); // should be ignored
          expect(future, throwsFormatException);
        }),
        completes,
      );
    });
  });

  group('with multiple futures', () {
    late Completer completer1;
    late Completer completer2;
    late Future future1;
    late Future future2;

    setUp(() {
      errorGroup = ErrorGroup();
      completer1 = Completer();
      completer2 = Completer();
      future1 = errorGroup.registerFuture(completer1.future);
      future2 = errorGroup.registerFuture(completer2.future);
    });

    test('should pipe exceptions from one future to the other and to '
        '.complete', () {
      expect(future1, throwsFormatException);
      expect(future2, throwsFormatException);
      expect(errorGroup.done, throwsFormatException);

      completer1.completeError(const FormatException());
    });

    test('each future should be able to complete with a value '
        'independently', () {
      expect(future1, completion(equals('value1')));
      expect(future2, completion(equals('value2')));
      expect(errorGroup.done, completes);

      completer1.complete('value1');
      completer2.complete('value2');
    });

    test("shouldn't throw a top-level exception if a future receives an error "
        'after the other listened future completes', () {
      expect(future1, completion(equals('value')));
      completer1.complete('value');

      expect(
        future1.then((_) {
          // shouldn't cause a top-level exception
          completer2.completeError(const FormatException());
        }),
        completes,
      );
    });

    test("shouldn't throw a top-level exception if an error is signaled after "
        'one listened future completes', () {
      expect(future1, completion(equals('value')));
      completer1.complete('value');

      expect(
        future1.then((_) {
          // shouldn't cause a top-level exception
          errorGroup.signalError(const FormatException());
        }),
        completes,
      );
    });
  });

  group('with a single stream', () {
    late StreamController controller;
    late Stream stream;

    setUp(() {
      errorGroup = ErrorGroup();
      controller = StreamController.broadcast(sync: true);
      stream = errorGroup.registerStream(controller.stream);
    });

    test('should pass through values from the stream', () {
      final iter = StreamIterator(stream);
      iter.moveNext().then((hasNext) {
        expect(hasNext, isTrue);
        expect(iter.current, equals(1));
        iter.moveNext().then((hasNext) {
          expect(hasNext, isTrue);
          expect(iter.current, equals(2));
          expect(iter.moveNext(), completion(isFalse));
        });
      });
      expect(errorGroup.done, completes);

      controller
        ..add(1)
        ..add(2)
        ..close();
    });

    test('should pass through an error from the stream if it has a '
        'listener', () {
      expect(stream.first, throwsFormatException);
      // errorGroup shouldn't top-level the exception
      controller.addError(const FormatException());
    });

    test('should notify the error group of an exception from the stream even '
        'if it has a listener', () {
      expect(stream.first, throwsFormatException);
      expect(errorGroup.done, throwsFormatException);
      controller.addError(const FormatException());
    });

    test('should pass a signaled exception to the stream if it has a listener '
        'and should unsubscribe that stream', () {
      // errorGroup shouldn't top-level the exception
      expect(stream.first, throwsFormatException);
      errorGroup.signalError(const FormatException());

      expect(() => controller.add('value'), returnsNormally);
    });

    test('should notify the error group of a signaled exception even if the '
        'stream has a listener', () {
      expect(stream.first, throwsFormatException);
      expect(errorGroup.done, throwsFormatException);
      errorGroup.signalError(const FormatException());
    });

    test('should see one value and complete .done when the stream is done even '
        "if the stream doesn't have a listener", () {
      expect(errorGroup.done, completes);
      controller.add('value');
      controller.close();

      // Now that broadcast controllers have been removed a listener should
      // see the value that has been put into the controller.
      expect(
        errorGroup.done.then((_) => stream.toList()),
        completion(equals(['value'])),
      );
    });
  });

  group('with a single single-subscription stream', () {
    late StreamController controller;
    late Stream stream;

    setUp(() {
      errorGroup = ErrorGroup();
      controller = StreamController(sync: true);
      stream = errorGroup.registerStream(controller.stream);
    });

    test('should complete .done when the stream is done even if the stream '
        "doesn't have a listener", () {
      expect(errorGroup.done, completes);
      controller.add('value');
      controller.close();

      // A listener added afterwards should receive the value
      expect(
        errorGroup.done.then((_) => stream.toList()),
        completion(equals(['value'])),
      );
    });

    test('should pipe an exception from the stream to .done if the stream '
        "doesn't have a listener", () {
      expect(errorGroup.done, throwsFormatException);
      controller.addError(const FormatException());

      // A listener added afterwards should receive the exception
      expect(
        errorGroup.done.catchError((_) {
          controller.add('value'); // should be ignored
          expect(stream.first, throwsFormatException);
        }),
        completes,
      );
    });

    test("should pass a signaled exception to .done if the stream doesn't "
        'have a listener', () {
      expect(errorGroup.done, throwsFormatException);
      errorGroup.signalError(const FormatException());

      // A listener added afterwards should receive the exception
      expect(
        errorGroup.done.catchError((_) {
          controller.add('value'); // should be ignored
          expect(stream.first, throwsFormatException);
        }),
        completes,
      );
    });
  });

  group('with multiple streams', () {
    late StreamController controller1;
    late StreamController controller2;
    late Stream stream1;
    late Stream stream2;

    setUp(() {
      errorGroup = ErrorGroup();
      controller1 = StreamController.broadcast(sync: true);
      controller2 = StreamController.broadcast(sync: true);
      stream1 = errorGroup.registerStream(controller1.stream);
      stream2 = errorGroup.registerStream(controller2.stream);
    });

    test(
      'should pipe exceptions from one stream to the other and to .done',
      () {
        expect(stream1.first, throwsFormatException);
        expect(stream2.first, throwsFormatException);
        expect(errorGroup.done, throwsFormatException);

        controller1.addError(const FormatException());
      },
    );

    test('each future should be able to emit values independently', () {
      expect(stream1.toList(), completion(equals(['value1.1', 'value1.2'])));
      expect(stream2.toList(), completion(equals(['value2.1', 'value2.2'])));
      expect(errorGroup.done, completes);

      controller1
        ..add('value1.1')
        ..add('value1.2')
        ..close();
      controller2
        ..add('value2.1')
        ..add('value2.2')
        ..close();
    });

    test("shouldn't throw a top-level exception if a stream receives an error "
        'after the other listened stream completes', () {
      final signal = Completer<void>();
      expect(
        stream1.toList().whenComplete(signal.complete),
        completion(equals(['value1', 'value2'])),
      );
      controller1
        ..add('value1')
        ..add('value2')
        ..close();

      expect(
        signal.future.then((_) {
          // shouldn't cause a top-level exception
          controller2.addError(const FormatException());
        }),
        completes,
      );
    });

    test("shouldn't throw a top-level exception if an error is signaled after "
        'one listened stream completes', () {
      final signal = Completer<void>();
      expect(
        stream1.toList().whenComplete(signal.complete),
        completion(equals(['value1', 'value2'])),
      );
      controller1
        ..add('value1')
        ..add('value2')
        ..close();

      expect(
        signal.future.then((_) {
          // shouldn't cause a top-level exception
          errorGroup.signalError(const FormatException());
        }),
        completes,
      );
    });
  });

  group('with a stream and a future', () {
    late StreamController controller;
    late Stream stream;
    late Completer completer;
    late Future future;

    setUp(() {
      errorGroup = ErrorGroup();
      controller = StreamController.broadcast(sync: true);
      stream = errorGroup.registerStream(controller.stream);
      completer = Completer();
      future = errorGroup.registerFuture(completer.future);
    });

    test('should pipe exceptions from the stream to the future', () {
      expect(stream.first, throwsFormatException);
      expect(future, throwsFormatException);
      expect(errorGroup.done, throwsFormatException);

      controller.addError(const FormatException());
    });

    test('should pipe exceptions from the future to the stream', () {
      expect(stream.first, throwsFormatException);
      expect(future, throwsFormatException);
      expect(errorGroup.done, throwsFormatException);

      completer.completeError(const FormatException());
    });

    test('the stream and the future should be able to complete/emit values '
        'independently', () {
      expect(stream.toList(), completion(equals(['value1.1', 'value1.2'])));
      expect(future, completion(equals('value2.0')));
      expect(errorGroup.done, completes);

      controller
        ..add('value1.1')
        ..add('value1.2')
        ..close();
      completer.complete('value2.0');
    });

    test(
      "shouldn't throw a top-level exception if the stream receives an error "
      'after the listened future completes',
      () {
        expect(future, completion(equals('value')));
        completer.complete('value');

        expect(
          future.then((_) {
            // shouldn't cause a top-level exception
            controller.addError(const FormatException());
          }),
          completes,
        );
      },
    );

    test("shouldn't throw a top-level exception if the future receives an "
        'error after the listened stream completes', () {
      final signal = Completer<void>();
      expect(
        stream.toList().whenComplete(signal.complete),
        completion(equals(['value1', 'value2'])),
      );
      controller
        ..add('value1')
        ..add('value2')
        ..close();

      expect(
        signal.future.then((_) {
          // shouldn't cause a top-level exception
          completer.completeError(const FormatException());
        }),
        completes,
      );
    });
  });
}
