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

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(FormatException());
    });

    test(
        "shouldn't allow additional futures or streams once an error has been "
        'signaled', () {
      expect(errorGroup.done, throwsFormatException);
      errorGroup.signalError(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(FormatException());
    });

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

      completer.completeError(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(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(FormatException());
        }),
        completes,
      );
    });
  });
}
