// 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.

// @dart = 2.12
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';

import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart';

import 'line_breaker_test_helper.dart';
import 'line_breaker_test_raw_data.dart';

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

void testMain() {
  group('nextLineBreak', () {
    test('Does not go beyond the ends of a string', () {
      expect(split('foo'), <Line>[
        Line('foo', LineBreakType.endOfText),
      ]);

      final LineBreakResult result = nextLineBreak('foo', 'foo'.length);
      expect(result.index, 'foo'.length);
      expect(result.type, LineBreakType.endOfText);
    });

    test('whitespace', () {
      expect(split('foo bar'), <Line>[
        Line('foo ', LineBreakType.opportunity),
        Line('bar', LineBreakType.endOfText),
      ]);
      expect(split('  foo    bar  '), <Line>[
        Line('  ', LineBreakType.opportunity),
        Line('foo    ', LineBreakType.opportunity),
        Line('bar  ', LineBreakType.endOfText),
      ]);
    });

    test('single-letter lines', () {
      expect(split('foo a bar'), <Line>[
        Line('foo ', LineBreakType.opportunity),
        Line('a ', LineBreakType.opportunity),
        Line('bar', LineBreakType.endOfText),
      ]);
      expect(split('a b c'), <Line>[
        Line('a ', LineBreakType.opportunity),
        Line('b ', LineBreakType.opportunity),
        Line('c', LineBreakType.endOfText),
      ]);
      expect(split(' a b '), <Line>[
        Line(' ', LineBreakType.opportunity),
        Line('a ', LineBreakType.opportunity),
        Line('b ', LineBreakType.endOfText),
      ]);
    });

    test('new line characters', () {
      final String bk = String.fromCharCode(0x000B);
      // Can't have a line break between CR×LF.
      expect(split('foo\r\nbar'), <Line>[
        Line('foo\r\n', LineBreakType.mandatory),
        Line('bar', LineBreakType.endOfText),
      ]);

      // Any other new line is considered a line break on its own.

      expect(split('foo\n\nbar'), <Line>[
        Line('foo\n', LineBreakType.mandatory),
        Line('\n', LineBreakType.mandatory),
        Line('bar', LineBreakType.endOfText),
      ]);
      expect(split('foo\r\rbar'), <Line>[
        Line('foo\r', LineBreakType.mandatory),
        Line('\r', LineBreakType.mandatory),
        Line('bar', LineBreakType.endOfText),
      ]);
      expect(split('foo$bk${bk}bar'), <Line>[
        Line('foo$bk', LineBreakType.mandatory),
        Line(bk, LineBreakType.mandatory),
        Line('bar', LineBreakType.endOfText),
      ]);

      expect(split('foo\n\rbar'), <Line>[
        Line('foo\n', LineBreakType.mandatory),
        Line('\r', LineBreakType.mandatory),
        Line('bar', LineBreakType.endOfText),
      ]);
      expect(split('foo$bk\rbar'), <Line>[
        Line('foo$bk', LineBreakType.mandatory),
        Line('\r', LineBreakType.mandatory),
        Line('bar', LineBreakType.endOfText),
      ]);
      expect(split('foo\r${bk}bar'), <Line>[
        Line('foo\r', LineBreakType.mandatory),
        Line(bk, LineBreakType.mandatory),
        Line('bar', LineBreakType.endOfText),
      ]);
      expect(split('foo$bk\nbar'), <Line>[
        Line('foo$bk', LineBreakType.mandatory),
        Line('\n', LineBreakType.mandatory),
        Line('bar', LineBreakType.endOfText),
      ]);
      expect(split('foo\n${bk}bar'), <Line>[
        Line('foo\n', LineBreakType.mandatory),
        Line(bk, LineBreakType.mandatory),
        Line('bar', LineBreakType.endOfText),
      ]);

      // New lines at the beginning and end.

      expect(split('foo\n'), <Line>[
        Line('foo\n', LineBreakType.mandatory),
        Line('', LineBreakType.endOfText),
      ]);
      expect(split('foo\r'), <Line>[
        Line('foo\r', LineBreakType.mandatory),
        Line('', LineBreakType.endOfText),
      ]);
      expect(split('foo$bk'), <Line>[
        Line('foo$bk', LineBreakType.mandatory),
        Line('', LineBreakType.endOfText),
      ]);

      expect(split('\nfoo'), <Line>[
        Line('\n', LineBreakType.mandatory),
        Line('foo', LineBreakType.endOfText),
      ]);
      expect(split('\rfoo'), <Line>[
        Line('\r', LineBreakType.mandatory),
        Line('foo', LineBreakType.endOfText),
      ]);
      expect(split('${bk}foo'), <Line>[
        Line(bk, LineBreakType.mandatory),
        Line('foo', LineBreakType.endOfText),
      ]);

      // Whitespace with new lines.

      expect(split('foo  \n'), <Line>[
        Line('foo  \n', LineBreakType.mandatory),
        Line('', LineBreakType.endOfText),
      ]);

      expect(split('foo  \n   '), <Line>[
        Line('foo  \n', LineBreakType.mandatory),
        Line('   ', LineBreakType.endOfText),
      ]);

      expect(split('foo  \n   bar'), <Line>[
        Line('foo  \n', LineBreakType.mandatory),
        Line('   ', LineBreakType.opportunity),
        Line('bar', LineBreakType.endOfText),
      ]);

      expect(split('\n  foo'), <Line>[
        Line('\n', LineBreakType.mandatory),
        Line('  ', LineBreakType.opportunity),
        Line('foo', LineBreakType.endOfText),
      ]);
      expect(split('   \n  foo'), <Line>[
        Line('   \n', LineBreakType.mandatory),
        Line('  ', LineBreakType.opportunity),
        Line('foo', LineBreakType.endOfText),
      ]);
    });

    test('trailing spaces and new lines', () {
      expect(
        findBreaks('foo bar  '),
        <LineBreakResult>[
          LineBreakResult(4, 4, 3, LineBreakType.opportunity),
          LineBreakResult(9, 9, 7, LineBreakType.endOfText),
        ],
      );

      expect(
        findBreaks('foo  \nbar\nbaz   \n'),
        <LineBreakResult>[
          LineBreakResult(6, 5, 3, LineBreakType.mandatory),
          LineBreakResult(10, 9, 9, LineBreakType.mandatory),
          LineBreakResult(17, 16, 13, LineBreakType.mandatory),
          LineBreakResult(17, 17, 17, LineBreakType.endOfText),
        ],
      );
    });

    test('leading spaces', () {
      expect(
        findBreaks(' foo'),
        <LineBreakResult>[
          LineBreakResult(1, 1, 0, LineBreakType.opportunity),
          LineBreakResult(4, 4, 4, LineBreakType.endOfText),
        ],
      );

      expect(
        findBreaks('   foo'),
        <LineBreakResult>[
          LineBreakResult(3, 3, 0, LineBreakType.opportunity),
          LineBreakResult(6, 6, 6, LineBreakType.endOfText),
        ],
      );

      expect(
        findBreaks('  foo   bar'),
        <LineBreakResult>[
          LineBreakResult(2, 2, 0, LineBreakType.opportunity),
          LineBreakResult(8, 8, 5, LineBreakType.opportunity),
          LineBreakResult(11, 11, 11, LineBreakType.endOfText),
        ],
      );

      expect(
        findBreaks('  \n   foo'),
        <LineBreakResult>[
          LineBreakResult(3, 2, 0, LineBreakType.mandatory),
          LineBreakResult(6, 6, 3, LineBreakType.opportunity),
          LineBreakResult(9, 9, 9, LineBreakType.endOfText),
        ],
      );
    });

    test('comprehensive test', () {
      final List<TestCase> testCollection = parseRawTestData(rawLineBreakTestData);
      for (int t = 0; t < testCollection.length; t++) {
        final TestCase testCase = testCollection[t];
        final String text = testCase.toText();

        int lastLineBreak = 0;
        int surrogateCount = 0;
        // `s` is the index in the `testCase.signs` list.
        for (int s = 0; s < testCase.signs.length; s++) {
          // `i` is the index in the `text`.
          final int i = s + surrogateCount;
          if (s < testCase.chars.length && testCase.chars[s].isSurrogatePair) {
            surrogateCount++;
          }

          final Sign sign = testCase.signs[s];
          final LineBreakResult result = nextLineBreak(text, lastLineBreak);
          if (sign.isBreakOpportunity) {
            // The line break should've been found at index `i`.
            expect(
              result.index,
              i,
              reason: 'Failed at test case number $t:\n'
                  '${testCase.toString()}\n'
                  '"$text"\n'
                  '\nExpected line break at {$lastLineBreak - $i} but found line break at {$lastLineBreak - ${result.index}}.',
            );

            // Since this is a line break, passing a `maxEnd` that's greater
            // should return the same line break.
            final LineBreakResult maxEndResult =
                nextLineBreak(text, lastLineBreak, maxEnd: i + 1);
            expect(maxEndResult.index, i);
            expect(maxEndResult.type, isNot(LineBreakType.prohibited));

            lastLineBreak = i;
          } else {
            // This isn't a line break opportunity so the line break should be
            // somewhere after index `i`.
            expect(
              result.index,
              greaterThan(i),
              reason: 'Failed at test case number $t:\n'
                  '${testCase.toString()}\n'
                  '"$text"\n'
                  '\nUnexpected line break found at {$lastLineBreak - $i}.',
            );

            // Since this isn't a line break, passing it as a `maxEnd` should
            // return `maxEnd` as a prohibited line break type.
            final LineBreakResult maxEndResult =
                nextLineBreak(text, lastLineBreak, maxEnd: i);
            expect(maxEndResult.index, i);
            expect(maxEndResult.type, LineBreakType.prohibited);
          }
        }
      }
    });
  });
}

