// Copyright 2013 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:typed_data';

import 'package:js/js.dart';
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;
import 'package:web_engine_tester/golden_tester.dart';

import '../matchers.dart';
import 'common.dart';
import 'test_data.dart';

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

void testMain() {
  group('CanvasKit Images', () {
    setUpCanvasKitTest();

    tearDown(() {
      debugRestoreHttpRequestFactory();
    });

    _testCkAnimatedImage();
    _testForImageCodecs(useBrowserImageDecoder: false);

    if (browserSupportsImageDecoder) {
      _testForImageCodecs(useBrowserImageDecoder: true);
      _testCkBrowserImageDecoder();
    }

    test('isAvif', () {
      expect(isAvif(Uint8List.fromList(<int>[])), isFalse);
      expect(isAvif(Uint8List.fromList(<int>[1, 2, 3])), isFalse);
      expect(
        isAvif(Uint8List.fromList(<int>[
          0x00, 0x00, 0x00, 0x1c, 0x66, 0x74, 0x79, 0x70,
          0x61, 0x76, 0x69, 0x66, 0x00, 0x00, 0x00, 0x00,
        ])),
        isTrue,
      );
      expect(
        isAvif(Uint8List.fromList(<int>[
          0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70,
          0x61, 0x76, 0x69, 0x66, 0x00, 0x00, 0x00, 0x00,
        ])),
        isTrue,
      );
    });
  }, skip: isSafari);
}

