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

final EngineTextStyle defaultStyle = EngineTextStyle.only(
  color: const Color(0xFFFF0000),
  fontFamily: FlutterViewEmbedder.defaultFontFamily,
  fontSize: FlutterViewEmbedder.defaultFontSize,
);
final EngineTextStyle style1 = defaultStyle.copyWith(fontSize: 20);
final EngineTextStyle style2 = defaultStyle.copyWith(color: blue);
final EngineTextStyle style3 = defaultStyle.copyWith(fontFamily: 'Roboto');

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

Future<void> testMain() async {
  group('$LayoutFragmenter', () {
    test('empty paragraph', () {
      final CanvasParagraph paragraph1 = rich(
        EngineParagraphStyle(),
        (CanvasParagraphBuilder builder) {},
      );
      expect(split(paragraph1), <_Fragment>[
        _Fragment('', endOfText, null, ffPrevious, defaultStyle),
      ]);

      final CanvasParagraph paragraph2 = rich(
        EngineParagraphStyle(),
        (CanvasParagraphBuilder builder) {
          builder.addText('');
        },
      );
      expect(split(paragraph2), <_Fragment>[
        _Fragment('', endOfText, null, ffPrevious, defaultStyle),
      ]);

      final CanvasParagraph paragraph3 = rich(
        EngineParagraphStyle(),
        (CanvasParagraphBuilder builder) {
          builder.pushStyle(style1);
          builder.addText('');
        },
      );
      expect(split(paragraph3), <_Fragment>[
        _Fragment('', endOfText, null, ffPrevious, style1),
      ]);
    });

    test('single span', () {
      final CanvasParagraph paragraph =
          plain(EngineParagraphStyle(), 'Lorem 12 $rtlWord1   ipsum34');
      expect(split(paragraph), <_Fragment>[
        _Fragment('Lorem', prohibited, ltr, ffLtr, defaultStyle),
        _Fragment(' ', opportunity, null, ffSandwich, defaultStyle, sp: 1),
        _Fragment('12', prohibited, ltr, ffPrevious, defaultStyle),
        _Fragment(' ', opportunity, null, ffSandwich, defaultStyle, sp: 1),
        _Fragment(rtlWord1, prohibited, rtl, ffRtl, defaultStyle),
        _Fragment('   ', opportunity, null, ffSandwich, defaultStyle, sp: 3),
        _Fragment('ipsum34', endOfText, ltr, ffLtr, defaultStyle),
      ]);
    });

    test('multi span', () {
      final CanvasParagraph paragraph = rich(
        EngineParagraphStyle(),
        (CanvasParagraphBuilder builder) {
          builder.pushStyle(style1);
          builder.addText('Lorem');
          builder.pop();
          builder.pushStyle(style2);
          builder.addText(' ipsum 12 ');
          builder.pop();
          builder.pushStyle(style3);
          builder.addText(' $rtlWord1 foo.');
          builder.pop();
        },
      );

      expect(split(paragraph), <_Fragment>[
        _Fragment('Lorem', prohibited, ltr, ffLtr, style1),
        _Fragment(' ', opportunity, null, ffSandwich, style2, sp: 1),
        _Fragment('ipsum', prohibited, ltr, ffLtr, style2),
        _Fragment(' ', opportunity, null, ffSandwich, style2, sp: 1),
        _Fragment('12', prohibited, ltr, ffPrevious, style2),
        _Fragment(' ', prohibited, null, ffSandwich, style2, sp: 1),
        _Fragment(' ', opportunity, null, ffSandwich, style3, sp: 1),
        _Fragment(rtlWord1, prohibited, rtl, ffRtl, style3),
        _Fragment(' ', opportunity, null, ffSandwich, style3, sp: 1),
        _Fragment('foo', prohibited, ltr, ffLtr, style3),
        _Fragment('.', endOfText, null, ffSandwich, style3),
      ]);
    });

    test('new lines', () {
      final CanvasParagraph paragraph = rich(
        EngineParagraphStyle(),
        (CanvasParagraphBuilder builder) {
          builder.pushStyle(style1);
          builder.addText('Lor\nem \n');
          builder.pop();
          builder.pushStyle(style2);
          builder.addText(' \n  ipsum 12 ');
          builder.pop();
          builder.pushStyle(style3);
          builder.addText(' $rtlWord1 fo');
          builder.pop();
          builder.pushStyle(style1);
          builder.addText('o.');
          builder.pop();
        },
      );

      expect(split(paragraph), <_Fragment>[
        _Fragment('Lor', prohibited, ltr, ffLtr, style1),
        _Fragment('\n', mandatory, null, ffSandwich, style1, nl: 1, sp: 1),
        _Fragment('em', prohibited, ltr, ffLtr, style1),
        _Fragment(' \n', mandatory, null, ffSandwich, style1, nl: 1, sp: 2),
        _Fragment(' \n', mandatory, null, ffSandwich, style2, nl: 1, sp: 2),
        _Fragment('  ', opportunity, null, ffSandwich, style2, sp: 2),
        _Fragment('ipsum', prohibited, ltr, ffLtr, style2),
        _Fragment(' ', opportunity, null, ffSandwich, style2, sp: 1),
        _Fragment('12', prohibited, ltr, ffPrevious, style2),
        _Fragment(' ', prohibited, null, ffSandwich, style2, sp: 1),
        _Fragment(' ', opportunity, null, ffSandwich, style3, sp: 1),
        _Fragment(rtlWord1, prohibited, rtl, ffRtl, style3),
        _Fragment(' ', opportunity, null, ffSandwich, style3, sp: 1),
        _Fragment('fo', prohibited, ltr, ffLtr, style3),
        _Fragment('o', prohibited, ltr, ffLtr, style1),
        _Fragment('.', endOfText, null, ffSandwich, style1),
      ]);
    });

    test('last line is empty', () {
      final CanvasParagraph paragraph = rich(
        EngineParagraphStyle(),
        (CanvasParagraphBuilder builder) {
          builder.pushStyle(style1);
          builder.addText('Lorem \n');
          builder.pop();
          builder.pushStyle(style2);
          builder.addText(' \n  ipsum \n');
          builder.pop();
        },
      );

      expect(split(paragraph), <_Fragment>[
        _Fragment('Lorem', prohibited, ltr, ffLtr, style1),
        _Fragment(' \n', mandatory, null, ffSandwich, style1, nl: 1, sp: 2),
        _Fragment(' \n', mandatory, null, ffSandwich, style2, nl: 1, sp: 2),
        _Fragment('  ', opportunity, null, ffSandwich, style2, sp: 2),
        _Fragment('ipsum', prohibited, ltr, ffLtr, style2),
        _Fragment(' \n', mandatory, null, ffSandwich, style2, nl: 1, sp: 2),
        _Fragment('', endOfText, null, ffSandwich, style2),
      ]);
    });

    test('space-only spans', () {
      final CanvasParagraph paragraph = rich(
        EngineParagraphStyle(),
        (CanvasParagraphBuilder builder) {
          builder.addText('Lorem ');
          builder.pushStyle(style1);
          builder.addText('   ');
          builder.pop();
          builder.pushStyle(style2);
          builder.addText('  ');
          builder.pop();
          builder.addText('ipsum');
        },
      );

      expect(split(paragraph), <_Fragment>[
        _Fragment('Lorem', prohibited, ltr, ffLtr, defaultStyle),
        _Fragment(' ', prohibited, null, ffSandwich, defaultStyle, sp: 1),
        _Fragment('   ', prohibited, null, ffSandwich, style1, sp: 3),
        _Fragment('  ', opportunity, null, ffSandwich, style2, sp: 2),
        _Fragment('ipsum', endOfText, ltr, ffLtr, defaultStyle),
      ]);
    });

    test('placeholders', () {
      final CanvasParagraph paragraph = rich(
        EngineParagraphStyle(),
        (CanvasParagraphBuilder builder) {
          builder.pushStyle(style1);
          builder.addPlaceholder(100, 100, PlaceholderAlignment.top);
          builder.addText('Lorem');
          builder.addPlaceholder(100, 100, PlaceholderAlignment.top);
          builder.addText('ipsum\n');
          builder.addPlaceholder(100, 100, PlaceholderAlignment.top);
          builder.pop();
          builder.pushStyle(style2);
          builder.addText('$rtlWord1 ');
          builder.addPlaceholder(100, 100, PlaceholderAlignment.top);
          builder.addText('\nsit');
          builder.pop();
          builder.addPlaceholder(100, 100, PlaceholderAlignment.top);
        },
      );

      final String placeholderChar = String.fromCharCode(0xFFFC);

      expect(split(paragraph), <_Fragment>[
        _Fragment(placeholderChar, opportunity, ltr, ffLtr, null),
        _Fragment('Lorem', opportunity, ltr, ffLtr, style1),
        _Fragment(placeholderChar, opportunity, ltr, ffLtr, null),
        _Fragment('ipsum', prohibited, ltr, ffLtr, style1),
        _Fragment('\n', mandatory, null, ffSandwich, style1, nl: 1, sp: 1),
        _Fragment(placeholderChar, opportunity, ltr, ffLtr, null),
        _Fragment(rtlWord1, prohibited, rtl, ffRtl, style2),
        _Fragment(' ', opportunity, null, ffSandwich, style2, sp: 1),
        _Fragment(placeholderChar, prohibited, ltr, ffLtr, null),
        _Fragment('\n', mandatory, null, ffSandwich, style2, nl: 1, sp: 1),
        _Fragment('sit', opportunity, ltr, ffLtr, style2),
        _Fragment(placeholderChar, endOfText, ltr, ffLtr, null),
      ]);
    });
  });
}

