// 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 '../common/rendering.dart';
import '../common/test_initialization.dart';
import 'utils.dart';

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

Future<void> testMain() async {
  setUpUnitTests(
    withImplicitView: true,
    emulateTesterEnvironment: false,
    setUpTestViewDimensions: false,
  );

  group('${ui.SceneBuilder}', () {
    const ui.Rect region = ui.Rect.fromLTWH(0, 0, 300, 300);
    test('Test offset layer', () async {
      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
      sceneBuilder.pushOffset(150, 150);
      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        canvas.drawCircle(
          ui.Offset.zero,
          50,
          ui.Paint()..color = const ui.Color(0xFF00FF00)
        );
      }));

      await renderScene(sceneBuilder.build());
      await matchGoldenFile('scene_builder_centered_circle.png', region: region);
    });

    test('Test transform layer', () async {
      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
      final Matrix4 transform = Matrix4.identity();

      // The html renderer expects the top-level transform to just be a scaling
      // matrix for the device pixel ratio, so just push the identity matrix.
      sceneBuilder.pushTransform(transform.toFloat64());
      transform.translate(150, 150);
      transform.rotate(kUnitZ, math.pi / 3);
      sceneBuilder.pushTransform(transform.toFloat64());
      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        canvas.drawRRect(
          ui.RRect.fromRectAndRadius(
            ui.Rect.fromCircle(center: ui.Offset.zero, radius: 50),
            const ui.Radius.circular(10)
          ),
          ui.Paint()..color = const ui.Color(0xFF0000FF)
        );
      }));

      await renderScene(sceneBuilder.build());
      await matchGoldenFile('scene_builder_rotated_rounded_square.png', region: region);
    });

    test('Test clipRect layer', () async {
      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
      sceneBuilder.pushClipRect(const ui.Rect.fromLTRB(0, 0, 150, 150));
      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        canvas.drawCircle(
          const ui.Offset(150, 150),
          50,
          ui.Paint()..color = const ui.Color(0xFFFF0000)
        );
      }));

      await renderScene(sceneBuilder.build());
      await matchGoldenFile('scene_builder_circle_clip_rect.png', region: region);
    });

    test('Test clipRRect layer', () async {
      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
      sceneBuilder.pushClipRRect(ui.RRect.fromRectAndRadius(
        const ui.Rect.fromLTRB(0, 0, 150, 150),
        const ui.Radius.circular(25),
      ), clipBehavior: ui.Clip.antiAlias);
      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        canvas.drawCircle(
          const ui.Offset(150, 150),
          50,
          ui.Paint()..color = const ui.Color(0xFFFF00FF)
        );
      }));

      await renderScene(sceneBuilder.build());
      await matchGoldenFile('scene_builder_circle_clip_rrect.png', region: region);
    });

    test('Test clipPath layer', () async {
      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
      final ui.Path path = ui.Path();
      path.addOval(ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 60));
      sceneBuilder.pushClipPath(path);
      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        canvas.drawRect(
          ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50),
          ui.Paint()..color = const ui.Color(0xFF00FFFF)
        );
      }));

      await renderScene(sceneBuilder.build());
      await matchGoldenFile('scene_builder_rectangle_clip_circular_path.png', region: region);
    });

    test('Test opacity layer', () async {
      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        canvas.drawRect(
          ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50),
          ui.Paint()..color = const ui.Color(0xFF00FF00)
        );
      }));

      sceneBuilder.pushOpacity(0x7F);
      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        final ui.Paint paint = ui.Paint()..color = const ui.Color(0xFFFF0000);
        canvas.drawCircle(
          const ui.Offset(125, 150),
          50,
          paint
        );
        canvas.drawCircle(
          const ui.Offset(175, 150),
          50,
          paint
        );
      }));

      await renderScene(sceneBuilder.build());
      await matchGoldenFile('scene_builder_opacity_circles_on_square.png', region: region);
    });

    test('shader mask layer', () async {
      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();

      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        final ui.Paint paint = ui.Paint()..color = const ui.Color(0xFFFF0000);
        canvas.drawCircle(
          const ui.Offset(125, 150),
          50,
          paint
        );
        canvas.drawCircle(
          const ui.Offset(175, 150),
          50,
          paint
        );
      }));

      final ui.Shader shader = ui.Gradient.linear(
        ui.Offset.zero,
        const ui.Offset(50, 50), <ui.Color>[
          const ui.Color(0xFFFFFFFF),
          const ui.Color(0x00000000),
        ]);
      sceneBuilder.pushShaderMask(
        shader,
        const ui.Rect.fromLTRB(125, 125, 175, 175),
        ui.BlendMode.srcATop
      );

      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        canvas.drawRect(
          ui.Rect.fromCircle(center: const ui.Offset(150, 150), radius: 50),
          ui.Paint()..color = const ui.Color(0xFF00FF00)
        );
      }));

      await renderScene(sceneBuilder.build());
      await matchGoldenFile('scene_builder_shader_mask.png', region: region);
    }, skip: isFirefox && isHtml); // https://github.com/flutter/flutter/issues/86623

    test('backdrop filter layer', () async {
      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();

      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        // Create a red and blue checkerboard pattern
        final ui.Paint redPaint = ui.Paint()..color = const ui.Color(0xFFFF0000);
        final ui.Paint bluePaint = ui.Paint()..color = const ui.Color(0xFF0000FF);
        for (double y = 0; y < 300; y += 10) {
          for (double x = 0; x < 300; x += 10) {
            final ui.Paint paint = ((x + y) % 20 == 0) ? redPaint : bluePaint;
            canvas.drawRect(ui.Rect.fromLTWH(x, y, 10, 10), paint);
          }
        }
      }));

      sceneBuilder.pushBackdropFilter(ui.ImageFilter.blur(
        sigmaX: 3.0,
        sigmaY: 3.0,
      ));

      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        canvas.drawCircle(
          const ui.Offset(150, 150),
          50,
          ui.Paint()..color = const ui.Color(0xFF00FF00)
        );
      }));

      await renderScene(sceneBuilder.build());
      await matchGoldenFile('scene_builder_backdrop_filter.png', region: region);
    });

    test('image filter layer', () async {
      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
      sceneBuilder.pushImageFilter(ui.ImageFilter.blur(
        sigmaX: 5.0,
        sigmaY: 5.0,
      ));

      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        canvas.drawCircle(
          const ui.Offset(150, 150),
          50,
          ui.Paint()..color = const ui.Color(0xFF00FF00)
        );
      }));

      await renderScene(sceneBuilder.build());
      await matchGoldenFile('scene_builder_image_filter.png', region: region);
    });

    test('color filter layer', () async {
      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
      const ui.ColorFilter sepia = ui.ColorFilter.matrix(<double>[
        0.393, 0.769, 0.189, 0, 0,
        0.349, 0.686, 0.168, 0, 0,
        0.272, 0.534, 0.131, 0, 0,
        0,     0,     0,     1, 0,
      ]);
      sceneBuilder.pushColorFilter(sepia);

      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
        canvas.drawCircle(
          const ui.Offset(150, 150),
          50,
          ui.Paint()..color = const ui.Color(0xFF00FF00)
        );
      }));

      await renderScene(sceneBuilder.build());
      await matchGoldenFile('scene_builder_color_filter.png', region: region);
    });
  });
}

ui.Picture drawPicture(void Function(ui.Canvas) drawCommands) {
  final ui.PictureRecorder recorder = ui.PictureRecorder();
  final ui.Canvas canvas = ui.Canvas(recorder);
  drawCommands(canvas);
  return recorder.endRecording();
}
