// 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 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart';

import '../../common/test_initialization.dart';
import '../paragraph/helper.dart';

/// Some text measurements are sensitive to browser implementations. Position
/// info in the following tests only pass in Chrome, they are slightly different
/// on each browser. So we need to ignore position info on non-Chrome browsers
/// when comparing expectations with actual output.
bool get isBlink => browserEngine == BrowserEngine.blink;

String fontFamilyToAttribute(String fontFamily) {
  fontFamily = canonicalizeFontFamily(fontFamily)!;
  if (browserEngine == BrowserEngine.firefox) {
    return fontFamily.replaceAll('"', '&quot;');
  } else if (browserEngine == BrowserEngine.blink ||
      browserEngine == BrowserEngine.webkit) {
    return fontFamily.replaceAll('"', '');
  }
  return fontFamily;
}

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

Future<void> testMain() async {
  setUpUnitTests();

  test('empty paragraph', () {
    final CanvasParagraph paragraph1 = rich(
      EngineParagraphStyle(),
      (CanvasParagraphBuilder builder) {},
    );
    expect(paragraph1.plainText, '');
    expect(paragraph1.spans, hasLength(1));
    expect(paragraph1.spans.single.start, 0);
    expect(paragraph1.spans.single.end, 0);

    final CanvasParagraph paragraph2 = rich(
      EngineParagraphStyle(),
      (CanvasParagraphBuilder builder) {
        builder.addText('');
      },
    );
    expect(paragraph2.plainText, '');
    expect(paragraph2.spans, hasLength(1));
    expect(paragraph2.spans.single.start, 0);
    expect(paragraph2.spans.single.end, 0);
  });

  test('Builds a text-only canvas paragraph', () {
    final EngineParagraphStyle style = EngineParagraphStyle(fontSize: 13.0);
    final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);

    builder.addText('Hello');

    final CanvasParagraph paragraph = builder.build();
    expect(paragraph.paragraphStyle, style);
    expect(paragraph.plainText, 'Hello');
    expect(paragraph.spans, hasLength(1));

    paragraph.layout(const ParagraphConstraints(width: double.infinity));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: 0, left: 0, width: 13*5, fontSize: 13)}">'
      'Hello'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: !isBlink,
    );

    // Should break "Hello" into "Hel" and "lo".
    paragraph.layout(const ParagraphConstraints(width: 39.0));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: 0, left: 0, width: 13*3, fontSize: 13)}">'
      'Hel'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 13, left: 0, width: 13*2, fontSize: 13)}">'
      'lo'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: !isBlink,
    );

    final ParagraphSpan span = paragraph.spans.single;
    expect(getSpanText(paragraph, span), 'Hello');
    expect(span.style, styleWithDefaults(fontSize: 13.0));
  });

  test('Correct defaults', () {
    final EngineParagraphStyle style = EngineParagraphStyle();
    final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);

    builder.addText('Hello');

    final CanvasParagraph paragraph = builder.build();
    expect(paragraph.paragraphStyle, style);
    expect(paragraph.plainText, 'Hello');
    expect(paragraph.spans, hasLength(1));

    paragraph.layout(const ParagraphConstraints(width: double.infinity));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: 0, left: 0, width: 14*5)}">'
      'Hello'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: !isBlink,
    );

    final ParagraphSpan span = paragraph.spans.single;
    expect(span.style, styleWithDefaults());
  });

  test('Sets correct styles for max-lines', () {
    final EngineParagraphStyle style = EngineParagraphStyle(maxLines: 2);
    final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);

    builder.addText('Hello');

    final CanvasParagraph paragraph = builder.build();
    expect(paragraph.paragraphStyle, style);
    expect(paragraph.plainText, 'Hello');

    paragraph.layout(const ParagraphConstraints(width: double.infinity));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: 0, left: 0, width: 14*5)}">'
      'Hello'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: !isBlink,
    );
  });

  test('Sets correct styles for ellipsis', () {
    final EngineParagraphStyle style = EngineParagraphStyle(ellipsis: '...');
    final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);

    builder.addText('HelloWorld');

    final CanvasParagraph paragraph = builder.build();
    expect(paragraph.paragraphStyle, style);
    expect(paragraph.plainText, 'HelloWorld');

    paragraph.layout(const ParagraphConstraints(width: 100.0));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: 0, left: 0, width: 14*4)}">'
      'Hell'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 0, left: 14*4, width: 14*3)}">'
      '...'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: !isBlink,
    );
  });

  test('Builds a single-span paragraph with complex styles', () {
    final EngineParagraphStyle style =
        EngineParagraphStyle(fontSize: 13.0, height: 1.5);
    final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);

    builder.pushStyle(TextStyle(fontSize: 9.0));
    builder.pushStyle(TextStyle(fontWeight: FontWeight.bold));
    builder.pushStyle(TextStyle(fontSize: 40.0));
    builder.pop();
    builder
        .pushStyle(TextStyle(fontStyle: FontStyle.italic, letterSpacing: 2.0));
    builder.addText('Hello');

    final CanvasParagraph paragraph = builder.build();
    expect(paragraph.plainText, 'Hello');
    expect(paragraph.spans, hasLength(1));

    paragraph.layout(const ParagraphConstraints(width: double.infinity));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: 0, left: 0, width: (9+2)*5, lineHeight: 1.5*9, fontSize: 9, fontWeight: 'bold', fontStyle: 'italic', letterSpacing: 2)}">'
      'Hello'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: !isBlink,
    );

    final ParagraphSpan span = paragraph.spans.single;
    expect(getSpanText(paragraph, span), 'Hello');
    expect(
      span.style,
      styleWithDefaults(
        height: 1.5,
        fontSize: 9.0,
        fontWeight: FontWeight.bold,
        fontStyle: FontStyle.italic,
        letterSpacing: 2.0,
      ),
    );
  });

  test('Builds a multi-span paragraph', () {
    final EngineParagraphStyle style = EngineParagraphStyle(fontSize: 13.0);
    final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);

    builder.pushStyle(TextStyle(fontWeight: FontWeight.bold));
    builder.addText('Hello');
    builder.pop();
    builder.pushStyle(TextStyle(fontStyle: FontStyle.italic));
    builder.addText(' world');

    final CanvasParagraph paragraph = builder.build();
    expect(paragraph.plainText, 'Hello world');
    expect(paragraph.spans, hasLength(2));

    paragraph.layout(const ParagraphConstraints(width: double.infinity));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: 0, left: 0, width: 13*5, fontSize: 13, fontWeight: 'bold')}">'
      'Hello'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 0, left: 65, width: 13*1, fontSize: 13, fontStyle: 'italic')}">'
      ' '
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 0, left: 78, width: 13*5, fontSize: 13, fontStyle: 'italic')}">'
      'world'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: !isBlink,
    );

    // Should break "Hello world" into 2 lines: "Hello " and "world".
    paragraph.layout(const ParagraphConstraints(width: 75.0));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: 0, left: 0, width: 13*5, fontSize: 13, fontWeight: 'bold')}">'
      'Hello'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 0, left: 65, width: 0, fontSize: 13, fontStyle: 'italic')}">'
      ' '
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 13, left: 0, width: 13*5, fontSize: 13, fontStyle: 'italic')}">'
      'world'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: !isBlink,
    );

    final ParagraphSpan hello = paragraph.spans.first;
    expect(getSpanText(paragraph, hello), 'Hello');
    expect(
      hello.style,
      styleWithDefaults(
        fontSize: 13.0,
        fontWeight: FontWeight.bold,
      ),
    );

    final ParagraphSpan world = paragraph.spans.last;
    expect(getSpanText(paragraph, world), ' world');
    expect(
      world.style,
      styleWithDefaults(
        fontSize: 13.0,
        fontStyle: FontStyle.italic,
      ),
    );
  });

  test('Builds a multi-span paragraph with complex styles', () {
    final EngineParagraphStyle style = EngineParagraphStyle(fontSize: 13.0);
    final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);

    builder.pushStyle(TextStyle(fontWeight: FontWeight.bold));
    builder.pushStyle(TextStyle(height: 2.0));
    builder.addText('Hello');
    builder.pop(); // pop TextStyle(height: 2.0).
    builder.pushStyle(TextStyle(fontStyle: FontStyle.italic));
    builder.addText(' world');
    builder.pushStyle(TextStyle(fontWeight: FontWeight.normal));
    builder.addText('!');

    final CanvasParagraph paragraph = builder.build();
    expect(paragraph.plainText, 'Hello world!');
    expect(paragraph.spans, hasLength(3));

    paragraph.layout(const ParagraphConstraints(width: double.infinity));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: 0, left: 0, width: 13*5, lineHeight: 2*13, fontSize: 13, fontWeight: 'bold')}">'
      'Hello'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 6, left: 65, width: 13*1, fontSize: 13, fontWeight: 'bold', fontStyle: 'italic')}">'
      ' '
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 6, left: 78, width: 13*5, fontSize: 13, fontWeight: 'bold', fontStyle: 'italic')}">'
      'world'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 6, left: 143, width: 13*1, fontSize: 13, fontWeight: 'normal', fontStyle: 'italic')}">'
      '!'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: !isBlink,
    );

    final ParagraphSpan hello = paragraph.spans[0];
    expect(getSpanText(paragraph, hello), 'Hello');
    expect(
      hello.style,
      styleWithDefaults(
        fontSize: 13.0,
        fontWeight: FontWeight.bold,
        height: 2.0,
      ),
    );

    final ParagraphSpan world = paragraph.spans[1];
    expect(getSpanText(paragraph, world), ' world');
    expect(
      world.style,
      styleWithDefaults(
        fontSize: 13.0,
        fontWeight: FontWeight.bold,
        fontStyle: FontStyle.italic,
      ),
    );

    final ParagraphSpan bang = paragraph.spans[2];
    expect(getSpanText(paragraph, bang), '!');
    expect(
      bang.style,
      styleWithDefaults(
        fontSize: 13.0,
        fontWeight: FontWeight.normal,
        fontStyle: FontStyle.italic,
      ),
    );
  });

  test('Paragraph with new lines generates correct DOM', () {
    final EngineParagraphStyle style = EngineParagraphStyle(fontSize: 13.0);
    final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);

    builder.addText('First\nSecond ');
    builder.pushStyle(TextStyle(fontStyle: FontStyle.italic));
    builder.addText('ThirdLongLine');

    final CanvasParagraph paragraph = builder.build();
    expect(paragraph.plainText, 'First\nSecond ThirdLongLine');
    expect(paragraph.spans, hasLength(2));

    // There's a new line between "First" and "Second", but "Second" and
    // "ThirdLongLine" remain together since constraints are infinite.
    paragraph.layout(const ParagraphConstraints(width: double.infinity));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: 0, left: 0, width: 13*5, fontSize: 13)}">'
      'First'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 13, left: 0, width: 13*6, fontSize: 13)}">'
      'Second'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 13, left: 13*6, width: 13*1, fontSize: 13)}">'
      ' '
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 13, left: 13*7, width: 13*13, fontSize: 13, fontStyle: 'italic')}">'
      'ThirdLongLine'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: !isBlink,
    );

    // Should break the paragraph into "First", "Second " and "ThirdLongLine".
    paragraph.layout(const ParagraphConstraints(width: 180.0));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: 0, left: 0, width: 13*5, fontSize: 13)}">'
      'First'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 13, left: 0, width: 13*6, fontSize: 13)}">'
      'Second'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 13, left: 13*6, width: 0, fontSize: 13)}">'
      ' '
      '</flt-span>'
      '<flt-span style="${spanStyle(top: 26, left: 0, width: 13*13, fontSize: 13, fontStyle: 'italic')}">'
      'ThirdLongLine'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: !isBlink,
    );
  });

  test('various font sizes', () {
    // Paragraphs and spans force the FlutterTest font in test mode. We need to
    // trick them into thinking they are not in test mode, so they use the
    // provided font family.
    debugEmulateFlutterTesterEnvironment = false;
    final EngineParagraphStyle style = EngineParagraphStyle(fontSize: 12.0, fontFamily: 'first');
    final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);

    builder.addText('First ');
    builder.pushStyle(TextStyle(fontSize: 18.0, fontFamily: 'second'));
    builder.addText('Second ');
    builder.pushStyle(TextStyle(fontSize: 10.0, fontFamily: 'third'));
    builder.addText('Third');

    final CanvasParagraph paragraph = builder.build();
    expect(paragraph.plainText, 'First Second Third');
    expect(paragraph.spans, hasLength(3));

    // The paragraph should take the font size and family from the span with the
    // greatest font size.
    paragraph.layout(const ParagraphConstraints(width: double.infinity));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span style="${spanStyle(top: null, left: null, width: null, fontSize: 12, fontFamily: 'first')}">'
      'First'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: null, left: null, width: null, fontSize: 12, fontFamily: 'first')}">'
      ' '
      '</flt-span>'
      '<flt-span style="${spanStyle(top: null, left: null, width: null, fontSize: 18, fontFamily: 'second')}">'
      'Second'
      '</flt-span>'
      '<flt-span style="${spanStyle(top: null, left: null, width: null, fontSize: 18, fontFamily: 'second')}">'
      ' '
      '</flt-span>'
      '<flt-span style="${spanStyle(top: null, left: null, width: null, fontSize: 10, fontFamily: 'third')}">'
      'Third'
      '</flt-span>'
      '</flt-paragraph>',
      // Since we are using unknown font families, we can't predict the text
      // measurements.
      ignorePositions: true,
    );
    debugEmulateFlutterTesterEnvironment = true;
  });

  // Regression test for https://github.com/flutter/flutter/issues/108431.
  // Set dir attribute for RTL fragments in order to let the browser
  // handle mirrored characters.
  test('Sets "dir" attribute for RTL fragment', () {
    final EngineParagraphStyle style = EngineParagraphStyle(
      fontSize: 20.0,
      textDirection: TextDirection.rtl,
    );
    final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);

    builder.addText('(1)');

    final CanvasParagraph paragraph = builder.build();
    expect(paragraph.paragraphStyle, style);
    expect(paragraph.plainText, '(1)');

    paragraph.layout(const ParagraphConstraints(width: double.infinity));
    expectOuterHtml(
      paragraph,
      '<flt-paragraph style="${paragraphStyle()}">'
      '<flt-span dir="rtl" style="${spanStyle(top: null, left: null, width: null, fontSize: 20)}">'
      '('
      '</flt-span>'
      '<flt-span style="${spanStyle(top: null, left: null, width: null, fontSize: 20)}">'
      '1'
      '</flt-span>'
      '<flt-span dir="rtl" style="${spanStyle(top: null, left: null, width: null, fontSize: 20)}">'
      ')'
      '</flt-span>'
      '</flt-paragraph>',
      ignorePositions: true,
    );
  });
}

