// 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:math' as math;

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';

const ui.Rect region = ui.Rect.fromLTWH(0, 0, 500, 100);

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

Future<void> testMain() async {
  setUpAll(() async {
    await ui.webOnlyInitializePlatform();
    renderer.fontCollection.debugRegisterTestFonts();
    await renderer.fontCollection.ensureFontsLoaded();
  });

  setUp(() async {
    // To debug test failures uncomment the following to visualize clipping
    // layers:
    // debugShowClipLayers = true;
    SurfaceSceneBuilder.debugForgetFrameScene();
    for (final DomNode scene in domDocument.querySelectorAll('flt-scene')) {
      scene.remove();
    }
  });

  test('pushClipRect', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    builder.pushClipRect(
      const ui.Rect.fromLTRB(10, 10, 60, 60),
    );
    _drawTestPicture(builder);
    builder.pop();

    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_shifted_clip_rect.png', region: region);
  });

  test('pushClipRect with offset and transform', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();

    builder.pushOffset(0, 60);
    builder.pushTransform(
      Matrix4.diagonal3Values(1, -1, 1).toFloat64(),
    );
    builder.pushClipRect(
      const ui.Rect.fromLTRB(10, 10, 60, 60),
    );
    _drawTestPicture(builder);
    builder.pop();
    builder.pop();
    builder.pop();

    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_clip_rect_with_offset_and_transform.png',
        region: region);
  });

  test('pushClipRect with offset and transform ClipOp none should not clip',
      () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();

    builder.pushOffset(0, 80);
    builder.pushTransform(
      Matrix4.diagonal3Values(1, -1, 1).toFloat64(),
    );
    builder.pushClipRect(const ui.Rect.fromLTRB(10, 10, 60, 60),
        clipBehavior: ui.Clip.none);
    _drawTestPicture(builder);
    builder.pop();
    builder.pop();
    builder.pop();

    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_clip_rect_clipop_none.png',
        region: region);
  });

  test('pushClipRRect with offset and transform ClipOp none should not clip',
      () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();

    builder.pushOffset(0, 80);
    builder.pushTransform(
      Matrix4.diagonal3Values(1, -1, 1).toFloat64(),
    );
    builder.pushClipRRect(
        ui.RRect.fromRectAndRadius(
          const ui.Rect.fromLTRB(10, 10, 60, 60),
          const ui.Radius.circular(1),
        ),
        clipBehavior: ui.Clip.none);
    _drawTestPicture(builder);
    builder.pop();
    builder.pop();
    builder.pop();

    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_clip_rrect_clipop_none.png',
        region: region);
  });

  test('pushClipRRect', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    builder.pushClipRRect(
      ui.RRect.fromLTRBR(10, 10, 60, 60, const ui.Radius.circular(5)),
    );
    _drawTestPicture(builder);
    builder.pop();

    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_shifted_clip_rrect.png', region: region);
  });

  test('pushPhysicalShape', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    builder.pushPhysicalShape(
      path: ui.Path()..addRect(const ui.Rect.fromLTRB(10, 10, 60, 60)),
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color.fromRGBO(0, 0, 0, 0.3),
      elevation: 0,
    );
    _drawTestPicture(builder);
    builder.pop();

    builder.pushOffset(70, 0);
    builder.pushPhysicalShape(
      path: ui.Path()
        ..addRRect(ui.RRect.fromLTRBR(10, 10, 60, 60, const ui.Radius.circular(5))),
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color.fromRGBO(0, 0, 0, 0.3),
      elevation: 0,
    );
    _drawTestPicture(builder);
    builder.pop();
    builder.pop();

    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_shifted_physical_shape_clip.png',
        region: region);
  });

  test('pushPhysicalShape clipOp.none', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    builder.pushPhysicalShape(
      path: ui.Path()..addRect(const ui.Rect.fromLTRB(10, 10, 60, 60)),
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color.fromRGBO(0, 0, 0, 0.3),
      elevation: 0,
    );
    _drawTestPicture(builder);
    builder.pop();

    builder.pushOffset(70, 0);
    builder.pushPhysicalShape(
      path: ui.Path()
        ..addRRect(ui.RRect.fromLTRBR(10, 10, 60, 60, const ui.Radius.circular(5))),
      color: const ui.Color.fromRGBO(0, 0, 0, 0.3),
      elevation: 0,
    );
    _drawTestPicture(builder);
    builder.pop();
    builder.pop();

    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_shifted_physical_shape_clipnone.png',
        region: region);
  });

  test('pushPhysicalShape with path and elevation', () async {
    final ui.Path cutCornersButton = ui.Path()
      ..moveTo(15, 10)
      ..lineTo(60, 10)
      ..lineTo(60, 60)
      ..lineTo(15, 60)
      ..lineTo(10, 55)
      ..lineTo(10, 15);

    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    builder.pushPhysicalShape(
      path: cutCornersButton,
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color(0xFFA0FFFF),
      elevation: 2,
    );
    _drawTestPicture(builder);
    builder.pop();

    builder.pushOffset(70, 0);
    builder.pushPhysicalShape(
      path: cutCornersButton,
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color(0xFFA0FFFF),
      elevation: 8,
    );
    _drawTestPicture(builder);
    builder.pop();
    builder.pop();

    builder.pushOffset(140, 0);
    builder.pushPhysicalShape(
      path: ui.Path()..addOval(const ui.Rect.fromLTRB(10, 10, 60, 60)),
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color(0xFFA0FFFF),
      elevation: 4,
    );
    _drawTestPicture(builder);
    builder.pop();
    builder.pop();

    builder.pushOffset(210, 0);
    builder.pushPhysicalShape(
      path: ui.Path()
        ..addRRect(ui.RRect.fromRectAndRadius(
            const ui.Rect.fromLTRB(10, 10, 60, 60), const ui.Radius.circular(10.0))),
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color(0xFFA0FFFF),
      elevation: 4,
    );
    _drawTestPicture(builder);
    builder.pop();
    builder.pop();

    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_physical_shape_path.png',
        region: region);
  });

  test('pushPhysicalShape should update across frames', () async {
    final ui.Path cutCornersButton = ui.Path()
      ..moveTo(15, 10)
      ..lineTo(60, 10)
      ..lineTo(60, 60)
      ..lineTo(15, 60)
      ..lineTo(10, 55)
      ..lineTo(10, 15);

    /// Start with shape that has elevation and red color.
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    final ui.PhysicalShapeEngineLayer oldShapeLayer = builder.pushPhysicalShape(
      path: cutCornersButton,
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color(0xFFFF0000),
      elevation: 2,
    );
    _drawTestPicture(builder);
    builder.pop();

    final DomElement viewElement = builder.build().webOnlyRootElement!;
    domDocument.body!.append(viewElement);
    await matchGoldenFile('compositing_physical_update_1.png', region: region);
    viewElement.remove();

    /// Update color to green.
    final SurfaceSceneBuilder builder2 = SurfaceSceneBuilder();
    final ui.PhysicalShapeEngineLayer oldShapeLayer2 = builder2.pushPhysicalShape(
      path: cutCornersButton,
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color(0xFF00FF00),
      elevation: 2,
      oldLayer: oldShapeLayer,
    );
    _drawTestPicture(builder2);
    builder2.pop();

    final DomElement viewElement2 = builder2.build().webOnlyRootElement!;
    domDocument.body!.append(viewElement2);
    await matchGoldenFile('compositing_physical_update_2.png', region: region);
    viewElement2.remove();

    /// Update elevation.
    final SurfaceSceneBuilder builder3 = SurfaceSceneBuilder();
    final ui.PhysicalShapeEngineLayer oldShapeLayer3 = builder3.pushPhysicalShape(
      path: cutCornersButton,
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color(0xFF00FF00),
      elevation: 6,
      oldLayer: oldShapeLayer2,
    );
    _drawTestPicture(builder3);
    builder3.pop();

    final DomElement viewElement3 = builder3.build().webOnlyRootElement!;
    domDocument.body!.append(viewElement3);
    await matchGoldenFile('compositing_physical_update_3.png',
        region: region);
    viewElement3.remove();

    /// Update shape from arbitrary path to rect.
    final SurfaceSceneBuilder builder4 = SurfaceSceneBuilder();
    final ui.PhysicalShapeEngineLayer oldShapeLayer4 = builder4.pushPhysicalShape(
      path: ui.Path()..addOval(const ui.Rect.fromLTRB(10, 10, 60, 60)),
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color(0xFF00FF00),
      elevation: 6,
      oldLayer: oldShapeLayer3,
    );
    _drawTestPicture(builder4);
    builder4.pop();

    final DomElement viewElement4 = builder4.build().webOnlyRootElement!;
    domDocument.body!.append(viewElement4);
    await matchGoldenFile('compositing_physical_update_4.png', region: region);
    viewElement4.remove();

    /// Update shape back to arbitrary path.
    final SurfaceSceneBuilder builder5 = SurfaceSceneBuilder();
    final ui.PhysicalShapeEngineLayer oldShapeLayer5 = builder5.pushPhysicalShape(
      path: cutCornersButton,
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color(0xFF00FF00),
      elevation: 6,
      oldLayer: oldShapeLayer4,
    );
    _drawTestPicture(builder5);
    builder5.pop();

    final DomElement viewElement5 = builder5.build().webOnlyRootElement!;
    domDocument.body!.append(viewElement5);
    await matchGoldenFile('compositing_physical_update_3.png',
        region: region);
    viewElement5.remove();

    /// Update shadow color.
    final SurfaceSceneBuilder builder6 = SurfaceSceneBuilder();
    builder6.pushPhysicalShape(
      path: cutCornersButton,
      clipBehavior: ui.Clip.hardEdge,
      color: const ui.Color(0xFF00FF00),
      shadowColor: const ui.Color(0xFFFF0000),
      elevation: 6,
      oldLayer: oldShapeLayer5,
    );
    _drawTestPicture(builder6);
    builder6.pop();

    final DomElement viewElement6 = builder6.build().webOnlyRootElement!;
    domDocument.body!.append(viewElement6);
    await matchGoldenFile('compositing_physical_update_5.png', region: region);
    viewElement6.remove();
  });

  test('pushImageFilter blur', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    builder.pushImageFilter(
      ui.ImageFilter.blur(sigmaX: 1, sigmaY: 3),
    );
    _drawTestPicture(builder);
    builder.pop();

    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_image_filter.png', region: region);
  });

  test('pushImageFilter matrix', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    builder.pushImageFilter(
      ui.ImageFilter.matrix(
          (
              Matrix4.identity()
                ..translate(40, 10)
                ..rotateZ(math.pi / 6)
                ..scale(0.75, 0.75)
          ).toFloat64()),
    );
    _drawTestPicture(builder);
    builder.pop();

    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_image_filter_matrix.png', region: region);
  });

  group('Cull rect computation', () {
    _testCullRectComputation();
  });
}