void _testForImageCodecs({required bool useBrowserImageDecoder}) {
  final String mode = useBrowserImageDecoder ? 'webcodecs' : 'wasm';
  final List<String> warnings = <String>[];
  late void Function(String) oldPrintWarning;

  group('($mode)', () {
    setUp(() {
      browserSupportsImageDecoder = useBrowserImageDecoder;
      warnings.clear();
    });

    setUpAll(() {
      oldPrintWarning = printWarning;
      printWarning = (String warning) {
        warnings.add(warning);
      };
    });

    tearDown(() {
      debugResetBrowserSupportsImageDecoder();
    });

    tearDownAll(() {
      printWarning = oldPrintWarning;
    });

    test('CkAnimatedImage can be explicitly disposed of', () {
      final CkAnimatedImage image = CkAnimatedImage.decodeFromBytes(kTransparentImage, 'test');
      expect(image.debugDisposed, isFalse);
      image.dispose();
      expect(image.debugDisposed, isTrue);

      // Disallow usage after disposal
      expect(() => image.frameCount, throwsAssertionError);
      expect(() => image.repetitionCount, throwsAssertionError);
      expect(() => image.getNextFrame(), throwsAssertionError);

      // Disallow double-dispose.
      expect(() => image.dispose(), throwsAssertionError);
      testCollector.collectNow();
    });

    test('CkAnimatedImage remembers last animation position after resurrection', () async {
      browserSupportsFinalizationRegistry = false;

      final CkAnimatedImage image = CkAnimatedImage.decodeFromBytes(kAnimatedGif, 'test');
      expect(image.frameCount, 3);
      expect(image.repetitionCount, -1);

      final ui.FrameInfo frame1 = await image.getNextFrame();
      await expectFrameData(frame1, <int>[255, 0, 0, 255]);
      final ui.FrameInfo frame2 = await image.getNextFrame();
      await expectFrameData(frame2, <int>[0, 255, 0, 255]);

      // Pretend that the image is temporarily deleted.
      image.delete();
      image.didDelete();

      // Check that we got the 3rd frame after resurrection.
      final ui.FrameInfo frame3 = await image.getNextFrame();
      await expectFrameData(frame3, <int>[0, 0, 255, 255]);

      testCollector.collectNow();
    });

    test('CkImage toString', () {
      final SkImage skImage =
          canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage)!
              .makeImageAtCurrentFrame();
      final CkImage image = CkImage(skImage);
      expect(image.toString(), '[1×1]');
      image.dispose();
      testCollector.collectNow();
    });

    test('CkImage can be explicitly disposed of', () {
      final SkImage skImage =
          canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage)!
              .makeImageAtCurrentFrame();
      final CkImage image = CkImage(skImage);
      expect(image.debugDisposed, isFalse);
      expect(image.box.isDeletedPermanently, isFalse);
      image.dispose();
      expect(image.debugDisposed, isTrue);
      expect(image.box.isDeletedPermanently, isTrue);

      // Disallow double-dispose.
      expect(() => image.dispose(), throwsAssertionError);
      testCollector.collectNow();
    });

    test('CkImage can be explicitly disposed of when cloned', () async {
      final SkImage skImage =
          canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage)!
              .makeImageAtCurrentFrame();
      final CkImage image = CkImage(skImage);
      final SkiaObjectBox<CkImage, SkImage> box = image.box;
      expect(box.refCount, 1);
      expect(box.debugGetStackTraces().length, 1);

      final CkImage clone = image.clone();
      expect(box.refCount, 2);
      expect(box.debugGetStackTraces().length, 2);

      expect(image.isCloneOf(clone), isTrue);
      expect(box.isDeletedPermanently, isFalse);

      testCollector.collectNow();
      expect(skImage.isDeleted(), isFalse);
      image.dispose();
      expect(box.refCount, 1);
      expect(box.isDeletedPermanently, isFalse);

      testCollector.collectNow();
      expect(skImage.isDeleted(), isFalse);
      clone.dispose();
      expect(box.refCount, 0);
      expect(box.isDeletedPermanently, isTrue);

      testCollector.collectNow();
      expect(skImage.isDeleted(), isTrue);
      expect(box.debugGetStackTraces().length, 0);
      testCollector.collectNow();
    });

    test('CkImage toByteData', () async {
      final SkImage skImage =
          canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage)!
              .makeImageAtCurrentFrame();
      final CkImage image = CkImage(skImage);
      expect((await image.toByteData()).lengthInBytes, greaterThan(0));
      expect((await image.toByteData(format: ui.ImageByteFormat.png)).lengthInBytes, greaterThan(0));
      testCollector.collectNow();
    });

    test('toByteData with decodeImageFromPixels on videoFrame formats', () async {
      // This test ensures that toByteData() returns pixels that can be used by decodeImageFromPixels
      // for the following videoFrame formats:
      // [BGRX, I422, I420, I444, BGRA]
      final DomResponse listingResponse = await httpFetch('/test_images/');
      final List<String> testFiles = (await listingResponse.json() as List<dynamic>).cast<String>();

      Future<ui.Image> testDecodeFromPixels(Uint8List pixels, int width, int height) async {
        final Completer<ui.Image> completer = Completer<ui.Image>();
        ui.decodeImageFromPixels(
          pixels,
          width,
          height,
          ui.PixelFormat.rgba8888,
          (ui.Image image) {
            completer.complete(image);
          },
        );
        return completer.future;
      }

      // Sanity-check the test file list. If suddenly test files are moved or
      // deleted, and the test server returns an empty list, or is missing some
      // important test files, we want to know.
      expect(testFiles, isNotEmpty);
      expect(testFiles, contains(matches(RegExp(r'.*\.jpg'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.png'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.gif'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.webp'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.bmp'))));

      for (final String testFile in testFiles) {
        final DomResponse imageResponse = await httpFetch('/test_images/$testFile');
        final Uint8List imageData = (await imageResponse.arrayBuffer() as ByteBuffer).asUint8List();
        final ui.Codec codec = await skiaInstantiateImageCodec(imageData);
        expect(codec.frameCount, greaterThan(0));
        expect(codec.repetitionCount, isNotNull);

        final ui.FrameInfo frame = await codec.getNextFrame();
        final CkImage ckImage = frame.image as CkImage;
        final ByteData imageBytes = await ckImage.toByteData();
        expect(imageBytes.lengthInBytes, greaterThan(0));

        final Uint8List pixels = imageBytes.buffer.asUint8List();
        final ui.Image testImage = await testDecodeFromPixels(pixels, ckImage.width, ckImage.height);
        expect(testImage, isNotNull);
        codec.dispose();
      }
      // TODO(hterkelsen): Firefox and Safari do not currently support ImageDecoder.
      // TODO(jacksongardner): enable on wasm
      // see https://github.com/flutter/flutter/issues/118334
    }, skip: isFirefox || isSafari || isWasm);

    test('CkImage.clone also clones the VideoFrame', () async {
      final CkBrowserImageDecoder image = await CkBrowserImageDecoder.create(
        data: kAnimatedGif,
        debugSource: 'test',
      );
      final ui.FrameInfo frame = await image.getNextFrame();
      final CkImage ckImage = frame.image as CkImage;
      expect(ckImage.videoFrame, isNotNull);

      final CkImage imageClone = ckImage.clone();
      expect(imageClone.videoFrame, isNotNull);

      final ByteData png = await imageClone.toByteData(format: ui.ImageByteFormat.png);
      expect(png, isNotNull);

      // The precise PNG encoding is browser-specific, but we can check the file
      // signature.
      expect(detectContentType(png.buffer.asUint8List()), 'image/png');
      testCollector.collectNow();
    // TODO(hterkelsen): Firefox and Safari do not currently support ImageDecoder.
    }, skip: isFirefox || isSafari);

    // Regression test for https://github.com/flutter/flutter/issues/72469
    test('CkImage can be resurrected', () {
      browserSupportsFinalizationRegistry = false;
      final SkImage skImage =
          canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage)!
              .makeImageAtCurrentFrame();
      final CkImage image = CkImage(skImage);
      expect(image.box.rawSkiaObject, isNotNull);

      // Pretend that the image is temporarily deleted.
      image.box.delete();
      image.box.didDelete();
      expect(image.box.rawSkiaObject, isNull);

      // Attempting to access the skia object here would previously throw
      // "Stack Overflow" in Safari.
      expect(image.box.skiaObject, isNotNull);
      testCollector.collectNow();
    });

    test('skiaInstantiateWebImageCodec loads an image from the network',
        () async {
      final TestHttpRequestMock mock = TestHttpRequestMock()
          ..status = 200
          ..response = kTransparentImage.buffer;
      httpRequestFactory = () => TestHttpRequest(mock);
      final Future<ui.Codec> futureCodec =
          skiaInstantiateWebImageCodec('http://image-server.com/picture.jpg',
              null);
      mock.sendEvent('load', DomProgressEvent('test progress event'));
      final ui.Codec codec = await futureCodec;
      expect(codec.frameCount, 1);
      final ui.Image image = (await codec.getNextFrame()).image;
      expect(image.height, 1);
      expect(image.width, 1);
      testCollector.collectNow();
    });

    test('instantiateImageCodec respects target image size',
        () async {
      const List<List<int>> targetSizes = <List<int>>[
        <int>[1, 1],
        <int>[1, 2],
        <int>[2, 3],
        <int>[3, 4],
        <int>[4, 4],
        <int>[10, 20],
      ];

      for (final List<int> targetSize in targetSizes) {
        final int targetWidth = targetSize[0];
        final int targetHeight = targetSize[1];

        final ui.Codec codec = await ui.instantiateImageCodec(
          k4x4PngImage,
          targetWidth: targetWidth,
          targetHeight: targetHeight,
        );

        final ui.Image image = (await codec.getNextFrame()).image;
        expect(image.width, targetWidth);
        expect(image.height, targetHeight);
        image.dispose();
        codec.dispose();
      }

      testCollector.collectNow();
    });

    test('instantiateImageCodec with multi-frame image does not support targetWidth/targetHeight',
        () async {
        final ui.Codec codec = await ui.instantiateImageCodec(
          kAnimatedGif,
          targetWidth: 2,
          targetHeight: 3,
        );
        final ui.Image image = (await codec.getNextFrame()).image;

        expect(
        warnings,
        containsAllInOrder(
          <String>[
            'targetWidth and targetHeight for multi-frame images not supported',
          ],
        ),
      );

        // expect the re-size did not happen, kAnimatedGif is [1x1]
        expect(image.width, 1);
        expect(image.height, 1);
        image.dispose();
        codec.dispose();

        testCollector.collectNow();
    });

    test('skiaInstantiateWebImageCodec throws exception on request error',
        () async {
      final TestHttpRequestMock mock = TestHttpRequestMock();
      httpRequestFactory = () => TestHttpRequest(mock);
      try {
        final Future<ui.Codec> futureCodec = skiaInstantiateWebImageCodec(
            'url-does-not-matter', null);
        mock.sendEvent('error', DomProgressEvent('test error'));
        await futureCodec;
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        expect(
          exception.toString(),
          'ImageCodecException: Failed to load network image.\n'
          'Image URL: url-does-not-matter\n'
          'Trying to load an image from another domain? Find answers at:\n'
          'https://flutter.dev/docs/development/platform-integration/web-images',
        );
      }
      testCollector.collectNow();
    });

    test('skiaInstantiateWebImageCodec throws exception on HTTP error',
        () async {
      try {
        await skiaInstantiateWebImageCodec('/does-not-exist.jpg', null);
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        expect(
          exception.toString(),
          'ImageCodecException: Failed to load network image.\n'
          'Image URL: /does-not-exist.jpg\n'
          'Server response code: 404',
        );
      }
      testCollector.collectNow();
    });

    test('skiaInstantiateWebImageCodec includes URL in the error for malformed image',
        () async {
      final TestHttpRequestMock mock = TestHttpRequestMock()
          ..status = 200
          ..response = Uint8List(0).buffer;
      httpRequestFactory = () => TestHttpRequest(mock);
      try {
        final Future<ui.Codec> futureCodec = skiaInstantiateWebImageCodec(
            'http://image-server.com/picture.jpg', null);
        mock.sendEvent('load', DomProgressEvent('test progress event'));
        await futureCodec;
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        if (!browserSupportsImageDecoder) {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to decode image data.\n'
            'Image source: http://image-server.com/picture.jpg',
          );
        } else {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to detect image file format using the file header.\n'
            'File header was empty.\n'
            'Image source: http://image-server.com/picture.jpg',
          );
        }
      }
      testCollector.collectNow();
    });

    test('Reports error when failing to decode empty image data', () async {
      try {
        await ui.instantiateImageCodec(Uint8List(0));
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        if (!browserSupportsImageDecoder) {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to decode image data.\n'
            'Image source: encoded image bytes',
          );
        } else {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to detect image file format using the file header.\n'
            'File header was empty.\n'
            'Image source: encoded image bytes',
          );
        }
      }
    });

    test('Reports error when failing to decode malformed image data', () async {
      try {
        await ui.instantiateImageCodec(Uint8List.fromList(<int>[
          0xFF, 0xD8, 0xFF, 0xDB, 0x00, 0x00, 0x00,
        ]));
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        if (!browserSupportsImageDecoder) {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to decode image data.\n'
            'Image source: encoded image bytes'
          );
        } else {
          expect(
            exception.toString(),
            // Browser error message is not checked as it can depend on the
            // browser engine and version.
            matches(RegExp(
              r"ImageCodecException: Failed to decode image using the browser's ImageDecoder API.\n"
              r'Image source: encoded image bytes\n'
              r'Original browser error: .+'
            ))
          );
        }
      }
    });

    test('Includes file header in the error message when fails to detect file type', () async {
      try {
        await ui.instantiateImageCodec(Uint8List.fromList(<int>[
          0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00,
        ]));
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        if (!browserSupportsImageDecoder) {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to decode image data.\n'
            'Image source: encoded image bytes'
          );
        } else {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to detect image file format using the file header.\n'
            'File header was [0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x00].\n'
            'Image source: encoded image bytes'
          );
        }
      }
    });

    test('Provides readable error message when image type is unsupported', () async {
      addTearDown(() {
        debugContentTypeDetector = null;
      });
      debugContentTypeDetector = (_) {
        return 'unsupported/image-type';
      };
      try {
        await ui.instantiateImageCodec(Uint8List.fromList(<int>[
          0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00,
        ]));
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        if (!browserSupportsImageDecoder) {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to decode image data.\n'
            'Image source: encoded image bytes'
          );
        } else {
          expect(
            exception.toString(),
            "ImageCodecException: Image file format (unsupported/image-type) is not supported by this browser's ImageDecoder API.\n"
            'Image source: encoded image bytes'
          );
        }
      }
    });

    test('decodeImageFromPixels', () async {
      Future<ui.Image> testDecodeFromPixels(int width, int height) async {
        final Completer<ui.Image> completer = Completer<ui.Image>();
        ui.decodeImageFromPixels(
          Uint8List.fromList(List<int>.filled(width * height * 4, 0)),
          width,
          height,
          ui.PixelFormat.rgba8888,
          (ui.Image image) {
            completer.complete(image);
          },
        );
        return completer.future;
      }

      final ui.Image image1 = await testDecodeFromPixels(10, 20);
      expect(image1, isNotNull);
      expect(image1.width, 10);
      expect(image1.height, 20);

      final ui.Image image2 = await testDecodeFromPixels(40, 100);
      expect(image2, isNotNull);
      expect(image2.width, 40);
      expect(image2.height, 100);
    });

    test('decodeImageFromPixels respects target image size', () async {
      Future<ui.Image> testDecodeFromPixels(int width, int height, int targetWidth, int targetHeight) async {
        final Completer<ui.Image> completer = Completer<ui.Image>();
        ui.decodeImageFromPixels(
          Uint8List.fromList(List<int>.filled(width * height * 4, 0)),
          width,
          height,
          ui.PixelFormat.rgba8888,
          (ui.Image image) {
            completer.complete(image);
          },
          targetWidth: targetWidth,
          targetHeight: targetHeight,
        );
        return completer.future;
      }

      const List<List<int>> targetSizes = <List<int>>[
        <int>[1, 1],
        <int>[1, 2],
        <int>[2, 3],
        <int>[3, 4],
        <int>[4, 4],
        <int>[10, 20],
      ];

      for (final List<int> targetSize in targetSizes) {
        final int targetWidth = targetSize[0];
        final int targetHeight = targetSize[1];

        final ui.Image image = await testDecodeFromPixels(10, 20, targetWidth, targetHeight);

        expect(image.width, targetWidth);
        expect(image.height, targetHeight);
        image.dispose();
      }
    });

    test('decodeImageFromPixels upscale when allowUpscaling is false', () async {
      Future<ui.Image> testDecodeFromPixels(int width, int height) async {
        final Completer<ui.Image> completer = Completer<ui.Image>();
        ui.decodeImageFromPixels(
          Uint8List.fromList(List<int>.filled(width * height * 4, 0)),
          width,
          height,
          ui.PixelFormat.rgba8888,
          (ui.Image image) {
            completer.complete(image);
          },
          targetWidth: 20,
          targetHeight: 30,
          allowUpscaling: false
        );
        return completer.future;
      }
      expect(() async => testDecodeFromPixels(10, 20), throwsAssertionError);
    });

    test('Decode test images', () async {
      final DomResponse listingResponse = await httpFetch('/test_images/');
      final List<String> testFiles = (await listingResponse.json() as List<dynamic>).cast<String>();

      // Sanity-check the test file list. If suddenly test files are moved or
      // deleted, and the test server returns an empty list, or is missing some
      // important test files, we want to know.
      expect(testFiles, isNotEmpty);
      expect(testFiles, contains(matches(RegExp(r'.*\.jpg'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.png'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.gif'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.webp'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.bmp'))));

      for (final String testFile in testFiles) {
        final DomResponse imageResponse = await httpFetch('/test_images/$testFile');
        final Uint8List imageData = (await imageResponse.arrayBuffer() as ByteBuffer).asUint8List();
        final ui.Codec codec = await skiaInstantiateImageCodec(imageData);
        expect(codec.frameCount, greaterThan(0));
        expect(codec.repetitionCount, isNotNull);
        for (int i = 0; i < codec.frameCount; i++) {
          final ui.FrameInfo frame = await codec.getNextFrame();
          expect(frame.duration, isNotNull);
          expect(frame.image, isNotNull);
        }
        codec.dispose();
      }
    });

    // Reproduces https://skbug.com/12721
    test('decoded image can be read back from picture', () async {
      final DomResponse imageResponse = await httpFetch('/test_images/mandrill_128.png');
      final Uint8List imageData = (await imageResponse.arrayBuffer() as ByteBuffer).asUint8List();
      final ui.Codec codec = await skiaInstantiateImageCodec(imageData);
      final ui.FrameInfo frame = await codec.getNextFrame();
      final CkImage image = frame.image as CkImage;

      final CkImage snapshot;
      {
        final LayerSceneBuilder sb = LayerSceneBuilder();
        sb.pushOffset(10, 10);
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.drawRect(
          const ui.Rect.fromLTRB(5, 5, 20, 20),
          CkPaint(),
        );
        canvas.drawImage(image, ui.Offset.zero, CkPaint());
        canvas.drawRect(
          const ui.Rect.fromLTRB(90, 90, 105, 105),
          CkPaint(),
        );
        sb.addPicture(ui.Offset.zero, recorder.endRecording());
        sb.pop();
        snapshot = await sb.build().toImage(150, 150) as CkImage;
      }

      {
        final LayerSceneBuilder sb = LayerSceneBuilder();
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.drawImage(snapshot, ui.Offset.zero, CkPaint());
        sb.addPicture(ui.Offset.zero, recorder.endRecording());

        CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
        await matchGoldenFile(
          'canvaskit_read_back_decoded_image_$mode.png',
          region: const ui.Rect.fromLTRB(0, 0, 150, 150),
        );
      }

      image.dispose();
      codec.dispose();
    });

    // This is a regression test for the issues with transferring textures from
    // one GL context to another, such as:
    //
    //  * https://github.com/flutter/flutter/issues/86809
    //  * https://github.com/flutter/flutter/issues/91881
    test('the same image can be rendered on difference surfaces', () async {
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      final ui.Codec codec = await ui.instantiateImageCodec(k4x4PngImage);
      final CkImage image = (await codec.getNextFrame()).image as CkImage;

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(4, 4);
      {
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.save();
        canvas.scale(16, 16);
        canvas.drawImage(image, ui.Offset.zero, CkPaint());
        canvas.restore();
        canvas.drawParagraph(makeSimpleText('1'), const ui.Offset(4, 4));
        sb.addPicture(ui.Offset.zero, recorder.endRecording());
      }
      sb.addPlatformView(0, width: 100, height: 100);
      sb.pushOffset(20, 20);
      {
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.save();
        canvas.scale(16, 16);
        canvas.drawImage(image, ui.Offset.zero, CkPaint());
        canvas.restore();
        canvas.drawParagraph(makeSimpleText('2'), const ui.Offset(2, 2));
        sb.addPicture(ui.Offset.zero, recorder.endRecording());
      }
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
      await matchGoldenFile(
        'canvaskit_cross_gl_context_image_$mode.png',
        region: const ui.Rect.fromLTRB(0, 0, 100, 100),
      );

      await disposePlatformView(0);
    });

    test('toImageSync with texture-backed image', () async {
      final DomResponse imageResponse = await httpFetch('/test_images/mandrill_128.png');
      final Uint8List imageData = (await imageResponse.arrayBuffer() as ByteBuffer).asUint8List();
      final ui.Codec codec = await skiaInstantiateImageCodec(imageData);
      final ui.FrameInfo frame = await codec.getNextFrame();
      final CkImage mandrill = frame.image as CkImage;
      final ui.PictureRecorder recorder = ui.PictureRecorder();
      final ui.Canvas canvas = ui.Canvas(recorder);
      canvas.drawImageRect(
        mandrill,
        const ui.Rect.fromLTWH(0, 0, 128, 128),
        const ui.Rect.fromLTWH(0, 0, 128, 128),
        ui.Paint(),
      );
      final ui.Picture picture = recorder.endRecording();
      final ui.Image image = picture.toImageSync(50, 50);

      expect(image.width, 50);
      expect(image.height, 50);

      final ByteData? data = await image.toByteData();
      expect(data, isNotNull);
      expect(data!.lengthInBytes, 50 * 50 * 4);
      expect(data.buffer.asUint32List().any((int byte) => byte != 0), isTrue);

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      {
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.save();
        canvas.drawImage(image as CkImage, ui.Offset.zero, CkPaint());
        canvas.restore();
        sb.addPicture(ui.Offset.zero, recorder.endRecording());
      }
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
      await matchGoldenFile(
        'canvaskit_picture_texture_toimage',
        region: const ui.Rect.fromLTRB(0, 0, 128, 128),
      );
      mandrill.dispose();
      codec.dispose();
    });

    test('decoded image can be read back from picture', () async {
      final DomResponse imageResponse = await httpFetch('/test_images/mandrill_128.png');
      final Uint8List imageData = (await imageResponse.arrayBuffer() as ByteBuffer).asUint8List();
      final ui.Codec codec = await skiaInstantiateImageCodec(imageData);
      final ui.FrameInfo frame = await codec.getNextFrame();
      final CkImage image = frame.image as CkImage;

      final CkImage snapshot;
      {
        final LayerSceneBuilder sb = LayerSceneBuilder();
        sb.pushOffset(10, 10);
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.drawRect(
          const ui.Rect.fromLTRB(5, 5, 20, 20),
          CkPaint(),
        );
        canvas.drawImage(image, ui.Offset.zero, CkPaint());
        canvas.drawRect(
          const ui.Rect.fromLTRB(90, 90, 105, 105),
          CkPaint(),
        );
        sb.addPicture(ui.Offset.zero, recorder.endRecording());
        sb.pop();
        snapshot = await sb.build().toImage(150, 150) as CkImage;
      }

      {
        final LayerSceneBuilder sb = LayerSceneBuilder();
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.drawImage(snapshot, ui.Offset.zero, CkPaint());
        sb.addPicture(ui.Offset.zero, recorder.endRecording());

        CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
        await matchGoldenFile(
          'canvaskit_read_back_decoded_image_$mode.png',
          region: const ui.Rect.fromLTRB(0, 0, 150, 150),
        );
      }

      image.dispose();
      codec.dispose();
    });

    test('can detect JPEG from just magic number', () async {
      expect(
        detectContentType(
          Uint8List.fromList(<int>[0xff, 0xd8, 0xff, 0xe2, 0x0c, 0x58, 0x49, 0x43, 0x43, 0x5f])),
        'image/jpeg');
    });
  }, timeout: const Timeout.factor(10)); // These tests can take a while. Allow for a longer timeout.
}

