// 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 'package:js/js_util.dart' as js_util;
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 'common.dart';
import 'test_data.dart';

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

void testMain() {
  group('$HtmlViewEmbedder', () {
    setUpCanvasKitTest();

    setUp(() {
      window.debugOverrideDevicePixelRatio(1);
    });

    test('embeds interactive platform views', () async {
      final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      rasterizer.draw(sb.build().layerTree);

      // The platform view is now split in two parts. The contents live
      // as a child of the glassPane, and the slot lives in the glassPane
      // shadow root. The slot is the one that has pointer events auto.
      final DomElement contents = flutterViewEmbedder.glassPaneElement!
          .querySelector('#view-0')!;
      final DomElement slot = flutterViewEmbedder.sceneElement!
          .querySelector('slot')!;
      final DomElement contentsHost = contents.parent!;
      final DomElement slotHost = slot.parent!;

      expect(contents, isNotNull,
          reason: 'The view from the factory is injected in the DOM.');

      expect(contentsHost.tagName, equalsIgnoringCase('flt-platform-view'));
      expect(slotHost.tagName, equalsIgnoringCase('flt-platform-view-slot'));

      expect(slotHost.style.pointerEvents, 'auto',
          reason: 'The slot reenables pointer events.');
      expect(contentsHost.getAttribute('slot'), slot.getAttribute('name'),
          reason: 'The contents and slot are correctly related.');
    });

    test('clips platform views with RRects', () async {
      final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.pushClipRRect(
          ui.RRect.fromLTRBR(0, 0, 10, 10, const ui.Radius.circular(3)));
      sb.addPlatformView(0, width: 10, height: 10);
      rasterizer.draw(sb.build().layerTree);

      expect(
        flutterViewEmbedder.sceneElement!
            .querySelectorAll('#sk_path_defs')
            .single,
        isNotNull,
      );
      expect(
        flutterViewEmbedder.sceneElement!
            .querySelectorAll('#sk_path_defs')
            .single
            .querySelectorAll('clipPath')
            .single,
        isNotNull,
      );
      expect(
        flutterViewEmbedder.sceneElement!
            .querySelectorAll('flt-clip')
            .single
            .style
            .clipPath,
        'url("#svgClip1")',
      );
      expect(
        flutterViewEmbedder.sceneElement!
            .querySelectorAll('flt-clip')
            .single
            .style
            .width,
        '100%',
      );
      expect(
        flutterViewEmbedder.sceneElement!
            .querySelectorAll('flt-clip')
            .single
            .style
            .height,
        '100%',
      );
    });

    test('correctly transforms platform views', () async {
      final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      final Matrix4 scaleMatrix = Matrix4.identity()
        ..scale(5, 5)
        ..translate(100, 100);
      sb.pushTransform(scaleMatrix.toFloat64());
      sb.pushOffset(3, 3);
      sb.addPlatformView(0, width: 10, height: 10);
      rasterizer.draw(sb.build().layerTree);

      // Transformations happen on the slot element.
      final DomElement slotHost = flutterViewEmbedder.sceneElement!
          .querySelector('flt-platform-view-slot')!;

      expect(
        slotHost.style.transform,
        // We should apply the scale matrix first, then the offset matrix.
        // So the translate should be 515 (5 * 100 + 5 * 3), and not
        // 503 (5 * 100 + 3).
        'matrix3d(5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 5, 0, 515, 515, 0, 1)',
      );
    });

    test('correctly offsets platform views', () async {
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.addPlatformView(0, offset: const ui.Offset(3, 4), width: 5, height: 6);
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);

      final DomElement slotHost = flutterViewEmbedder.sceneElement!
          .querySelector('flt-platform-view-slot')!;
      final DomCSSStyleDeclaration style = slotHost.style;

      expect(style.transform, 'matrix(1, 0, 0, 1, 3, 4)');
      expect(style.width, '5px');
      expect(style.height, '6px');

      final DomRect slotRect = slotHost.getBoundingClientRect();
      expect(slotRect.left, 3);
      expect(slotRect.top, 4);
      expect(slotRect.right, 8);
      expect(slotRect.bottom, 10);
    });

    // Returns the list of CSS transforms applied to the ancestor chain of
    // elements starting from `viewHost`, up until and excluding <flt-scene>.
    List<String> getTransformChain(DomElement viewHost) {
      final List<String> chain = <String>[];
      DomElement? element = viewHost;
      while (element != null && element.tagName.toLowerCase() != 'flt-scene') {
        chain.add(element.style.transform);
        element = element.parent;
      }
      return chain;
    }

    test('correctly offsets when clip chain length is changed', () async {
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(3, 3);
      sb.pushClipRect(ui.Rect.largest);
      sb.pushOffset(6, 6);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.pop();
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);

      // Transformations happen on the slot element.
      DomElement slotHost = flutterViewEmbedder.sceneElement!
          .querySelector('flt-platform-view-slot')!;

      expect(
        getTransformChain(slotHost),
        <String>[
          'matrix(1, 0, 0, 1, 6, 6)',
          'matrix(1, 0, 0, 1, 3, 3)',
        ],
      );

      sb = LayerSceneBuilder();
      sb.pushOffset(3, 3);
      sb.pushClipRect(ui.Rect.largest);
      sb.pushOffset(6, 6);
      sb.pushClipRect(ui.Rect.largest);
      sb.pushOffset(9, 9);
      sb.addPlatformView(0, width: 10, height: 10);
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);

      // Transformations happen on the slot element.
      slotHost = flutterViewEmbedder.sceneElement!
          .querySelector('flt-platform-view-slot')!;

      expect(
        getTransformChain(slotHost),
        <String>[
          'matrix(1, 0, 0, 1, 9, 9)',
          'matrix(1, 0, 0, 1, 6, 6)',
          'matrix(1, 0, 0, 1, 3, 3)',
        ],
      );
    });

    test('converts device pixels to logical pixels (no clips)', () async {
      window.debugOverrideDevicePixelRatio(4);
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(1, 1);
      sb.pushOffset(2, 2);
      sb.pushOffset(3, 3);
      sb.addPlatformView(0, width: 10, height: 10);
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);

      // Transformations happen on the slot element.
      final DomElement slotHost = flutterViewEmbedder.sceneElement!
          .querySelector('flt-platform-view-slot')!;

      expect(
        getTransformChain(slotHost),
        <String>['matrix(0.25, 0, 0, 0.25, 1.5, 1.5)'],
      );
    });

    test('converts device pixels to logical pixels (with clips)', () async {
      window.debugOverrideDevicePixelRatio(4);
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(3, 3);
      sb.pushClipRect(ui.Rect.largest);
      sb.pushOffset(6, 6);
      sb.pushClipRect(ui.Rect.largest);
      sb.pushOffset(9, 9);
      sb.addPlatformView(0, width: 10, height: 10);
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);

      // Transformations happen on the slot element.
      final DomElement slotHost = flutterViewEmbedder.sceneElement!
          .querySelector('flt-platform-view-slot')!;

      expect(
        getTransformChain(slotHost),
        <String>[
          'matrix(1, 0, 0, 1, 9, 9)',
          'matrix(1, 0, 0, 1, 6, 6)',
          'matrix(0.25, 0, 0, 0.25, 0.75, 0.75)',
        ],
      );
    });

    test('renders overlays on top of platform views', () async {
      expect(SurfaceFactory.instance.debugCacheSize, 0);
      expect(configuration.canvasKitMaximumSurfaces, 8);
      final CkPicture testPicture =
          paintPicture(const ui.Rect.fromLTRB(0, 0, 10, 10), (CkCanvas canvas) {
        canvas.drawCircle(const ui.Offset(5, 5), 5, CkPaint());
      });

      // Initialize all platform views to be used in the test.
      final List<int> platformViewIds = <int>[];
      for (int i = 0; i < 16; i++) {
        ui.platformViewRegistry.registerViewFactory(
          'test-platform-view',
          (int viewId) => createDomHTMLDivElement()..id = 'view-$i',
        );
        await createPlatformView(i, 'test-platform-view');
        platformViewIds.add(i);
      }

      void renderTestScene({required int viewCount}) {
        final LayerSceneBuilder sb = LayerSceneBuilder();
        sb.pushOffset(0, 0);
        for (int i = 0; i < viewCount; i++) {
          sb.addPicture(ui.Offset.zero, testPicture);
          sb.addPlatformView(i, width: 10, height: 10);
        }
        CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
      }

      // Frame 1:
      //   Render: up to cache size platform views.
      //   Expect: main canvas plus platform view overlays.
      renderTestScene(viewCount: 8);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
      ]);

      // Frame 2:
      //   Render: zero platform views.
      //   Expect: main canvas, no overlays.
      await Future<void>.delayed(Duration.zero);
      renderTestScene(viewCount: 0);
      _expectSceneMatches(<_EmbeddedViewMarker>[_overlay]);

      // Frame 3:
      //   Render: less than cache size platform views.
      //   Expect: overlays reused.
      await Future<void>.delayed(Duration.zero);
      renderTestScene(viewCount: 6);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
      ]);

      // Frame 4:
      //   Render: more platform views than max cache size.
      //   Expect: main canvas, backup overlay, maximum overlays.
      await Future<void>.delayed(Duration.zero);
      renderTestScene(viewCount: 16);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
      ]);

      // Frame 5:
      //   Render: zero platform views.
      //   Expect: main canvas, no overlays.
      await Future<void>.delayed(Duration.zero);
      renderTestScene(viewCount: 0);
      _expectSceneMatches(<_EmbeddedViewMarker>[_overlay]);

      // Frame 6:
      //   Render: deleted platform views.
      //   Expect: error.
      for (final int id in platformViewIds) {
        const StandardMethodCodec codec = StandardMethodCodec();
        final Completer<void> completer = Completer<void>();
        ui.window.sendPlatformMessage(
          'flutter/platform_views',
          codec.encodeMethodCall(MethodCall(
            'dispose',
            id,
          )),
          completer.complete,
        );
        await completer.future;
      }

      try {
        renderTestScene(viewCount: platformViewIds.length);
        fail('Expected to throw');
      } on AssertionError catch (error) {
        expect(
          error.toString(),
          'Assertion failed: "Cannot render platform views: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15. These views have not been created, or they have been deleted."',
        );
      }

      // Frame 7:
      //   Render: a platform view after error.
      //   Expect: success. Just checking the system is not left in a corrupted state.
      await createPlatformView(0, 'test-platform-view');
      renderTestScene(viewCount: 0);
      _expectSceneMatches(<_EmbeddedViewMarker>[_overlay]);
      // TODO(yjbanov): skipped due to https://github.com/flutter/flutter/issues/73867
    }, skip: isSafari);

    test('correctly reuses overlays', () async {
      final CkPicture testPicture =
          paintPicture(const ui.Rect.fromLTRB(0, 0, 10, 10), (CkCanvas canvas) {
        canvas.drawCircle(const ui.Offset(5, 5), 5, CkPaint());
      });

      // Initialize all platform views to be used in the test.
      final List<int> platformViewIds = <int>[];
      for (int i = 0; i < 20; i++) {
        ui.platformViewRegistry.registerViewFactory(
          'test-platform-view',
          (int viewId) => createDomHTMLDivElement()..id = 'view-$i',
        );
        await createPlatformView(i, 'test-platform-view');
        platformViewIds.add(i);
      }

      void renderTestScene(List<int> views) {
        final LayerSceneBuilder sb = LayerSceneBuilder();
        sb.pushOffset(0, 0);
        for (final int view in views) {
          sb.addPicture(ui.Offset.zero, testPicture);
          sb.addPlatformView(view, width: 10, height: 10);
        }
        CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
      }

      // Frame 1:
      //   Render: Views 1-10
      //   Expect: main canvas plus platform view overlays; empty cache.
      renderTestScene(<int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
      expect(SurfaceFactory.instance.numAvailableOverlays, 0);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _platformView,
        _platformView,
      ]);

      // Frame 2:
      //   Render: Views 2-11
      //   Expect: main canvas plus platform view overlays; empty cache.
      await Future<void>.delayed(Duration.zero);
      renderTestScene(<int>[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
      expect(SurfaceFactory.instance.numAvailableOverlays, 0);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _platformView,
        _platformView,
      ]);

      // Frame 3:
      //   Render: Views 3-12
      //   Expect: main canvas plus platform view overlays; empty cache.
      await Future<void>.delayed(Duration.zero);
      renderTestScene(<int>[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _platformView,
        _platformView,
      ]);

      // Frame 4:
      //   Render: Views 3-12 again (same as last frame)
      //   Expect: main canvas plus platform view overlays; empty cache.
      await Future<void>.delayed(Duration.zero);
      renderTestScene(<int>[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
        _platformView,
        _platformView,
        _platformView,
      ]);

      // TODO(yjbanov): skipped due to https://github.com/flutter/flutter/issues/73867
    }, skip: isSafari);

    test('embeds and disposes of a platform view', () async {
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
      ]);

      expect(
        flutterViewEmbedder.glassPaneElement!
            .querySelector('flt-platform-view'),
        isNotNull,
      );

      await disposePlatformView(0);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);

      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
      ]);

      expect(
        flutterViewEmbedder.glassPaneElement!
            .querySelector('flt-platform-view'),
        isNull,
      );
    });

    test('does not crash when resizing the window after textures have been registered', () async {
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      final CkBrowserImageDecoder image = await CkBrowserImageDecoder.create(
        data: kAnimatedGif,
        debugSource: 'test',
      );
      final ui.FrameInfo frame = await image.getNextFrame();
      final CkImage ckImage = frame.image as CkImage;

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      final CkPictureRecorder recorder = CkPictureRecorder();
      final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
      canvas.drawImage(ckImage, ui.Offset.zero, CkPaint());
      final CkPicture picture = recorder.endRecording();
      sb.addPicture(ui.Offset.zero, picture);
      sb.addPlatformView(0, width: 10, height: 10);

      window.webOnlyDebugPhysicalSizeOverride = const ui.Size(100, 100);
      window.debugForceResize();
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
      ]);

      window.webOnlyDebugPhysicalSizeOverride = const ui.Size(200, 200);
      window.debugForceResize();
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
      ]);

      window.webOnlyDebugPhysicalSizeOverride = null;
      window.debugForceResize();
    // ImageDecoder is not supported in Safari or Firefox.
    }, skip: isSafari || isFirefox);

    test('removed the DOM node of an unrendered platform view', () async {
      final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
      ]);

      expect(
        flutterViewEmbedder.glassPaneElement!
            .querySelector('flt-platform-view'),
        isNotNull,
      );

      // Render a frame with a different platform view.
      await createPlatformView(1, 'test-platform-view');
      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(1, width: 10, height: 10);
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
      ]);

      expect(
          flutterViewEmbedder.glassPaneElement!
              .querySelectorAll('flt-platform-view'),
          hasLength(2));

      // Render a frame without a platform view, but also without disposing of
      // the platform view.
      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
      ]);

      // The actual contents of the platform view are kept in the dom, until
      // it's actually disposed of!
      expect(
          flutterViewEmbedder.glassPaneElement!
              .querySelectorAll('flt-platform-view'),
          hasLength(2));
    });

    test(
        'removes old SVG clip definitions from the DOM when the view is recomposited',
        () async {
      final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'test-view',
      );
      await createPlatformView(0, 'test-platform-view');

      void renderTestScene() {
        final LayerSceneBuilder sb = LayerSceneBuilder();
        sb.pushOffset(0, 0);
        sb.pushClipRRect(
            ui.RRect.fromLTRBR(0, 0, 10, 10, const ui.Radius.circular(3)));
        sb.addPlatformView(0, width: 10, height: 10);
        rasterizer.draw(sb.build().layerTree);
      }

      final DomNode skPathDefs = flutterViewEmbedder.sceneElement!
          .querySelector('#sk_path_defs')!;

      expect(skPathDefs.childNodes, hasLength(0));

      renderTestScene();
      expect(skPathDefs.childNodes, hasLength(1));

      await Future<void>.delayed(Duration.zero);
      renderTestScene();
      expect(skPathDefs.childNodes, hasLength(1));

      await Future<void>.delayed(Duration.zero);
      renderTestScene();
      expect(skPathDefs.childNodes, hasLength(1));
    });

    test('does not crash when a prerolled platform view is not composited',
        () async {
      final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.pushClipRect(ui.Rect.zero);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.pop();
      // The below line should not throw an error.
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
      ]);
    });

    test('does not crash when overlays are disabled', () async {
      final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
      HtmlViewEmbedder.debugDisableOverlays = true;
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.pop();
      // The below line should not throw an error.
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
      ]);
      HtmlViewEmbedder.debugDisableOverlays = false;
    });

    test('works correctly with max overlays == 2', () async {
      final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
      final FlutterConfiguration config = FlutterConfiguration()
        ..setUserConfiguration(
          js_util.jsify(<String, Object?>{
            'canvasKitMaximumSurfaces': 2,
          }) as JsFlutterConfiguration);
      debugSetConfiguration(config);

      SurfaceFactory.instance.debugClear();

      expect(SurfaceFactory.instance.maximumSurfaces, 2);
      expect(SurfaceFactory.instance.maximumOverlays, 1);

      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');
      await createPlatformView(1, 'test-platform-view');

      LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.pop();
      // The below line should not throw an error.
      rasterizer.draw(sb.build().layerTree);

      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
      ]);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.pop();
      // The below line should not throw an error.
      rasterizer.draw(sb.build().layerTree);

      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
        _platformView,
      ]);

      // Reset configuration
      debugSetConfiguration(FlutterConfiguration());
    });

    test(
        'correctly renders when overlays are disabled and a subset '
        'of views is used', () async {
      final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
      HtmlViewEmbedder.debugDisableOverlays = true;
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');
      await createPlatformView(1, 'test-platform-view');

      LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.pop();
      // The below line should not throw an error.
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _platformView,
      ]);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.pop();
      // The below line should not throw an error.
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
      ]);

      HtmlViewEmbedder.debugDisableOverlays = false;
    });

    test('does not create overlays for invisible platform views', () async {
      final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
      ui.platformViewRegistry.registerViewFactory(
          'test-visible-view',
          (int viewId) =>
              createDomHTMLDivElement()..className = 'visible-platform-view');
      ui.platformViewRegistry.registerViewFactory(
        'test-invisible-view',
        (int viewId) =>
            createDomHTMLDivElement()..className = 'invisible-platform-view',
        isVisible: false,
      );
      await createPlatformView(0, 'test-visible-view');
      await createPlatformView(1, 'test-invisible-view');
      await createPlatformView(2, 'test-visible-view');
      await createPlatformView(3, 'test-invisible-view');
      await createPlatformView(4, 'test-invisible-view');
      await createPlatformView(5, 'test-invisible-view');
      await createPlatformView(6, 'test-invisible-view');

      expect(platformViewManager.isInvisible(0), isFalse);
      expect(platformViewManager.isInvisible(1), isTrue);

      LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.pop();
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _overlay,
      ]);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.pop();
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _platformView,
        _overlay,
      ]);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.addPlatformView(2, width: 10, height: 10);
      sb.pop();
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _platformView,
        _overlay,
        _platformView,
        _overlay,
      ]);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.addPlatformView(2, width: 10, height: 10);
      sb.addPlatformView(3, width: 10, height: 10);
      sb.pop();
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _platformView,
        _overlay,
        _platformView,
        _platformView,
        _overlay,
      ]);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.addPlatformView(2, width: 10, height: 10);
      sb.addPlatformView(3, width: 10, height: 10);
      sb.addPlatformView(4, width: 10, height: 10);
      sb.pop();
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _platformView,
        _overlay,
        _platformView,
        _platformView,
        _platformView,
        _overlay,
      ]);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.addPlatformView(2, width: 10, height: 10);
      sb.addPlatformView(3, width: 10, height: 10);
      sb.addPlatformView(4, width: 10, height: 10);
      sb.addPlatformView(5, width: 10, height: 10);
      sb.pop();
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _platformView,
        _overlay,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _overlay,
      ]);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(0, width: 10, height: 10);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.addPlatformView(2, width: 10, height: 10);
      sb.addPlatformView(3, width: 10, height: 10);
      sb.addPlatformView(4, width: 10, height: 10);
      sb.addPlatformView(5, width: 10, height: 10);
      sb.addPlatformView(6, width: 10, height: 10);
      sb.pop();
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _platformView,
        _overlay,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _overlay,
      ]);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.addPlatformView(3, width: 10, height: 10);
      sb.addPlatformView(4, width: 10, height: 10);
      sb.addPlatformView(5, width: 10, height: 10);
      sb.addPlatformView(6, width: 10, height: 10);
      sb.pop();
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _overlay,
      ]);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.addPlatformView(2, width: 10, height: 10);
      sb.addPlatformView(3, width: 10, height: 10);
      sb.addPlatformView(4, width: 10, height: 10);
      sb.pop();
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _overlay,
      ]);

      sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      sb.addPlatformView(4, width: 10, height: 10);
      sb.addPlatformView(3, width: 10, height: 10);
      sb.addPlatformView(2, width: 10, height: 10);
      sb.addPlatformView(1, width: 10, height: 10);
      sb.pop();
      rasterizer.draw(sb.build().layerTree);
      _expectSceneMatches(<_EmbeddedViewMarker>[
        _overlay,
        _platformView,
        _platformView,
        _platformView,
        _platformView,
        _overlay,
      ]);
    });
  });
}

// Used to test that the platform views and overlays are in the correct order in
// the scene.
enum _EmbeddedViewMarker {
  overlay,
  platformView,
}

_EmbeddedViewMarker get _overlay => _EmbeddedViewMarker.overlay;
_EmbeddedViewMarker get _platformView => _EmbeddedViewMarker.platformView;

void _expectSceneMatches(List<_EmbeddedViewMarker> markers) {
  final List<DomElement> sceneElements = flutterViewEmbedder
      .sceneElement!.children
      .where((DomElement element) => element.tagName != 'svg')
      .toList();
  expect(markers, hasLength(sceneElements.length));
  for (int i = 0; i < markers.length; i++) {
    switch (markers[i]) {
      case _EmbeddedViewMarker.overlay:
        expect(sceneElements[i].tagName, 'FLT-CANVAS-CONTAINER');
        break;
      case _EmbeddedViewMarker.platformView:
        expect(sceneElements[i].tagName, 'FLT-PLATFORM-VIEW-SLOT');
        break;
    }
  }
}