/// Holds information about how a line was split from a string.
class Line {
  Line(this.text, this.breakType);

  final String text;
  final LineBreakType breakType;

  @override
  int get hashCode => hashValues(text, breakType);

  @override
  bool operator ==(Object other) {
    return other is Line && other.text == text && other.breakType == breakType;
  }

  String get escapedText {
    final String bk = String.fromCharCode(0x000B);
    final String nl = String.fromCharCode(0x0085);
    return text
        .replaceAll('"', '\\"')
        .replaceAll('\n', '\\n')
        .replaceAll('\r', '\\r')
        .replaceAll(bk, '{BK}')
        .replaceAll(nl, '{NL}');
  }

  @override
  String toString() {
    return '"$escapedText" ($breakType)';
  }
}

List<Line> split(String text) {
  final List<Line> lines = <Line>[];

  int lastIndex = 0;
  for (LineBreakResult brk in findBreaks(text)) {
    lines.add(Line(text.substring(lastIndex, brk.index), brk.type));
    lastIndex = brk.index;
  }
  return lines;
}

List<LineBreakResult> findBreaks(String text) {
  final List<LineBreakResult> breaks = <LineBreakResult>[];

  LineBreakResult brk = nextLineBreak(text, 0);
  breaks.add(brk);
  while (brk.type != LineBreakType.endOfText) {
    brk = nextLineBreak(text, brk.index);
    breaks.add(brk);
  }
  return breaks;
}
