// 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:html' as html;
import 'dart:js_util' as js_util;
import 'dart:typed_data';

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' hide TextStyle, ImageShader;

import 'package:web_engine_tester/golden_tester.dart';

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

Future<void> testMain() async {
  const double screenWidth = 600.0;
  const double screenHeight = 800.0;
  const Rect screenRect = Rect.fromLTWH(0, 0, screenWidth, screenHeight);

  // Commit a recording canvas to a bitmap, and compare with the expected
  Future<void> _checkScreenshot(RecordingCanvas rc, String fileName,
      {Rect region = const Rect.fromLTWH(0, 0, 500, 500),
      double maxDiffRatePercent = 0.0,
      bool write = false}) async {
    final EngineCanvas engineCanvas =
        BitmapCanvas(screenRect, RenderStrategy());
    rc.endRecording();
    rc.apply(engineCanvas, screenRect);

    // Wrap in <flt-scene> so that our CSS selectors kick in.
    final html.Element sceneElement = html.Element.tag('flt-scene');
    try {
      sceneElement.append(engineCanvas.rootElement);
      html.document.body!.append(sceneElement);
      await matchGoldenFile(
        '$fileName.png',
        region: region,
        write: write,
        maxDiffRatePercent: maxDiffRatePercent,
      );
    } finally {
      // The page is reused across tests, so remove the element after taking the
      // golden screenshot.
      sceneElement.remove();
    }
  }

  setUp(() async {
    debugEmulateFlutterTesterEnvironment = true;
    disposeWebGl();
    await webOnlyInitializePlatform();
    webOnlyFontCollection.debugRegisterTestFonts();
    await webOnlyFontCollection.ensureFontsLoaded();
  });

  Future<void> _testVertices(
      String fileName, Vertices vertices, BlendMode blendMode, Paint paint,
      {bool write = false}) async {
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
    rc.drawVertices(
        vertices as SurfaceVertices, blendMode, paint as SurfacePaint);
    await _checkScreenshot(rc, fileName, write: write);
  }

  test('Should draw green hairline triangles when colors array is null.',
      () async {
    final Vertices vertices = Vertices.raw(
        VertexMode.triangles,
        Float32List.fromList(<double>[
          20.0,
          20.0,
          220.0,
          10.0,
          110.0,
          220.0,
          220.0,
          320.0,
          20.0,
          310.0,
          200.0,
          420.0
        ]));
    await _testVertices('draw_vertices_hairline_triangle', vertices,
        BlendMode.srcOver, Paint()..color = Color.fromARGB(255, 0, 128, 0));
  });

  test(
      'Should draw black hairline triangles when colors array is null'
      ' and Paint() has no color.', () async {
    // ignore: unused_local_variable
    final Int32List colors = Int32List.fromList(<int>[
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF,
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF,
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF,
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF
    ]);
    final Vertices vertices = Vertices.raw(
        VertexMode.triangles,
        Float32List.fromList(<double>[
          20.0,
          20.0,
          220.0,
          10.0,
          110.0,
          220.0,
          220.0,
          320.0,
          20.0,
          310.0,
          200.0,
          420.0
        ]));
    await _testVertices('draw_vertices_hairline_triangle_black', vertices,
        BlendMode.srcOver, Paint());
  });

  /// Regression test for https://github.com/flutter/flutter/issues/71442.
  test(
      'Should draw filled triangles when colors array is null'
      ' and Paint() has color.', () async {
    // ignore: unused_local_variable
    final Int32List colors = Int32List.fromList(<int>[
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF,
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF,
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF,
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF
    ]);
    final Vertices vertices = Vertices.raw(
        VertexMode.triangles,
        Float32List.fromList(<double>[
          20.0,
          20.0,
          220.0,
          10.0,
          110.0,
          220.0,
          220.0,
          320.0,
          20.0,
          310.0,
          200.0,
          420.0
        ]));
    await _testVertices(
        'draw_vertices_triangle_green_filled',
        vertices,
        BlendMode.srcOver,
        Paint()
          ..style = PaintingStyle.fill
          ..color = const Color(0xFF00FF00));
  });

  test('Should draw hairline triangleFan.', () async {
    final Vertices vertices = Vertices.raw(
        VertexMode.triangleFan,
        Float32List.fromList(<double>[
          150.0,
          150.0,
          20.0,
          10.0,
          80.0,
          20.0,
          220.0,
          15.0,
          280.0,
          30.0,
          300.0,
          420.0
        ]));

    await _testVertices('draw_vertices_hairline_triangle_fan', vertices,
        BlendMode.srcOver, Paint()..color = Color.fromARGB(255, 0, 128, 0));
  });

  test('Should draw hairline triangleStrip.', () async {
    final Vertices vertices = Vertices.raw(
        VertexMode.triangleStrip,
        Float32List.fromList(<double>[
          20.0,
          20.0,
          220.0,
          10.0,
          110.0,
          220.0,
          220.0,
          320.0,
          20.0,
          310.0,
          200.0,
          420.0
        ]));
    await _testVertices('draw_vertices_hairline_triangle_strip', vertices,
        BlendMode.srcOver, Paint()..color = Color.fromARGB(255, 0, 128, 0));
  });

  test('Should draw triangles with colors.', () async {
    final Int32List colors = Int32List.fromList(<int>[
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF,
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF
    ]);
    final Vertices vertices = Vertices.raw(
        VertexMode.triangles,
        Float32List.fromList(<double>[
          150.0,
          150.0,
          20.0,
          10.0,
          80.0,
          20.0,
          220.0,
          15.0,
          280.0,
          30.0,
          300.0,
          420.0
        ]),
        colors: colors);

    await _testVertices('draw_vertices_triangles', vertices, BlendMode.srcOver,
        Paint()..color = Color.fromARGB(255, 0, 128, 0));
  });

  test('Should draw triangles with colors and indices.', () async {
    final Int32List colors = Int32List.fromList(
        <int>[0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000, 0xFF0000FF]);
    final Uint16List indices = Uint16List.fromList(<int>[0, 1, 2, 3, 4, 0]);

    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));

    final Vertices vertices = Vertices.raw(
        VertexMode.triangles,
        Float32List.fromList(<double>[
          210.0,
          150.0,
          30.0,
          110.0,
          80.0,
          30.0,
          220.0,
          15.0,
          280.0,
          30.0,
        ]),
        colors: colors,
        indices: indices);

    rc.drawVertices(
        vertices as SurfaceVertices, BlendMode.srcOver, SurfacePaint());

    await _checkScreenshot(rc, 'draw_vertices_triangles_indexed');
  });

  test('Should draw triangleFan with colors.', () async {
    final Int32List colors = Int32List.fromList(<int>[
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF,
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF
    ]);
    final Vertices vertices = Vertices.raw(
        VertexMode.triangleFan,
        Float32List.fromList(<double>[
          150.0,
          150.0,
          20.0,
          10.0,
          80.0,
          20.0,
          220.0,
          15.0,
          280.0,
          30.0,
          300.0,
          420.0
        ]),
        colors: colors);

    await _testVertices('draw_vertices_triangle_fan', vertices,
        BlendMode.srcOver, Paint()..color = Color.fromARGB(255, 0, 128, 0));
  });

  test('Should draw triangleStrip with colors.', () async {
    final Int32List colors = Int32List.fromList(<int>[
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF,
      0xFFFF0000,
      0xFF00FF00,
      0xFF0000FF
    ]);
    final Vertices vertices = Vertices.raw(
        VertexMode.triangleStrip,
        Float32List.fromList(<double>[
          20.0,
          20.0,
          220.0,
          10.0,
          110.0,
          220.0,
          220.0,
          320.0,
          20.0,
          310.0,
          200.0,
          420.0
        ]),
        colors: colors);
    await _testVertices('draw_vertices_triangle_strip', vertices,
        BlendMode.srcOver, Paint()..color = Color.fromARGB(255, 0, 128, 0));
  });

  Future<void> testTexture(TileMode tileMode, String filename) async {
    final Uint16List indices = Uint16List.fromList(<int>[0, 1, 2, 3, 4, 0]);

    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));

    final Vertices vertices = Vertices.raw(
        VertexMode.triangles,
        Float32List.fromList(<double>[
          210.0,
          150.0,
          0.0,
          0.0,
          80.0,
          30.0,
          220.0,
          15.0,
          280.0,
          30.0,
        ]),
        indices: indices);

    final Float32List matrix4 = Matrix4.identity().storage;

    final HtmlImage img = await createTestImage();
    final SurfacePaint paint = SurfacePaint();

    final EngineImageShader imgShader = EngineImageShader(img, tileMode, tileMode,
        Float64List.fromList(matrix4), FilterQuality.high);

    paint.shader = imgShader;

    rc.drawVertices(vertices as SurfaceVertices, BlendMode.srcOver, paint);
    await _checkScreenshot(rc, filename, maxDiffRatePercent: 1.0);
  }

  test('Should draw triangle with texture and indices', () async {
    await testTexture(TileMode.clamp, 'draw_vertices_texture');
  });

  test('Should draw triangle with texture and indices', () async {
    await testTexture(TileMode.mirror, 'draw_vertices_texture_mirror');
  });

  test('Should draw triangle with texture and indices', () async {
    await testTexture(TileMode.repeated, 'draw_vertices_texture_repeated');
  });
}

Future<HtmlImage> createTestImage({int width = 50, int height = 40}) {
  final html.CanvasElement canvas =
      html.CanvasElement(width: width, height: height);
  final html.CanvasRenderingContext2D ctx = canvas.context2D;
  ctx.fillStyle = '#E04040';
  ctx.fillRect(0, 0, width / 3, height);
  ctx.fill();
  ctx.fillStyle = '#40E080';
  ctx.fillRect(width / 3, 0, width / 3, height);
  ctx.fill();
  ctx.fillStyle = '#2040E0';
  ctx.fillRect(2 * width / 3, 0, width / 3, height);
  ctx.fill();
  final html.ImageElement imageElement = html.ImageElement();
  final Completer<HtmlImage> completer = Completer<HtmlImage>();
  imageElement.onLoad.listen((html.Event event) {
    completer.complete(HtmlImage(imageElement, width, height));
  });
  imageElement.src = js_util.callMethod(canvas, 'toDataURL', <dynamic>[]);
  return completer.future;
}