/// Tests specific to WASM codecs bundled with CanvasKit.
void _testCkAnimatedImage() {
  test('ImageDecoder toByteData(PNG)', () async {
    final CkAnimatedImage image = CkAnimatedImage.decodeFromBytes(kAnimatedGif, 'test');
    final ui.FrameInfo frame = await image.getNextFrame();
    final ByteData? png = await frame.image.toByteData(format: ui.ImageByteFormat.png);
    expect(png, isNotNull);

    // The precise PNG encoding is browser-specific, but we can check the file
    // signature.
    expect(detectContentType(png!.buffer.asUint8List()), 'image/png');
    testCollector.collectNow();
  });

  test('CkAnimatedImage toByteData(RGBA)', () async {
    final CkAnimatedImage image = CkAnimatedImage.decodeFromBytes(kAnimatedGif, 'test');
    const List<List<int>> expectedColors = <List<int>>[
      <int>[255, 0, 0, 255],
      <int>[0, 255, 0, 255],
      <int>[0, 0, 255, 255],
    ];
    for (int i = 0; i < image.frameCount; i++) {
      final ui.FrameInfo frame = await image.getNextFrame();
      final ByteData? rgba = await frame.image.toByteData();
      expect(rgba, isNotNull);
      expect(rgba!.buffer.asUint8List(), expectedColors[i]);
    }
    testCollector.collectNow();
  });
}

