// 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.dart';

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

const ui.Rect region = ui.Rect.fromLTRB(0, 0, 500, 250);

Future<void> matchSceneGolden(String goldenFile, LayerScene scene,
    {bool write = false}) async {
  final EnginePlatformDispatcher dispatcher =
  ui.window.platformDispatcher as EnginePlatformDispatcher;
  dispatcher.rasterizer!.draw(scene.layerTree);
  await matchGoldenFile(goldenFile, region: region, write: write);
}

void testMain() {
  group('ShaderMask', () {
    setUpCanvasKitTest();

    test('Renders sweep gradient with color blend', () async {
      final LayerSceneBuilder builder = LayerSceneBuilder();

      builder.pushOffset(0, 0);

      // Draw a red circle and apply it to the scene.
      final CkPictureRecorder recorder = CkPictureRecorder();
      final CkCanvas canvas = recorder.beginRecording(region);

      canvas.drawCircle(
        ui.Offset(425, 125),
        50,
        CkPaint()..color = ui.Color.fromARGB(255, 255, 0, 0),
      );
      final CkPicture redCircle = recorder.endRecording();

      builder.addPicture(ui.Offset.zero, redCircle);

      final CkGradientSweep shader = CkGradientSweep(
          ui.Offset(250, 125),
          <ui.Color>[
            ui.Color(0xFF4285F4),
            ui.Color(0xFF34A853),
            ui.Color(0xFFFBBC05),
            ui.Color(0xFFEA4335),
            ui.Color(0xFF4285F4),
          ],
          <double>[
            0.0,
            0.25,
            0.5,
            0.75,
            1.0,
          ],
          ui.TileMode.clamp,
          -(math.pi / 2),
          math.pi * 2 - (math.pi / 2),
          null);

      final ui.Path clipPath = ui.Path()
        ..addOval(ui.Rect.fromLTWH(25, 75, 100, 100));
      builder.pushClipPath(clipPath);

      // Apply a shader mask.
      builder.pushShaderMask(shader, ui.Rect.fromLTRB(0, 0, 200, 250),
          ui.BlendMode.color);

      // Draw another red circle and apply it to the scene.
      // This one should be grey since we have the color filter.
      final CkPictureRecorder recorder2 = CkPictureRecorder();
      final CkCanvas canvas2 = recorder2.beginRecording(region);

      canvas2.drawRect(ui.Rect.fromLTWH(25, 75, 100, 100),
        CkPaint()..color = ui.Color.fromARGB(255, 0, 255, 0),
      );

      final CkPicture sweepCircle = recorder2.endRecording();

      builder.addPicture(ui.Offset.zero, sweepCircle);

      await matchSceneGolden('canvaskit_shadermask_linear.png',
          builder.build());
    });

    /// Regression test for https://github.com/flutter/flutter/issues/78959
    test('Renders sweep gradient with color blend translated', () async {
      final LayerSceneBuilder builder = LayerSceneBuilder();

      builder.pushOffset(0, 0);

      // Draw a red circle and apply it to the scene.
      final CkPictureRecorder recorder = CkPictureRecorder();
      final CkCanvas canvas = recorder.beginRecording(region);

      canvas.drawCircle(
        ui.Offset(425, 125),
        50,
        CkPaint()..color = ui.Color.fromARGB(255, 255, 0, 0),
      );
      final CkPicture redCircle = recorder.endRecording();

      builder.addPicture(ui.Offset.zero, redCircle);

      final CkGradientSweep shader = CkGradientSweep(
          ui.Offset(250, 125),
          <ui.Color>[
            ui.Color(0xFF4285F4),
            ui.Color(0xFF34A853),
            ui.Color(0xFFFBBC05),
            ui.Color(0xFFEA4335),
            ui.Color(0xFF4285F4),
          ],
          <double>[
            0.0,
            0.25,
            0.5,
            0.75,
            1.0,
          ],
          ui.TileMode.clamp,
          -(math.pi / 2),
          math.pi * 2 - (math.pi / 2),
          null);

      final ui.Path clipPath = ui.Path()
        ..addOval(ui.Rect.fromLTWH(25, 75, 100, 100));
      builder.pushClipPath(clipPath);

      // Apply a shader mask.
      builder.pushShaderMask(shader, ui.Rect.fromLTRB(50, 50, 200, 250),
          ui.BlendMode.color);

      // Draw another red circle and apply it to the scene.
      // This one should be grey since we have the color filter.
      final CkPictureRecorder recorder2 = CkPictureRecorder();
      final CkCanvas canvas2 = recorder2.beginRecording(region);

      canvas2.drawRect(ui.Rect.fromLTWH(25, 75, 100, 100),
        CkPaint()..color = ui.Color.fromARGB(255, 0, 255, 0),
      );

      final CkPicture sweepCircle = recorder2.endRecording();

      builder.addPicture(ui.Offset.zero, sweepCircle);

      await matchSceneGolden('canvaskit_shadermask_linear_translated.png',
          builder.build());
    });
    // TODO: https://github.com/flutter/flutter/issues/60040
    // TODO: https://github.com/flutter/flutter/issues/71520
  }, skip: isIosSafari || isFirefox);
}