/// Holds information about how a fragment.
class _Fragment {
  _Fragment(this.text, this.type, this.textDirection, this.fragmentFlow, this.style, {
    this.nl = 0,
    this.sp = 0,
  });

  factory _Fragment._fromLayoutFragment(String text, LayoutFragment layoutFragment) {
    final ParagraphSpan span = layoutFragment.span;
    return _Fragment(
      text.substring(layoutFragment.start, layoutFragment.end),
      layoutFragment.type,
      layoutFragment.textDirection,
      layoutFragment.fragmentFlow,
      span is FlatTextSpan ? span.style : null,
      nl: layoutFragment.trailingNewlines,
      sp: layoutFragment.trailingSpaces,
    );
  }

  final String text;
  final LineBreakType type;
  final TextDirection? textDirection;
  final FragmentFlow fragmentFlow;
  final EngineTextStyle? style;

  /// The number of trailing new line characters.
  final int nl;

  /// The number of trailing spaces.
  final int sp;

  @override
  int get hashCode => Object.hash(text, type, textDirection, fragmentFlow, style, nl, sp);

  @override
  bool operator ==(Object other) {
    return other is _Fragment &&
        other.text == text &&
        other.type == type &&
        other.textDirection == textDirection &&
        other.fragmentFlow == fragmentFlow &&
        other.style == style &&
        other.nl == nl &&
        other.sp == sp;
  }

  @override
  String toString() {
    return '"$text" ($type, $textDirection, $fragmentFlow, nl: $nl, sp: $sp)';
  }
}

List<_Fragment> split(CanvasParagraph paragraph) {
  return <_Fragment>[
    for (final LayoutFragment layoutFragment
        in computeLayoutFragments(paragraph))
      _Fragment._fromLayoutFragment(paragraph.plainText, layoutFragment)
  ];
}

List<LayoutFragment> computeLayoutFragments(CanvasParagraph paragraph) {
  return LayoutFragmenter(paragraph.plainText, paragraph.spans).fragment();
}