void _testCullRectComputation() {
  // Draw a picture larger that screen. Verify that cull rect is equal to screen
  // bounds.
  test('fills screen bounds', () async {
    final ui.SceneBuilder builder = ui.SceneBuilder();
    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawCircle(
          ui.Offset.zero, 10000, SurfacePaint()..style = ui.PaintingStyle.fill);
    });
    builder.build();

    final PersistedPicture picture = enumeratePictures().single;
    expect(picture.optimalLocalCullRect, const ui.Rect.fromLTRB(0, 0, 500, 100));
  }, skip: '''
  TODO(https://github.com/flutter/flutter/issues/40395)
  Needs ability to set iframe to 500,100 size. Current screen seems to be 500,500''');

  // Draw a picture that overflows the screen. Verify that cull rect is the
  // intersection of screen bounds and paint bounds.
  test('intersects with screen bounds', () async {
    final ui.SceneBuilder builder = ui.SceneBuilder();
    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawCircle(ui.Offset.zero, 20, SurfacePaint()..style = ui.PaintingStyle.fill);
    });
    builder.build();

    final PersistedPicture picture = enumeratePictures().single;
    expect(picture.optimalLocalCullRect, const ui.Rect.fromLTRB(0, 0, 20, 20));
  });

  // Draw a picture that's fully outside the screen bounds. Verify the cull rect
  // is zero.
  test('fully outside screen bounds', () async {
    final ui.SceneBuilder builder = ui.SceneBuilder();
    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawCircle(
          const ui.Offset(-100, -100), 20, SurfacePaint()..style = ui.PaintingStyle.fill);
    });
    builder.build();

    final PersistedPicture picture = enumeratePictures().single;
    expect(picture.optimalLocalCullRect, ui.Rect.zero);
    expect(picture.debugExactGlobalCullRect, ui.Rect.zero);
  });

  // Draw a picture that's fully inside the screen. Verify that cull rect is
  // equal to the paint bounds.
  test('limits to paint bounds if no clip layers', () async {
    final ui.SceneBuilder builder = ui.SceneBuilder();
    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawCircle(
          const ui.Offset(50, 50), 10, SurfacePaint()..style = ui.PaintingStyle.fill);
    });
    builder.build();

    final PersistedPicture picture = enumeratePictures().single;
    expect(picture.optimalLocalCullRect, const ui.Rect.fromLTRB(40, 40, 60, 60));
  });

  // Draw a picture smaller than the screen. Offset it such that it remains
  // fully inside the screen bounds. Verify that cull rect is still just the
  // paint bounds.
  test('offset does not affect paint bounds', () async {
    final ui.SceneBuilder builder = ui.SceneBuilder();

    builder.pushOffset(10, 10);
    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawCircle(
          const ui.Offset(50, 50), 10, SurfacePaint()..style = ui.PaintingStyle.fill);
    });
    builder.pop();

    builder.build();

    final PersistedPicture picture = enumeratePictures().single;
    expect(picture.optimalLocalCullRect, const ui.Rect.fromLTRB(40, 40, 60, 60));
  });

  // Draw a picture smaller than the screen. Offset it such that the picture
  // overflows screen bounds. Verify that the cull rect is the intersection
  // between screen bounds and paint bounds.
  test('offset overflows paint bounds', () async {
    final ui.SceneBuilder builder = ui.SceneBuilder();

    builder.pushOffset(0, 90);
    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawCircle(ui.Offset.zero, 20, SurfacePaint()..style = ui.PaintingStyle.fill);
    });
    builder.pop();

    builder.build();

    final PersistedPicture picture = enumeratePictures().single;
    expect(
        picture.debugExactGlobalCullRect, const ui.Rect.fromLTRB(0, 70, 20, 100));
    expect(picture.optimalLocalCullRect, const ui.Rect.fromLTRB(0, -20, 20, 10));
  }, skip: '''
  TODO(https://github.com/flutter/flutter/issues/40395)
  Needs ability to set iframe to 500,100 size. Current screen seems to be 500,500''');

  // Draw a picture inside a layer clip but fill all available space inside it.
  // Verify that the cull rect is equal to the layer clip.
  test('fills layer clip rect', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    builder.pushClipRect(
      const ui.Rect.fromLTWH(10, 10, 60, 60),
    );

    builder.pushClipRect(
      const ui.Rect.fromLTWH(40, 40, 60, 60),
    );

    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawCircle(
          ui.Offset.zero, 10000, SurfacePaint()..style = ui.PaintingStyle.fill);
    });

    builder.pop(); // pushClipRect
    builder.pop(); // pushClipRect
    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_cull_rect_fills_layer_clip.png',
        region: region);

    final PersistedPicture picture = enumeratePictures().single;
    expect(picture.optimalLocalCullRect, const ui.Rect.fromLTRB(40, 40, 70, 70));
  });

  // Draw a picture inside a layer clip but position the picture such that its
  // paint bounds overflow the layer clip. Verify that the cull rect is the
  // intersection between the layer clip and paint bounds.
  test('intersects layer clip rect and paint bounds', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    builder.pushClipRect(
      const ui.Rect.fromLTWH(10, 10, 60, 60),
    );

    builder.pushClipRect(
      const ui.Rect.fromLTWH(40, 40, 60, 60),
    );

    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawCircle(
          const ui.Offset(80, 55), 30, SurfacePaint()..style = ui.PaintingStyle.fill);
    });

    builder.pop(); // pushClipRect
    builder.pop(); // pushClipRect
    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile(
        'compositing_cull_rect_intersects_clip_and_paint_bounds.png',
        region: region);

    final PersistedPicture picture = enumeratePictures().single;
    expect(picture.optimalLocalCullRect, const ui.Rect.fromLTRB(50, 40, 70, 70));
  });

  // Draw a picture inside a layer clip that's positioned inside the clip using
  // an offset layer. Verify that the cull rect is the intersection between the
  // layer clip and the offset paint bounds.
  test('offsets picture inside layer clip rect', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    builder.pushClipRect(
      const ui.Rect.fromLTWH(10, 10, 60, 60),
    );

    builder.pushClipRect(
      const ui.Rect.fromLTWH(40, 40, 60, 60),
    );

    builder.pushOffset(55, 70);

    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawCircle(ui.Offset.zero, 20, SurfacePaint()..style = ui.PaintingStyle.fill);
    });

    builder.pop(); // pushOffset
    builder.pop(); // pushClipRect
    builder.pop(); // pushClipRect
    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_cull_rect_offset_inside_layer_clip.png',
        region: region);

    final PersistedPicture picture = enumeratePictures().single;
    expect(picture.optimalLocalCullRect,
        const ui.Rect.fromLTRB(-15.0, -20.0, 15.0, 0.0));
  });

  // Draw a picture inside a layer clip that's positioned an offset layer such
  // that the picture is push completely outside the clip area. Verify that the
  // cull rect is zero.
  test('zero intersection with clip', () async {
    final ui.SceneBuilder builder = ui.SceneBuilder();
    builder.pushClipRect(
      const ui.Rect.fromLTWH(10, 10, 60, 60),
    );

    builder.pushClipRect(
      const ui.Rect.fromLTWH(40, 40, 60, 60),
    );

    builder.pushOffset(100, 50);

    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawCircle(ui.Offset.zero, 20, SurfacePaint()..style = ui.PaintingStyle.fill);
    });

    builder.pop(); // pushOffset
    builder.pop(); // pushClipRect
    builder.pop(); // pushClipRect

    builder.build();

    final PersistedPicture picture = enumeratePictures().single;
    expect(picture.optimalLocalCullRect, ui.Rect.zero);
    expect(picture.debugExactGlobalCullRect, ui.Rect.zero);
  });

  // Draw a picture inside a rotated clip. Verify that the cull rect is big
  // enough to fit the rotated clip.
  test('rotates clip and the picture', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    builder.pushOffset(80, 50);

    builder.pushTransform(
      Matrix4.rotationZ(-math.pi / 4).toFloat64(),
    );

    builder.pushClipRect(
      const ui.Rect.fromLTRB(-10, -10, 10, 10),
    );

    builder.pushTransform(
      Matrix4.rotationZ(math.pi / 4).toFloat64(),
    );

    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawPaint(SurfacePaint()
        ..color = const ui.Color.fromRGBO(0, 0, 255, 0.6)
        ..style = ui.PaintingStyle.fill);
      canvas.drawRect(
        const ui.Rect.fromLTRB(-5, -5, 5, 5),
        SurfacePaint()
          ..color = const ui.Color.fromRGBO(0, 255, 0, 1.0)
          ..style = ui.PaintingStyle.fill,
      );
    });

    builder.pop(); // pushTransform
    builder.pop(); // pushClipRect
    builder.pop(); // pushTransform
    builder.pop(); // pushOffset
    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_cull_rect_rotated.png', region: region);

    final PersistedPicture picture = enumeratePictures().single;
    expect(
      picture.optimalLocalCullRect,
      within(
          distance: 0.05, from: const ui.Rect.fromLTRB(-14.1, -14.1, 14.1, 14.1)),
    );
  });

  test('pushClipPath', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
    final ui.Path path = ui.Path();
    path.addRect(const ui.Rect.fromLTRB(10, 10, 60, 60));
    builder.pushClipPath(
      path,
    );
    _drawTestPicture(builder);
    builder.pop();

    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_clip_path.png', region: region);
  });

  // Draw a picture inside a rotated clip. Verify that the cull rect is big
  // enough to fit the rotated clip.
  test('clips correctly when using 3d transforms', () async {
    final SurfaceSceneBuilder builder = SurfaceSceneBuilder();

    builder.pushTransform(Matrix4.diagonal3Values(
            EnginePlatformDispatcher.browserDevicePixelRatio,
            EnginePlatformDispatcher.browserDevicePixelRatio,
            1.0)
        .toFloat64());

    // TODO(yjbanov): see the TODO below.
    // final double screenWidth = domWindow.innerWidth.toDouble();
    // final double screenHeight = domWindow.innerHeight.toDouble();

    final Matrix4 scaleTransform = Matrix4.identity().scaled(0.5, 0.2);
    builder.pushTransform(
      scaleTransform.toFloat64(),
    );

    builder.pushOffset(400, 200);

    builder.pushClipRect(
      const ui.Rect.fromLTRB(-200, -200, 200, 200),
    );

    builder
        .pushTransform(Matrix4.rotationY(45.0 * math.pi / 180.0).toFloat64());

    builder.pushClipRect(
      const ui.Rect.fromLTRB(-140, -140, 140, 140),
    );

    builder.pushTransform(Matrix4.translationValues(0, 0, -50).toFloat64());

    drawWithBitmapCanvas(builder, (RecordingCanvas canvas) {
      canvas.drawPaint(SurfacePaint()
        ..color = const ui.Color.fromRGBO(0, 0, 255, 0.6)
        ..style = ui.PaintingStyle.fill);
      // ui.Rect will be clipped.
      canvas.drawRect(
        const ui.Rect.fromLTRB(-150, -150, 150, 150),
        SurfacePaint()
          ..color = const ui.Color.fromRGBO(0, 255, 0, 1.0)
          ..style = ui.PaintingStyle.fill,
      );
      // Should be outside the clip range.
      canvas.drawRect(
        const ui.Rect.fromLTRB(-150, -150, -140, -140),
        SurfacePaint()
          ..color = const ui.Color.fromARGB(0xE0, 255, 0, 0)
          ..style = ui.PaintingStyle.fill,
      );
      canvas.drawRect(
        const ui.Rect.fromLTRB(140, -150, 150, -140),
        SurfacePaint()
          ..color = const ui.Color.fromARGB(0xE0, 255, 0, 0)
          ..style = ui.PaintingStyle.fill,
      );
      canvas.drawRect(
        const ui.Rect.fromLTRB(-150, 140, -140, 150),
        SurfacePaint()
          ..color = const ui.Color.fromARGB(0xE0, 255, 0, 0)
          ..style = ui.PaintingStyle.fill,
      );
      canvas.drawRect(
        const ui.Rect.fromLTRB(140, 140, 150, 150),
        SurfacePaint()
          ..color = const ui.Color.fromARGB(0xE0, 255, 0, 0)
          ..style = ui.PaintingStyle.fill,
      );
      // Should be inside clip range
      canvas.drawRect(
        const ui.Rect.fromLTRB(-100, -100, -90, -90),
        SurfacePaint()
          ..color = const ui.Color.fromARGB(0xE0, 0, 0, 0x80)
          ..style = ui.PaintingStyle.fill,
      );
      canvas.drawRect(
        const ui.Rect.fromLTRB(90, -100, 100, -90),
        SurfacePaint()
          ..color = const ui.Color.fromARGB(0xE0, 0, 0, 0x80)
          ..style = ui.PaintingStyle.fill,
      );
      canvas.drawRect(
        const ui.Rect.fromLTRB(-100, 90, -90, 100),
        SurfacePaint()
          ..color = const ui.Color.fromARGB(0xE0, 0, 0, 0x80)
          ..style = ui.PaintingStyle.fill,
      );
      canvas.drawRect(
        const ui.Rect.fromLTRB(90, 90, 100, 100),
        SurfacePaint()
          ..color = const ui.Color.fromARGB(0xE0, 0, 0, 0x80)
          ..style = ui.PaintingStyle.fill,
      );
    });

    builder.pop(); // pushTransform Z-50
    builder.pop(); // pushClipRect
    builder.pop(); // pushTransform 3D rotate
    builder.pop(); // pushClipRect
    builder.pop(); // pushOffset
    builder.pop(); // pushTransform scale
    builder.pop(); // pushTransform scale devicepixelratio
    domDocument.body!.append(builder.build().webOnlyRootElement!);

    await matchGoldenFile('compositing_3d_rotate1.png', region: region);

    // ignore: unused_local_variable
    final PersistedPicture picture = enumeratePictures().single;
    // TODO(yjbanov): https://github.com/flutter/flutter/issues/40395)
    //   Needs ability to set iframe to 500,100 size. Current screen seems to be 500,500.
    // expect(
    //   picture.optimalLocalCullRect,
    //   within(
    //       distance: 0.05,
    //       from: ui.Rect.fromLTRB(
    //           -140, -140, screenWidth - 360.0, screenHeight + 40.0)),
    // );
  });

  // This test reproduces text blurriness when two pieces of text appear inside
  // two nested clips:
  //
  //   ┌───────────────────────┐
  //   │   text in outer clip  │
  //   │ ┌────────────────────┐│
  //   │ │ text in inner clip ││
  //   │ └────────────────────┘│
  //   └───────────────────────┘
  //
  // This test clips using layers. See a similar test in `bitmap_canvas_golden_test.dart`,
  // which clips using canvas.
  //
  // More details: https://github.com/flutter/flutter/issues/32274
  test(
    'renders clipped text with high quality',
    () async {
      // To reproduce blurriness we need real clipping.
      final CanvasParagraph paragraph =
          (ui.ParagraphBuilder(ui.ParagraphStyle(fontFamily: 'Roboto'))
                // Use a decoration to force rendering in DOM mode.
                ..pushStyle(ui.TextStyle(decoration: ui.TextDecoration.lineThrough, decorationColor: const ui.Color(0x00000000)))
                ..addText('Am I blurry?'))
              .build() as CanvasParagraph;
      paragraph.layout(const ui.ParagraphConstraints(width: 1000));

      final ui.Rect canvasSize = ui.Rect.fromLTRB(
        0,
        0,
        paragraph.maxIntrinsicWidth + 16,
        2 * paragraph.height + 32,
      );
      final ui.Rect outerClip =
          ui.Rect.fromLTRB(0.5, 0.5, canvasSize.right, canvasSize.bottom);
      final ui.Rect innerClip = ui.Rect.fromLTRB(0.5, canvasSize.bottom / 2 + 0.5,
          canvasSize.right, canvasSize.bottom);
      final SurfaceSceneBuilder builder = SurfaceSceneBuilder();

      builder.pushClipRect(outerClip);

      {
        final EnginePictureRecorder recorder = EnginePictureRecorder();
        final RecordingCanvas canvas = recorder.beginRecording(outerClip);
        canvas.drawParagraph(paragraph, const ui.Offset(8.5, 8.5));
        final ui.Picture picture = recorder.endRecording();
        expect(paragraph.canDrawOnCanvas, isFalse);

        builder.addPicture(
          ui.Offset.zero,
          picture,
        );
      }

      builder.pushClipRect(innerClip);
      {
        final EnginePictureRecorder recorder = EnginePictureRecorder();
        final RecordingCanvas canvas = recorder.beginRecording(innerClip);
        canvas.drawParagraph(paragraph, ui.Offset(8.5, 8.5 + innerClip.top));
        final ui.Picture picture = recorder.endRecording();
        expect(paragraph.canDrawOnCanvas, isFalse);

        builder.addPicture(
          ui.Offset.zero,
          picture,
        );
      }
      builder.pop(); // inner clip
      builder.pop(); // outer clip

      final DomElement sceneElement = builder.build().webOnlyRootElement!;
      expect(
        sceneElement
            .querySelectorAll('flt-paragraph')
            .map<String>((DomElement e) => e.innerText)
            .toList(),
        <String>['Am I blurry?', 'Am I blurry?'],
        reason: 'Expected to render text using HTML',
      );
      domDocument.body!.append(sceneElement);

      await matchGoldenFile(
        'compositing_draw_high_quality_text.png',
        region: canvasSize,
      );
    },
    testOn: 'chrome',
  );
}