const String defaultFontFamily = 'FlutterTest';
const num defaultFontSize = 14;

String paragraphStyle() {
  return <String>[
    'position: absolute;',
    'white-space: pre;',
  ].join(' ');
}

String spanStyle({
  required num? top,
  required num? left,
  required num? width,
  String fontFamily = defaultFontFamily,
  num fontSize = defaultFontSize,
  String? fontWeight,
  String? fontStyle,
  num? lineHeight,
  num? letterSpacing,
}) {
  return <String>[
    'font-size: ${fontSize}px;',
    if (fontWeight != null) 'font-weight: $fontWeight;',
    if (fontStyle != null) 'font-style: $fontStyle;',
    'font-family: ${fontFamilyToAttribute(fontFamily)};',
    if (letterSpacing != null) 'letter-spacing: ${letterSpacing}px;',
    'position: absolute;',
    if (top != null) 'top: ${top}px;',
    if (left != null) 'left: ${left}px;',
    if (width != null) 'width: ${width}px;',
    'line-height: ${lineHeight ?? fontSize}px;',
  ].join(' ');
}

TextStyle styleWithDefaults({
  String fontFamily = FlutterViewEmbedder.defaultFontFamily,
  double fontSize = FlutterViewEmbedder.defaultFontSize,
  FontWeight? fontWeight,
  FontStyle? fontStyle,
  double? height,
  double? letterSpacing,
}) {
  return TextStyle(
    fontFamily: fontFamily,
    fontSize: fontSize,
    fontWeight: fontWeight,
    fontStyle: fontStyle,
    height: height,
    letterSpacing: letterSpacing,
  );
}

void expectOuterHtml(CanvasParagraph paragraph, String expected, {required bool ignorePositions}) {
  String outerHtml = paragraph.toDomElement().outerHTML!;
  if (ignorePositions) {
    outerHtml = removeMeasurementInfo(outerHtml);
    expected = removeMeasurementInfo(expected);
  }

  expect(outerHtml, expected);
}

/// Removes CSS styles that are based on text measurement from the given html
/// string.
///
/// Examples: top, left, line-height, width.
///
/// This is needed when the measurement is unknown or could be different
/// depending on browser and environment.
String removeMeasurementInfo(String outerHtml) {
  return outerHtml
      .replaceAll(RegExp(r'\s*line-height:\s*[\d\.]+px\s*;\s*'), '')
      .replaceAll(RegExp(r'\s*width:\s*[\d\.]+px\s*;\s*'), '')
      .replaceAll(RegExp(r'\s*top:\s*[\d\.]+px\s*;\s*'), '')
      .replaceAll(RegExp(r'\s*left:\s*[\d\.]+px\s*;\s*'), '');
}
