// Copyright 2014 The Flutter Authors. 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 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/scheduler.dart' show SchedulerBinding, timeDilation;
import 'package:flutter_test/flutter_test.dart';

import '../image_data.dart';
import 'fake_codec.dart';
import 'mocks_for_image_cache.dart';

class FakeFrameInfo implements FrameInfo {
  const FakeFrameInfo(this._duration, this._image);

  final Duration _duration;
  final Image _image;

  @override
  Duration get duration => _duration;

  @override
  Image get image => _image;

  int get imageHandleCount => image.debugGetOpenHandleStackTraces()!.length;

  FakeFrameInfo clone() {
    return FakeFrameInfo(
      _duration,
      _image.clone(),
    );
  }
}

class MockCodec implements Codec {
  @override
  late int frameCount;

  @override
  late int repetitionCount;

  int numFramesAsked = 0;

  Completer<FrameInfo> _nextFrameCompleter = Completer<FrameInfo>();

  @override
  Future<FrameInfo> getNextFrame() {
    numFramesAsked += 1;
    return _nextFrameCompleter.future;
  }

  void completeNextFrame(FrameInfo frameInfo) {
    _nextFrameCompleter.complete(frameInfo);
    _nextFrameCompleter = Completer<FrameInfo>();
  }

  void failNextFrame(String err) {
    _nextFrameCompleter.completeError(err);
  }

  @override
  void dispose() { }

}

class FakeEventReportingImageStreamCompleter extends ImageStreamCompleter {
  FakeEventReportingImageStreamCompleter({Stream<ImageChunkEvent>? chunkEvents}) {
    if (chunkEvents != null) {
      chunkEvents.listen((ImageChunkEvent event) {
          reportImageChunkEvent(event);
        },
      );
    }
  }
}