/// Tests specific to browser image codecs based functionality.
void _testCkBrowserImageDecoder() {
  assert(browserSupportsImageDecoder);

  test('ImageDecoder toByteData(PNG)', () async {
    final CkBrowserImageDecoder image = await CkBrowserImageDecoder.create(
      data: kAnimatedGif,
      debugSource: 'test',
    );
    final ui.FrameInfo frame = await image.getNextFrame();
    final ByteData? png = await frame.image.toByteData(format: ui.ImageByteFormat.png);
    expect(png, isNotNull);

    // The precise PNG encoding is browser-specific, but we can check the file
    // signature.
    expect(detectContentType(png!.buffer.asUint8List()), 'image/png');
    testCollector.collectNow();
  });

  test('ImageDecoder toByteData(RGBA)', () async {
    final CkBrowserImageDecoder image = await CkBrowserImageDecoder.create(
      data: kAnimatedGif,
      debugSource: 'test',
    );
    const List<List<int>> expectedColors = <List<int>>[
      <int>[255, 0, 0, 255],
      <int>[0, 255, 0, 255],
      <int>[0, 0, 255, 255],
    ];
    for (int i = 0; i < image.frameCount; i++) {
      final ui.FrameInfo frame = await image.getNextFrame();
      final ByteData? rgba = await frame.image.toByteData();
      expect(rgba, isNotNull);
      expect(rgba!.buffer.asUint8List(), expectedColors[i]);
    }
    testCollector.collectNow();
    // TODO(jacksongardner): enable on wasm
    // see https://github.com/flutter/flutter/issues/118334
  }, skip: isWasm);

  test('ImageDecoder expires after inactivity', () async {
    const Duration testExpireDuration = Duration(milliseconds: 100);
    debugOverrideWebDecoderExpireDuration(testExpireDuration);

    final CkBrowserImageDecoder image = await CkBrowserImageDecoder.create(
      data: kAnimatedGif,
      debugSource: 'test',
    );

    // ImageDecoder is initialized eagerly to populate `frameCount` and
    // `repetitionCount`.
    final ImageDecoder? decoder1 = image.debugCachedWebDecoder;
    expect(decoder1, isNotNull);
    expect(image.frameCount, 3);
    expect(image.repetitionCount, -1);

    // A frame can be decoded right away.
    final ui.FrameInfo frame1 = await image.getNextFrame();
    await expectFrameData(frame1, <int>[255, 0, 0, 255]);
    expect(frame1, isNotNull);

    // The cached decoder should not yet expire.
    await Future<void>.delayed(testExpireDuration ~/ 2);
    expect(image.debugCachedWebDecoder, same(decoder1));

    // Now it expires.
    await Future<void>.delayed(testExpireDuration);
    expect(image.debugCachedWebDecoder, isNull);

    // A new decoder should be created upon the next frame request.
    final ui.FrameInfo frame2 = await image.getNextFrame();

    // Check that the cached decoder is indeed new.
    final ImageDecoder? decoder2 = image.debugCachedWebDecoder;
    expect(decoder2, isNot(same(decoder1)));
    await expectFrameData(frame2, <int>[0, 255, 0, 255]);

    // Check that the new decoder remembers the last frame index.
    final ui.FrameInfo frame3 = await image.getNextFrame();
    await expectFrameData(frame3, <int>[0, 0, 255, 255]);

    testCollector.collectNow();
    debugRestoreWebDecoderExpireDuration();
    // TODO(jacksongardner): enable on wasm
    // see https://github.com/flutter/flutter/issues/118334
  }, skip: isWasm);
}

