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

import 'package:web_engine_tester/golden_tester.dart';
import 'screenshot.dart';

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

Future<void> testMain() async {
  const Rect region = Rect.fromLTWH(0, 0, 500, 100);

  late BitmapCanvas canvas;

  void appendToScene() {
    // Create a <flt-scene> element to make sure our CSS reset applies correctly.
    final html.Element testScene = html.Element.tag('flt-scene');
    if (isIosSafari) {
      // Shrink to fit on the iPhone screen.
      testScene.style.position = 'absolute';
      testScene.style.transformOrigin = '0 0 0';
      testScene.style.transform = 'scale(0.3)';
    }
    testScene.append(canvas.rootElement as html.Node);
    flutterViewEmbedder.glassPaneShadow!.querySelector('flt-scene-host')!.append(testScene);
  }

  setUpStableTestFonts();

  tearDown(() {
    flutterViewEmbedder.glassPaneShadow?.querySelector('flt-scene')?.remove();
  });

  /// Draws several lines, some aligned precisely with the pixel grid, and some
  /// that are offset by 0.5 vertically or horizontally.
  ///
  /// The produced picture stresses the antialiasing generated by the browser
  /// when positioning and rasterizing `<canvas>` tags. Aliasing artifacts can
  /// be seen depending on pixel alignment and whether antialiasing happens
  /// before or after rasterization.
  void drawMisalignedLines(BitmapCanvas canvas) {
    final SurfacePaintData linePaint = (SurfacePaint()
          ..style = PaintingStyle.stroke
          ..strokeWidth = 1)
        .paintData;

    final SurfacePaintData fillPaint =
        (SurfacePaint()..style = PaintingStyle.fill).paintData;

    canvas.translate(10, 10);

    canvas.drawRect(
      const Rect.fromLTWH(0, 0, 40, 40),
      linePaint,
    );

    canvas.drawLine(
      const Offset(10, 0),
      const Offset(10, 40),
      linePaint,
    );

    canvas.drawLine(
      const Offset(20.5, 0),
      const Offset(20, 40),
      linePaint,
    );

    canvas.drawCircle(const Offset(30, 10), 3, fillPaint);
    canvas.drawCircle(const Offset(30.5, 30), 3, fillPaint);
  }

  test('renders pixels that are not aligned inside the canvas', () async {
    canvas = BitmapCanvas(const Rect.fromLTWH(0, 0, 60, 60),
        RenderStrategy());

    drawMisalignedLines(canvas);

    appendToScene();

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

  test('compensates for misalignment of the canvas', () async {
    // Notice the 0.5 offset in the bounds rectangle. It's what causes the
    // misalignment of canvas relative to the pixel grid. BitmapCanvas will
    // shift its position back to 0.0 and at the same time it will it will
    // compensate by shifting the contents of the canvas in the opposite
    // direction.
    canvas = BitmapCanvas(const Rect.fromLTWH(0.5, 0.5, 60, 60),
        RenderStrategy());
    canvas.clipRect(const Rect.fromLTWH(0, 0, 50, 50), ClipOp.intersect);
    drawMisalignedLines(canvas);

    appendToScene();

    await matchGoldenFile('misaligned_canvas_test.png', region: region,
      maxDiffRatePercent: 1.0);
  });

  test('fill the whole canvas with color even when transformed', () async {
    canvas = BitmapCanvas(const Rect.fromLTWH(0, 0, 50, 50),
        RenderStrategy());
    canvas.clipRect(const Rect.fromLTWH(0, 0, 50, 50), ClipOp.intersect);
    canvas.translate(25, 25);
    canvas.drawColor(const Color.fromRGBO(0, 255, 0, 1.0), BlendMode.src);

    appendToScene();

    await matchGoldenFile('bitmap_canvas_fills_color_when_transformed.png',
        region: region,
        maxDiffRatePercent: 5.0);
  });

  test('fill the whole canvas with paint even when transformed', () async {
    canvas = BitmapCanvas(const Rect.fromLTWH(0, 0, 50, 50),
        RenderStrategy());
    canvas.clipRect(const Rect.fromLTWH(0, 0, 50, 50), ClipOp.intersect);
    canvas.translate(25, 25);
    canvas.drawPaint(SurfacePaintData()
      ..color = const Color.fromRGBO(0, 255, 0, 1.0)
      ..style = PaintingStyle.fill);

    appendToScene();

    await matchGoldenFile('bitmap_canvas_fills_paint_when_transformed.png',
        region: region,
        maxDiffRatePercent: 5.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 canvas. See a similar test in `compositing_golden_test.dart`,
  // which clips using layers.
  //
  // More details: https://github.com/flutter/flutter/issues/32274
  test('renders clipped DOM text with high quality', () async {
    final CanvasParagraph paragraph =
        (ParagraphBuilder(ParagraphStyle(fontFamily: 'Roboto'))
          ..addText('Am I blurry?')).build() as CanvasParagraph;
    paragraph.layout(const ParagraphConstraints(width: 1000));

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

    canvas = BitmapCanvas(canvasSize, RenderStrategy());
    canvas.debugChildOverdraw = true;
    canvas.clipRect(outerClip, ClipOp.intersect);
    canvas.drawParagraph(paragraph, const Offset(8.5, 8.5));
    canvas.clipRect(innerClip, ClipOp.intersect);
    canvas.drawParagraph(paragraph, Offset(8.5, 8.5 + innerClip.top));

    expect(
      canvas.rootElement.querySelectorAll('flt-paragraph').map<String>((DomElement e) => e.innerText).toList(),
      <String>['Am I blurry?', 'Am I blurry?'],
      reason: 'Expected to render text using HTML',
    );

    appendToScene();

    await matchGoldenFile(
      'bitmap_canvas_draws_high_quality_text.png',
      region: canvasSize,
      maxDiffRatePercent: 0.0,
      pixelComparison: PixelComparison.precise,
    );
  }, testOn: 'chrome');

  // NOTE: Chrome in --headless mode does not reproduce the bug that this test
  //       attempts to reproduce. However, it's still good to have this test
  //       for potential future regressions related to paint order.
  test('draws text on top of canvas when transformed and clipped', () async {
    final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(
      fontFamily: 'Ahem',
      fontSize: 18,
    ));

    const String text = 'This text is intentionally very long to make sure that it '
      'breaks into multiple lines.';
    builder.addText(text);

    final CanvasParagraph paragraph = builder.build() as CanvasParagraph;
    paragraph.layout(const ParagraphConstraints(width: 100));

    final Rect canvasSize = Offset.zero & const Size(500, 500);

    canvas = BitmapCanvas(canvasSize, RenderStrategy());
    canvas.debugChildOverdraw = true;

    final SurfacePaintData pathPaint = SurfacePaintData()
      ..color = const Color(0xFF7F7F7F)
      ..style = PaintingStyle.fill;

    const double r = 200.0;
    const double l = 50.0;

    final Path path = (Path()
      ..moveTo(-l, -l)
      ..lineTo(0, -r)
      ..lineTo(l, -l)
      ..lineTo(r, 0)
      ..lineTo(l, l)
      ..lineTo(0, r)
      ..lineTo(-l, l)
      ..lineTo(-r, 0)
      ..close()).shift(const Offset(250, 250));

    canvas.drawPath(path, pathPaint);
    canvas.drawParagraph(paragraph, const Offset(180, 50));

    expect(
      canvas.rootElement.querySelectorAll('flt-paragraph').map<String?>((DomElement e) => e.text).toList(),
      <String>[text],
      reason: 'Expected to render text using HTML',
    );

    final SceneBuilder sb = SceneBuilder();
    sb.pushTransform(Matrix4.diagonal3Values(EnginePlatformDispatcher.browserDevicePixelRatio,
        EnginePlatformDispatcher.browserDevicePixelRatio, 1.0).toFloat64());
    sb.pushTransform(Matrix4.rotationZ(math.pi / 2).toFloat64());
    sb.pushOffset(0, -500);
    sb.pushClipRect(canvasSize);
    sb.pop();
    sb.pop();
    sb.pop();
    sb.pop();
    final SurfaceScene scene = sb.build() as SurfaceScene;
    final DomElement sceneElement = scene.webOnlyRootElement!;
    if (isIosSafari) {
      // Shrink to fit on the iPhone screen.
      sceneElement.style.position = 'absolute';
      sceneElement.style.transformOrigin = '0 0 0';
      sceneElement.style.transform = 'scale(0.3)';
    }

    sceneElement.querySelector('flt-clip')!.append(canvas.rootElement);
    flutterViewEmbedder.glassPaneShadow!.querySelector('flt-scene-host')!.append(sceneElement as html.Node);

    await matchGoldenFile(
      'bitmap_canvas_draws_text_on_top_of_canvas.png',
      region: canvasSize,
      maxDiffRatePercent: 1.0,
      pixelComparison: PixelComparison.precise,
    );
  });

  // Regression test for https://github.com/flutter/flutter/issues/96498. When
  // a picture is made of just text that can be rendered using plain HTML,
  // BitmapCanvas should not create any <canvas> elements as they are expensive.
  test('does not allocate bitmap canvas just for text', () async {
    canvas = BitmapCanvas(const Rect.fromLTWH(0, 0, 50, 50), RenderStrategy());

    final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(fontFamily: 'Roboto'));
    builder.addText('Hello');
    final CanvasParagraph paragraph = builder.build() as CanvasParagraph;
    paragraph.layout(const ParagraphConstraints(width: 1000));

    canvas.drawParagraph(paragraph, const Offset(8.5, 8.5));
    expect(
      canvas.rootElement.querySelectorAll('canvas'),
      isEmpty,
    );
    expect(
      canvas.rootElement.querySelectorAll('flt-paragraph').single.innerText,
      'Hello',
    );
  });
}