void main() {
  late Image image20x10;
  late Image image200x100;
  setUp(() async {
    image20x10 = await createTestImage(width: 20, height: 10);
    image200x100 = await createTestImage(width: 200, height: 100);
  });

  testWidgets('Codec future fails', (WidgetTester tester) async {
    final Completer<Codec> completer = Completer<Codec>();
    MultiFrameImageStreamCompleter(
      codec: completer.future,
      scale: 1.0,
    );
    completer.completeError('failure message');
    await tester.idle();
    expect(tester.takeException(), 'failure message');
  });

  testWidgets('Decoding starts when a listener is added after codec is ready', (WidgetTester tester) async {
    final Completer<Codec> completer = Completer<Codec>();
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 1;
    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: completer.future,
      scale: 1.0,
    );

    completer.complete(mockCodec);
    await tester.idle();
    expect(mockCodec.numFramesAsked, 0);

    void listener(ImageInfo image, bool synchronousCall) { }
    imageStream.addListener(ImageStreamListener(listener));
    await tester.idle();
    expect(mockCodec.numFramesAsked, 1);
  });

  testWidgets('Decoding starts when a codec is ready after a listener is added', (WidgetTester tester) async {
    final Completer<Codec> completer = Completer<Codec>();
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 1;
    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: completer.future,
      scale: 1.0,
    );

    void listener(ImageInfo image, bool synchronousCall) { }
    imageStream.addListener(ImageStreamListener(listener));
    await tester.idle();
    expect(mockCodec.numFramesAsked, 0);

    completer.complete(mockCodec);
    await tester.idle();
    expect(mockCodec.numFramesAsked, 1);
  });

  testWidgets('Decoding does not crash when disposed', (WidgetTester tester) async {
    final Completer<Codec> completer = Completer<Codec>();
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 1;
    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: completer.future,
      scale: 1.0,
    );

    completer.complete(mockCodec);
    await tester.idle();
    expect(mockCodec.numFramesAsked, 0);

    void listener(ImageInfo image, bool synchronousCall) { }
    final ImageStreamListener streamListener = ImageStreamListener(listener);
    imageStream.addListener(streamListener);
    await tester.idle();
    expect(mockCodec.numFramesAsked, 1);

    final FrameInfo frame = FakeFrameInfo(const Duration(milliseconds: 200), image20x10);
    mockCodec.completeNextFrame(frame);
    imageStream.removeListener(streamListener);
    await tester.idle();
  });

  testWidgets('Chunk events of base ImageStreamCompleter are delivered', (WidgetTester tester) async {
    final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
    final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>();
    final ImageStreamCompleter imageStream = FakeEventReportingImageStreamCompleter(
      chunkEvents: streamController.stream,
    );

    imageStream.addListener(ImageStreamListener(
      (ImageInfo image, bool synchronousCall) { },
      onChunk: (ImageChunkEvent event) {
        chunkEvents.add(event);
      },
    ));
    streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 1, expectedTotalBytes: 3));
    streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 2, expectedTotalBytes: 3));
    await tester.idle();

    expect(chunkEvents.length, 2);
    expect(chunkEvents[0].cumulativeBytesLoaded, 1);
    expect(chunkEvents[0].expectedTotalBytes, 3);
    expect(chunkEvents[1].cumulativeBytesLoaded, 2);
    expect(chunkEvents[1].expectedTotalBytes, 3);
  });

  testWidgets('Chunk events of base ImageStreamCompleter are not buffered before listener registration', (WidgetTester tester) async {
    final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
    final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>();
    final ImageStreamCompleter imageStream = FakeEventReportingImageStreamCompleter(
      chunkEvents: streamController.stream,
    );

    streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 1, expectedTotalBytes: 3));
    await tester.idle();
    imageStream.addListener(ImageStreamListener(
      (ImageInfo image, bool synchronousCall) { },
      onChunk: (ImageChunkEvent event) {
        chunkEvents.add(event);
      },
    ));
    streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 2, expectedTotalBytes: 3));
    await tester.idle();

    expect(chunkEvents.length, 1);
    expect(chunkEvents[0].cumulativeBytesLoaded, 2);
    expect(chunkEvents[0].expectedTotalBytes, 3);
  });

  testWidgets('Chunk events of MultiFrameImageStreamCompleter are delivered', (WidgetTester tester) async {
    final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
    final Completer<Codec> completer = Completer<Codec>();
    final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>();
    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: completer.future,
      chunkEvents: streamController.stream,
      scale: 1.0,
    );

    imageStream.addListener(ImageStreamListener(
      (ImageInfo image, bool synchronousCall) { },
      onChunk: (ImageChunkEvent event) {
        chunkEvents.add(event);
      },
    ));
    streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 1, expectedTotalBytes: 3));
    streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 2, expectedTotalBytes: 3));
    await tester.idle();

    expect(chunkEvents.length, 2);
    expect(chunkEvents[0].cumulativeBytesLoaded, 1);
    expect(chunkEvents[0].expectedTotalBytes, 3);
    expect(chunkEvents[1].cumulativeBytesLoaded, 2);
    expect(chunkEvents[1].expectedTotalBytes, 3);
  });

  testWidgets('Chunk events of MultiFrameImageStreamCompleter are not buffered before listener registration', (WidgetTester tester) async {
    final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
    final Completer<Codec> completer = Completer<Codec>();
    final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>();
    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: completer.future,
      chunkEvents: streamController.stream,
      scale: 1.0,
    );

    streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 1, expectedTotalBytes: 3));
    await tester.idle();
    imageStream.addListener(ImageStreamListener(
      (ImageInfo image, bool synchronousCall) { },
      onChunk: (ImageChunkEvent event) {
        chunkEvents.add(event);
      },
    ));
    streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 2, expectedTotalBytes: 3));
    await tester.idle();

    expect(chunkEvents.length, 1);
    expect(chunkEvents[0].cumulativeBytesLoaded, 2);
    expect(chunkEvents[0].expectedTotalBytes, 3);
  });

  testWidgets('Chunk errors are reported', (WidgetTester tester) async {
    final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
    final Completer<Codec> completer = Completer<Codec>();
    final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>();
    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: completer.future,
      chunkEvents: streamController.stream,
      scale: 1.0,
    );

    imageStream.addListener(ImageStreamListener(
      (ImageInfo image, bool synchronousCall) { },
      onChunk: (ImageChunkEvent event) {
        chunkEvents.add(event);
      },
    ));
    streamController.addError(Error());
    streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 2, expectedTotalBytes: 3));
    await tester.idle();

    expect(tester.takeException(), isNotNull);
    expect(chunkEvents.length, 1);
    expect(chunkEvents[0].cumulativeBytesLoaded, 2);
    expect(chunkEvents[0].expectedTotalBytes, 3);
  });

  testWidgets('getNextFrame future fails', (WidgetTester tester) async {
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 1;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    void listener(ImageInfo image, bool synchronousCall) { }
    imageStream.addListener(ImageStreamListener(listener));
    codecCompleter.complete(mockCodec);
    // MultiFrameImageStreamCompleter only sets an error handler for the next
    // frame future after the codec future has completed.
    // Idling here lets the MultiFrameImageStreamCompleter advance and set the
    // error handler for the nextFrame future.
    await tester.idle();

    mockCodec.failNextFrame('frame completion error');
    await tester.idle();

    expect(tester.takeException(), 'frame completion error');
  });

  testWidgets('ImageStream emits frame (static image)', (WidgetTester tester) async {
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 1;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    final List<ImageInfo> emittedImages = <ImageInfo>[];
    imageStream.addListener(ImageStreamListener((ImageInfo image, bool synchronousCall) {
      emittedImages.add(image);
    }));

    codecCompleter.complete(mockCodec);
    await tester.idle();

    final FrameInfo frame = FakeFrameInfo(const Duration(milliseconds: 200), image20x10);
    mockCodec.completeNextFrame(frame);
    await tester.idle();

    expect(emittedImages.every((ImageInfo info) => info.image.isCloneOf(frame.image)), true);
  });

  testWidgets('ImageStream emits frames (animated images)', (WidgetTester tester) async {
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 2;
    mockCodec.repetitionCount = -1;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    final List<ImageInfo> emittedImages = <ImageInfo>[];
    imageStream.addListener(ImageStreamListener((ImageInfo image, bool synchronousCall) {
      emittedImages.add(image);
    }));

    codecCompleter.complete(mockCodec);
    await tester.idle();

    final FrameInfo frame1 = FakeFrameInfo(const Duration(milliseconds: 200), image20x10);
    mockCodec.completeNextFrame(frame1);
    await tester.idle();
    // We are waiting for the next animation tick, so at this point no frames
    // should have been emitted.
    expect(emittedImages.length, 0);

    await tester.pump();
    expect(emittedImages.single.image.isCloneOf(frame1.image), true);

    final FrameInfo frame2 = FakeFrameInfo(const Duration(milliseconds: 400), image200x100);
    mockCodec.completeNextFrame(frame2);

    await tester.pump(const Duration(milliseconds: 100));
    // The duration for the current frame was 200ms, so we don't emit the next
    // frame yet even though it is ready.
    expect(emittedImages.length, 1);

    await tester.pump(const Duration(milliseconds: 100));
    expect(emittedImages[0].image.isCloneOf(frame1.image), true);
    expect(emittedImages[1].image.isCloneOf(frame2.image), true);

    // Let the pending timer for the next frame to complete so we can cleanly
    // quit the test without pending timers.
    await tester.pump(const Duration(milliseconds: 400));
  });

  testWidgets('animation wraps back', (WidgetTester tester) async {
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 2;
    mockCodec.repetitionCount = -1;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    final List<ImageInfo> emittedImages = <ImageInfo>[];
    imageStream.addListener(ImageStreamListener((ImageInfo image, bool synchronousCall) {
      emittedImages.add(image);
    }));

    codecCompleter.complete(mockCodec);
    await tester.idle();

    final FakeFrameInfo frame1 = FakeFrameInfo(const Duration(milliseconds: 200), image20x10);
    final FakeFrameInfo frame2 = FakeFrameInfo(const Duration(milliseconds: 400), image200x100);

    mockCodec.completeNextFrame(frame1.clone());
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(); // first animation frame shows on first app frame.
    mockCodec.completeNextFrame(frame2.clone());
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(const Duration(milliseconds: 200)); // emit 2nd frame.
    mockCodec.completeNextFrame(frame1.clone());
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(const Duration(milliseconds: 400)); // emit 3rd frame

    expect(emittedImages[0].image.isCloneOf(frame1.image), true);
    expect(emittedImages[1].image.isCloneOf(frame2.image), true);
    expect(emittedImages[2].image.isCloneOf(frame1.image), true);

    // Let the pending timer for the next frame to complete so we can cleanly
    // quit the test without pending timers.
    await tester.pump(const Duration(milliseconds: 200));
  });

  testWidgets("animation doesn't repeat more than specified", (WidgetTester tester) async {
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 2;
    mockCodec.repetitionCount = 0;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    final List<ImageInfo> emittedImages = <ImageInfo>[];
    imageStream.addListener(ImageStreamListener((ImageInfo image, bool synchronousCall) {
      emittedImages.add(image);
    }));

    codecCompleter.complete(mockCodec);
    await tester.idle();

    final FrameInfo frame1 = FakeFrameInfo(const Duration(milliseconds: 200), image20x10);
    final FrameInfo frame2 = FakeFrameInfo(const Duration(milliseconds: 400), image200x100);

    mockCodec.completeNextFrame(frame1);
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(); // first animation frame shows on first app frame.
    mockCodec.completeNextFrame(frame2);
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(const Duration(milliseconds: 200)); // emit 2nd frame.
    mockCodec.completeNextFrame(frame1);
    // allow another frame to complete (but we shouldn't be asking for it as
    // this animation should not repeat.
    await tester.idle();
    await tester.pump(const Duration(milliseconds: 400));

    expect(emittedImages[0].image.isCloneOf(frame1.image), true);
    expect(emittedImages[1].image.isCloneOf(frame2.image), true);
  });

  testWidgets('frames are only decoded when there are listeners', (WidgetTester tester) async {
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 2;
    mockCodec.repetitionCount = -1;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    void listener(ImageInfo image, bool synchronousCall) { }
    imageStream.addListener(ImageStreamListener(listener));
    final ImageStreamCompleterHandle handle = imageStream.keepAlive();

    codecCompleter.complete(mockCodec);
    await tester.idle();

    final FrameInfo frame1 = FakeFrameInfo(const Duration(milliseconds: 200), image20x10);
    final FrameInfo frame2 = FakeFrameInfo(const Duration(milliseconds: 400), image200x100);

    mockCodec.completeNextFrame(frame1);
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(); // first animation frame shows on first app frame.
    mockCodec.completeNextFrame(frame2);
    imageStream.removeListener(ImageStreamListener(listener));
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(const Duration(milliseconds: 400)); // emit 2nd frame.

    // Decoding of the 3rd frame should not start as there are no registered
    // listeners to the stream
    expect(mockCodec.numFramesAsked, 2);

    imageStream.addListener(ImageStreamListener(listener));
    await tester.idle(); // let nextFrameFuture complete
    expect(mockCodec.numFramesAsked, 3);

    handle.dispose();
  });

  testWidgets('multiple stream listeners', (WidgetTester tester) async {
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 2;
    mockCodec.repetitionCount = -1;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    final List<ImageInfo> emittedImages1 = <ImageInfo>[];
    void listener1(ImageInfo image, bool synchronousCall) {
      emittedImages1.add(image);
    }
    final List<ImageInfo> emittedImages2 = <ImageInfo>[];
    void listener2(ImageInfo image, bool synchronousCall) {
      emittedImages2.add(image);
    }
    imageStream.addListener(ImageStreamListener(listener1));
    imageStream.addListener(ImageStreamListener(listener2));

    codecCompleter.complete(mockCodec);
    await tester.idle();

    final FrameInfo frame1 = FakeFrameInfo(const Duration(milliseconds: 200), image20x10);
    final FrameInfo frame2 = FakeFrameInfo(const Duration(milliseconds: 400), image200x100);

    mockCodec.completeNextFrame(frame1);
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(); // first animation frame shows on first app frame.

    expect(emittedImages1.single.image.isCloneOf(frame1.image), true);
    expect(emittedImages2.single.image.isCloneOf(frame1.image), true);

    mockCodec.completeNextFrame(frame2);
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(); // next app frame will schedule a timer.
    imageStream.removeListener(ImageStreamListener(listener1));

    await tester.pump(const Duration(milliseconds: 400)); // emit 2nd frame.
    expect(emittedImages1.single.image.isCloneOf(frame1.image), true);
    expect(emittedImages2[0].image.isCloneOf(frame1.image), true);
    expect(emittedImages2[1].image.isCloneOf(frame2.image), true);

  });

  testWidgets('timer is canceled when listeners are removed', (WidgetTester tester) async {
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 2;
    mockCodec.repetitionCount = -1;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    void listener(ImageInfo image, bool synchronousCall) { }
    imageStream.addListener(ImageStreamListener(listener));

    codecCompleter.complete(mockCodec);
    await tester.idle();

    final FrameInfo frame1 = FakeFrameInfo(const Duration(milliseconds: 200), image20x10);
    final FrameInfo frame2 = FakeFrameInfo(const Duration(milliseconds: 400), image200x100);

    mockCodec.completeNextFrame(frame1);
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(); // first animation frame shows on first app frame.

    mockCodec.completeNextFrame(frame2);
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump();

    imageStream.removeListener(ImageStreamListener(listener));
    // The test framework will fail this if there are pending timers at this
    // point.
  });

  testWidgets('timeDilation affects animation frame timers', (WidgetTester tester) async {
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 2;
    mockCodec.repetitionCount = -1;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    void listener(ImageInfo image, bool synchronousCall) { }
    imageStream.addListener(ImageStreamListener(listener));

    codecCompleter.complete(mockCodec);
    await tester.idle();

    final FrameInfo frame1 = FakeFrameInfo(const Duration(milliseconds: 200), image20x10);
    final FrameInfo frame2 = FakeFrameInfo(const Duration(milliseconds: 400), image200x100);

    mockCodec.completeNextFrame(frame1);
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(); // first animation frame shows on first app frame.

    timeDilation = 2.0;
    mockCodec.completeNextFrame(frame2);
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(); // schedule next app frame
    await tester.pump(const Duration(milliseconds: 200)); // emit 2nd frame.
    // Decoding of the 3rd frame should not start after 200 ms, as time is
    // dilated by a factor of 2.
    expect(mockCodec.numFramesAsked, 2);
    await tester.pump(const Duration(milliseconds: 200)); // emit 2nd frame.
    expect(mockCodec.numFramesAsked, 3);
    timeDilation = 1.0; // restore time dilation, or it will affect other tests
  });

  testWidgets('error handlers can intercept errors', (WidgetTester tester) async {
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 1;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter streamUnderTest = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    dynamic capturedException;
    void errorListener(dynamic exception, StackTrace? stackTrace) {
      capturedException = exception;
    }

    streamUnderTest.addListener(ImageStreamListener(
      (ImageInfo image, bool synchronousCall) { },
      onError: errorListener,
    ));

    codecCompleter.complete(mockCodec);
    // MultiFrameImageStreamCompleter only sets an error handler for the next
    // frame future after the codec future has completed.
    // Idling here lets the MultiFrameImageStreamCompleter advance and set the
    // error handler for the nextFrame future.
    await tester.idle();

    mockCodec.failNextFrame('frame completion error');
    await tester.idle();

    // No exception is passed up.
    expect(tester.takeException(), isNull);
    expect(capturedException, 'frame completion error');
  });

  testWidgets('remove and add listener ', (WidgetTester tester) async {
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 3;
    mockCodec.repetitionCount = 0;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    void listener(ImageInfo image, bool synchronousCall) { }
    imageStream.addListener(ImageStreamListener(listener));

    codecCompleter.complete(mockCodec);

    await tester.idle(); // let nextFrameFuture complete

    imageStream.addListener(ImageStreamListener(listener));
    imageStream.removeListener(ImageStreamListener(listener));


    final FrameInfo frame1 = FakeFrameInfo(const Duration(milliseconds: 200), image20x10);

    mockCodec.completeNextFrame(frame1);
    await tester.idle(); // let nextFrameFuture complete
    await tester.pump(); // first animation frame shows on first app frame.

    await tester.pump(const Duration(milliseconds: 200)); // emit 2nd frame.
  });

  testWidgets('ImageStreamListener hashCode and equals', (WidgetTester tester) async {
    void handleImage(ImageInfo image, bool synchronousCall) { }
    void handleImageDifferently(ImageInfo image, bool synchronousCall) { }
    void handleError(dynamic error, StackTrace? stackTrace) { }
    void handleChunk(ImageChunkEvent event) { }

    void compare({
      required ImageListener onImage1,
      required ImageListener onImage2,
      ImageChunkListener? onChunk1,
      ImageChunkListener? onChunk2,
      ImageErrorListener? onError1,
      ImageErrorListener? onError2,
      bool areEqual = true,
    }) {
      final ImageStreamListener l1 = ImageStreamListener(onImage1, onChunk: onChunk1, onError: onError1);
      final ImageStreamListener l2 = ImageStreamListener(onImage2, onChunk: onChunk2, onError: onError2);
      Matcher comparison(dynamic expected) => areEqual ? equals(expected) : isNot(equals(expected));
      expect(l1, comparison(l2));
      expect(l1.hashCode, comparison(l2.hashCode));
    }

    compare(onImage1: handleImage, onImage2: handleImage);
    compare(onImage1: handleImage, onImage2: handleImageDifferently, areEqual: false);
    compare(onImage1: handleImage, onChunk1: handleChunk, onImage2: handleImage, onChunk2: handleChunk);
    compare(onImage1: handleImage, onChunk1: handleChunk, onError1: handleError, onImage2: handleImage, onChunk2: handleChunk, onError2: handleError);
    compare(onImage1: handleImage, onChunk1: handleChunk, onImage2: handleImage, areEqual: false);
    compare(onImage1: handleImage, onChunk1: handleChunk, onError1: handleError, onImage2: handleImage, areEqual: false);
    compare(onImage1: handleImage, onChunk1: handleChunk, onError1: handleError, onImage2: handleImage, onChunk2: handleChunk, areEqual: false);
    compare(onImage1: handleImage, onChunk1: handleChunk, onError1: handleError, onImage2: handleImage, onError2: handleError, areEqual: false);
  });

  testWidgets('Keep alive handles do not drive frames or prevent last listener callbacks', (WidgetTester tester) async {
    final Image image10x10 = (await tester.runAsync(() => createTestImage(width: 10, height: 10)))!;
    final MockCodec mockCodec = MockCodec();
    mockCodec.frameCount = 2;
    mockCodec.repetitionCount = -1;
    final Completer<Codec> codecCompleter = Completer<Codec>();

    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );

    int onImageCount = 0;
    void activeListener(ImageInfo image, bool synchronousCall) {
      onImageCount += 1;
    }
    bool lastListenerDropped = false;
    imageStream.addOnLastListenerRemovedCallback(() {
      lastListenerDropped = true;
    });

    expect(lastListenerDropped, false);
    final ImageStreamCompleterHandle handle = imageStream.keepAlive();
    expect(lastListenerDropped, false);
    SchedulerBinding.instance.debugAssertNoTransientCallbacks('Only passive listeners');

    codecCompleter.complete(mockCodec);
    await tester.idle();

    expect(onImageCount, 0);

    final FakeFrameInfo frame1 = FakeFrameInfo(Duration.zero, image20x10);
    mockCodec.completeNextFrame(frame1);
    await tester.idle();
    SchedulerBinding.instance.debugAssertNoTransientCallbacks('Only passive listeners');
    await tester.pump();
    expect(onImageCount, 0);

    imageStream.addListener(ImageStreamListener(activeListener));

    final FakeFrameInfo frame2 = FakeFrameInfo(Duration.zero, image10x10);
    mockCodec.completeNextFrame(frame2);
    await tester.idle();
    expect(SchedulerBinding.instance.transientCallbackCount, 1);
    await tester.pump();

    expect(onImageCount, 1);

    imageStream.removeListener(ImageStreamListener(activeListener));
    expect(lastListenerDropped, true);

    mockCodec.completeNextFrame(frame1);
    await tester.idle();
    expect(SchedulerBinding.instance.transientCallbackCount, 1);
    await tester.pump();

    expect(onImageCount, 1);

    SchedulerBinding.instance.debugAssertNoTransientCallbacks('Only passive listeners');

    mockCodec.completeNextFrame(frame2);
    await tester.idle();
    SchedulerBinding.instance.debugAssertNoTransientCallbacks('Only passive listeners');
    await tester.pump();

    expect(onImageCount, 1);

    handle.dispose();
  });

  test('MultiFrameImageStreamCompleter - one frame image should only be decoded once', () async {
    final FakeCodec oneFrameCodec = await FakeCodec.fromData(Uint8List.fromList(kTransparentImage));
    final Completer<Codec> codecCompleter = Completer<Codec>();
    final Completer<void> decodeCompleter = Completer<void>();
    final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
      codec: codecCompleter.future,
      scale: 1.0,
    );
    final ImageStreamListener imageListener = ImageStreamListener((ImageInfo info, bool syncCall) {
      decodeCompleter.complete();
    });

    imageStream.keepAlive();  // do not dispose
    imageStream.addListener(imageListener);
    codecCompleter.complete(oneFrameCodec);
    await decodeCompleter.future;

    imageStream.removeListener(imageListener);
    expect(oneFrameCodec.numFramesAsked, 1);

    // Adding a new listener for decoded imageSteam, the one frame image should
    // not be decoded again.
    imageStream.addListener(ImageStreamListener((ImageInfo info, bool syncCall) {}));
    expect(oneFrameCodec.numFramesAsked, 1);
  });  // https://github.com/flutter/flutter/issues/82532

  test('Multi-frame complete unsubscribes to chunk events when disposed', () async {
    final FakeCodec codec = await FakeCodec.fromData(Uint8List.fromList(kTransparentImage));
    final StreamController<ImageChunkEvent> chunkStream = StreamController<ImageChunkEvent>();

    final MultiFrameImageStreamCompleter completer = MultiFrameImageStreamCompleter(
      codec: Future<Codec>.value(codec),
      scale: 1.0,
      chunkEvents: chunkStream.stream,
    );

    expect(chunkStream.hasListener, true);

    chunkStream.add(const ImageChunkEvent(cumulativeBytesLoaded: 1, expectedTotalBytes: 3));

    final ImageStreamListener listener = ImageStreamListener((ImageInfo info, bool syncCall) {});
    // Cause the completer to dispose.
    completer.addListener(listener);
    completer.removeListener(listener);

    expect(chunkStream.hasListener, false);

    // The above expectation should cover this, but the point of this test is to
    // make sure the completer does not assert that it's disposed and still
    // receiving chunk events. Streams from the network can keep sending data
    // even after evicting an image from the cache, for example.
    chunkStream.add(const ImageChunkEvent(cumulativeBytesLoaded: 2, expectedTotalBytes: 3));
  });

  test('ImageStream, setCompleter before addListener - synchronousCall should be true', () async {
    final Image image = await createTestImage(width: 100, height: 100);
    final OneFrameImageStreamCompleter imageStreamCompleter =
        OneFrameImageStreamCompleter(SynchronousFuture<ImageInfo>(TestImageInfo(1, image: image)));

    final ImageStream imageStream = ImageStream();
    imageStream.setCompleter(imageStreamCompleter);

    bool? synchronouslyCalled;
    imageStream.addListener(ImageStreamListener((ImageInfo image, bool synchronousCall) {
      synchronouslyCalled = synchronousCall;
    }));

    expect(synchronouslyCalled, true);
  });

  test('ImageStream, setCompleter after addListener - synchronousCall should be false', () async {
    final Image image = await createTestImage(width: 100, height: 100);
    final OneFrameImageStreamCompleter imageStreamCompleter =
        OneFrameImageStreamCompleter(SynchronousFuture<ImageInfo>(TestImageInfo(1, image: image)));

    final ImageStream imageStream = ImageStream();

    bool? synchronouslyCalled;
    imageStream.addListener(ImageStreamListener((ImageInfo image, bool synchronousCall) {
      synchronouslyCalled = synchronousCall;
    }));

    imageStream.setCompleter(imageStreamCompleter);

    expect(synchronouslyCalled, false);
  });
}