class TestHttpRequestMock {
  String responseType = 'invalid';
  int timeout = 10;
  bool withCredentials = false;
  dynamic response;
  int status = -1;
  Map<String, DomEventListener> listeners = <String, DomEventListener>{};

  void open(String method, String url, [bool? async]) {}
  void send() {}
  void addEventListener(String eventType, DomEventListener listener, [bool?
      useCapture]) =>
      listeners[eventType] = listener;

  void sendEvent(String eventType, DomProgressEvent event) =>
      listeners[eventType]!(event);
}

@JS()
@anonymous
@staticInterop
class TestHttpRequest implements DomXMLHttpRequest {
  factory TestHttpRequest(TestHttpRequestMock mock) {
    return TestHttpRequest._(
        responseType: mock.responseType,
        timeout: mock.timeout.toDouble(),
        withCredentials: mock.withCredentials,
        response: mock.response,
        status: mock.status.toDouble(),
        open: allowInterop((String method, String url, [bool? async]) =>
            mock.open(method, url, async)),
        send: allowInterop(() => mock.send()),
        addEventListener: allowInterop((String eventType, DomEventListener
                listener, [bool? useCapture]) =>
            mock.addEventListener(eventType, listener, useCapture)));
  }

  external factory TestHttpRequest._({
    String responseType,
    double timeout,
    bool withCredentials,
    dynamic response,
    double status,
    void Function(String method, String url, [bool? async]) open,
    void Function() send,
    void Function(String eventType, DomEventListener listener) addEventListener
  });
}

Future<void> expectFrameData(ui.FrameInfo frame, List<int> data) async {
  final ByteData frameData = (await frame.image.toByteData())!;
  expect(frameData.buffer.asUint8List(), Uint8List.fromList(data));
}