void _drawTestPicture(ui.SceneBuilder builder) {
  final EnginePictureRecorder recorder = EnginePictureRecorder();
  final RecordingCanvas canvas =
      recorder.beginRecording(const ui.Rect.fromLTRB(0, 0, 100, 100));
  canvas.drawCircle(
      const ui.Offset(10, 10), 10, SurfacePaint()..style = ui.PaintingStyle.fill);
  canvas.drawCircle(
      const ui.Offset(60, 10),
      10,
      SurfacePaint()
        ..style = ui.PaintingStyle.fill
        ..color = const ui.Color.fromRGBO(255, 0, 0, 1));
  canvas.drawCircle(
      const ui.Offset(10, 60),
      10,
      SurfacePaint()
        ..style = ui.PaintingStyle.fill
        ..color = const ui.Color.fromRGBO(0, 255, 0, 1));
  canvas.drawCircle(
      const ui.Offset(60, 60),
      10,
      SurfacePaint()
        ..style = ui.PaintingStyle.fill
        ..color = const ui.Color.fromRGBO(0, 0, 255, 1));
  final ui.Picture picture = recorder.endRecording();

  builder.addPicture(
    ui.Offset.zero,
    picture,
  );
}

typedef PaintCallback = void Function(RecordingCanvas canvas);

void drawWithBitmapCanvas(ui.SceneBuilder builder, PaintCallback callback,
    {ui.Rect bounds = ui.Rect.largest}) {
  final EnginePictureRecorder recorder = EnginePictureRecorder();
  final RecordingCanvas canvas = recorder.beginRecording(bounds);

  canvas.debugEnforceArbitraryPaint();
  callback(canvas);
  final ui.Picture picture = recorder.endRecording();

  builder.addPicture(
    ui.Offset.zero,
    picture,
  );
}
