// Copyright 2014 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:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';


class _ConsistentTextRangeImplementationMatcher extends Matcher {
  _ConsistentTextRangeImplementationMatcher(int length)
    : range = TextRange(start: -1, end: length + 1),
      assert(length >= 0);

  final TextRange range;
  @override
  Description describe(Description description) {
    return description.add('The implementation of TextBoundary.getTextBoundaryAt is consistent with its other methods.');
  }

  @override
  Description describeMismatch(dynamic item, Description mismatchDescription, Map<dynamic, dynamic> matchState, bool verbose) {
    final TextBoundary boundary = matchState['textBoundary'] as TextBoundary;
    final int position = matchState['position'] as int;
    final int leading = boundary.getLeadingTextBoundaryAt(position) ?? -1;
    final int trailing = boundary.getTrailingTextBoundaryAt(position) ?? -1;

    return mismatchDescription.add(
      'at position $position, expected ${TextRange(start: leading, end: trailing)} but got ${boundary.getTextBoundaryAt(position)}',
    );
  }

  @override
  bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
    for (int i = range.start; i <= range.end; i++) {
      final int? leading = (item as TextBoundary).getLeadingTextBoundaryAt(i);
      final int? trailing = item.getTrailingTextBoundaryAt(i);
      final TextRange boundary = item.getTextBoundaryAt(i);
      final bool consistent = boundary.start == (leading ?? -1) && boundary.end == (trailing ?? -1);
      if (!consistent) {
        matchState['textBoundary'] = item;
        matchState['position'] = i;
        return false;
      }
    }
    return true;
  }
}

Matcher _hasConsistentTextRangeImplementationWithinRange(int length) => _ConsistentTextRangeImplementationMatcher(length);

void main() {
  test('Character boundary works', () {
    const CharacterBoundary boundary = CharacterBoundary('abc');
    expect(boundary, _hasConsistentTextRangeImplementationWithinRange(3));

    expect(boundary.getLeadingTextBoundaryAt(-1), null);
    expect(boundary.getTrailingTextBoundaryAt(-1), 0);

    expect(boundary.getLeadingTextBoundaryAt(0), 0);
    expect(boundary.getTrailingTextBoundaryAt(0), 1);

    expect(boundary.getLeadingTextBoundaryAt(1), 1);
    expect(boundary.getTrailingTextBoundaryAt(1), 2);

    expect(boundary.getLeadingTextBoundaryAt(2), 2);
    expect(boundary.getTrailingTextBoundaryAt(2), 3);

    expect(boundary.getLeadingTextBoundaryAt(3), 3);
    expect(boundary.getTrailingTextBoundaryAt(3), null);

    expect(boundary.getLeadingTextBoundaryAt(4), 3);
    expect(boundary.getTrailingTextBoundaryAt(4), null);
  });

  test('Character boundary works with grapheme', () {
    const String text = 'a❄︎c';
    const CharacterBoundary boundary = CharacterBoundary(text);
    expect(boundary, _hasConsistentTextRangeImplementationWithinRange(text.length));

    expect(boundary.getLeadingTextBoundaryAt(-1), null);
    expect(boundary.getTrailingTextBoundaryAt(-1), 0);

    expect(boundary.getLeadingTextBoundaryAt(0), 0);
    expect(boundary.getTrailingTextBoundaryAt(0), 1);

    // The `❄` takes two character length.
    expect(boundary.getLeadingTextBoundaryAt(1), 1);
    expect(boundary.getTrailingTextBoundaryAt(1), 3);

    expect(boundary.getLeadingTextBoundaryAt(2), 1);
    expect(boundary.getTrailingTextBoundaryAt(2), 3);

    expect(boundary.getLeadingTextBoundaryAt(3), 3);
    expect(boundary.getTrailingTextBoundaryAt(3), 4);

    expect(boundary.getLeadingTextBoundaryAt(text.length), text.length);
    expect(boundary.getTrailingTextBoundaryAt(text.length), null);
  });

  test('wordBoundary.moveByWordBoundary', () {
    const String text = 'ABC   ABC\n'       // [0, 10)
                        'AÁ    Á\n'         // [10, 20)
                        '         \n'       // [20, 30)
                        'ABC!!!ABC\n'       // [30, 40)
                        '  !ABC !!\n'       // [40, 50)
                        'A  𑗋𑗋 A\n';     // [50, 60)

    final TextPainter textPainter = TextPainter()
      ..textDirection = TextDirection.ltr
      ..text = const TextSpan(text: text)
      ..layout();

    final TextBoundary boundary = textPainter.wordBoundaries.moveByWordBoundary;

    // 4 points to the 2nd whitespace in the first line.
    // Don't break between horizontal spaces and letters/numbers.
    expect(boundary.getLeadingTextBoundaryAt(4), 0);
    expect(boundary.getTrailingTextBoundaryAt(4), 9);

    // Works when words are starting/ending with a combining diacritical mark.
    expect(boundary.getLeadingTextBoundaryAt(14), 10);
    expect(boundary.getTrailingTextBoundaryAt(14), 19);

    // Do break before and after newlines.
    expect(boundary.getLeadingTextBoundaryAt(24), 20);
    expect(boundary.getTrailingTextBoundaryAt(24), 29);

    // Do not break on punctuations.
    expect(boundary.getLeadingTextBoundaryAt(34), 30);
    expect(boundary.getTrailingTextBoundaryAt(34), 39);

    // Ok to break if next to punctuations or separating spaces.
    expect(boundary.getLeadingTextBoundaryAt(44), 43);
    expect(boundary.getTrailingTextBoundaryAt(44), 46);

    // 44 points to a low surrogate of a punctuation.
    expect(boundary.getLeadingTextBoundaryAt(54), 50);
    expect(boundary.getTrailingTextBoundaryAt(54), 59);
  });

  test('line boundary works', () {
    final LineBoundary boundary = LineBoundary(TestTextLayoutMetrics());
    expect(boundary.getLeadingTextBoundaryAt(3), TestTextLayoutMetrics.lineAt3.start);
    expect(boundary.getTrailingTextBoundaryAt(3), TestTextLayoutMetrics.lineAt3.end);
    expect(boundary.getTextBoundaryAt(3), TestTextLayoutMetrics.lineAt3);
  });

  group('paragraph boundary', () {
    test('works for simple cases', () {
      const String textA= 'abcd efg hi\njklmno\npqrstuv';
      const ParagraphBoundary boundaryA = ParagraphBoundary(textA);

      // Position enclosed inside of paragraph, 'abcd efg h|i\n'.
      const int position = 10;

      // The range includes the line terminator.
      expect(boundaryA.getLeadingTextBoundaryAt(position), 0);
      expect(boundaryA.getTrailingTextBoundaryAt(position), 12);

      // This text includes a carriage return followed by a line feed.
      const String textB = 'abcd efg hi\r\njklmno\npqrstuv';
      const ParagraphBoundary boundaryB = ParagraphBoundary(textB);
      expect(boundaryB.getLeadingTextBoundaryAt(position), 0);
      expect(boundaryB.getTrailingTextBoundaryAt(position), 13);

      const String textF = 'Now is the time for\n' // 20
          'all good people\n'                         // 20 + 16 => 36
          'to come to the aid\n'                      // 36 + 19 => 55
          'of their country.';                        // 55 + 17 => 72
      const ParagraphBoundary boundaryF = ParagraphBoundary(textF);
      const int positionF = 11;
      expect(boundaryF.getLeadingTextBoundaryAt(positionF), 0);
      expect(boundaryF.getTrailingTextBoundaryAt(positionF), 20);
    });

    test('works for consecutive line terminators involving CRLF', () {
      const String textI = 'Now is the time for\n' // 20
          'all good people\n\r\n'                         // 20 + 16 => 38
          'to come to the aid\n'                      // 38 + 19 => 57
          'of their country.';                        // 57 + 17 => 74
      const ParagraphBoundary boundaryI = ParagraphBoundary(textI);
      const int positionI = 56;// \n at the end of the third line.
      const int positionJ = 38;// t at beginning of third line.
      const int positionK = 37;// \n at end of second line.
      expect(boundaryI.getLeadingTextBoundaryAt(positionI), 38);
      expect(boundaryI.getTrailingTextBoundaryAt(positionI), 57);
      expect(boundaryI.getLeadingTextBoundaryAt(positionJ), 38);
      expect(boundaryI.getTrailingTextBoundaryAt(positionJ), 57);
      expect(boundaryI.getLeadingTextBoundaryAt(positionK), 36);
      expect(boundaryI.getTrailingTextBoundaryAt(positionK), 38);
    });

    test('works for consecutive line terminators', () {
      const String textI = 'Now is the time for\n' // 20
          'all good people\n\n'                         // 20 + 16 => 37
          'to come to the aid\n'                      // 37 + 19 => 56
          'of their country.';                        // 56 + 17 => 73
      const ParagraphBoundary boundaryI = ParagraphBoundary(textI);
      const int positionI = 55;// \n at the end of the third line.
      const int positionJ = 37;// t at beginning of third line.
      const int positionK = 36;// \n at end of second line.
      expect(boundaryI.getLeadingTextBoundaryAt(positionI), 37);
      expect(boundaryI.getTrailingTextBoundaryAt(positionI), 56);
      expect(boundaryI.getLeadingTextBoundaryAt(positionJ), 37);
      expect(boundaryI.getTrailingTextBoundaryAt(positionJ), 56);
      expect(boundaryI.getLeadingTextBoundaryAt(positionK), 36);
      expect(boundaryI.getTrailingTextBoundaryAt(positionK), 37);
    });

    test('leading boundary works for consecutive CRLF', () {
      // This text includes multiple consecutive carriage returns followed by line feeds (CRLF).
      const String textH = 'abcd efg hi\r\n\r\n\r\n\r\n\r\n\r\n\r\n\n\n\n\n\njklmno\npqrstuv';
      const ParagraphBoundary boundaryH = ParagraphBoundary(textH);
      const int positionH = 18;
      expect(boundaryH.getLeadingTextBoundaryAt(positionH), 17);
      expect(boundaryH.getTrailingTextBoundaryAt(positionH), 19);
    });

    test('trailing boundary works for consecutive CRLF', () {
      // This text includes multiple consecutive carriage returns followed by line feeds (CRLF).
      const String textG = 'abcd efg hi\r\n\n\n\n\n\n\r\n\r\n\r\n\r\n\n\n\n\n\njklmno\npqrstuv';
      const ParagraphBoundary boundaryG = ParagraphBoundary(textG);
      const int positionG = 18;
      expect(boundaryG.getLeadingTextBoundaryAt(positionG), 18);
      expect(boundaryG.getTrailingTextBoundaryAt(positionG), 20);
    });

    test('works when position is between two CRLF', () {
      const String textE = 'abcd efg hi\r\nhello\r\n\n';
      const ParagraphBoundary boundaryE = ParagraphBoundary(textE);
      // Position enclosed inside of paragraph, 'abcd efg hi\r\nhello\r\n\n'.
      const int positionE = 16;
      expect(boundaryE.getLeadingTextBoundaryAt(positionE), 13);
      expect(boundaryE.getTrailingTextBoundaryAt(positionE), 20);
    });

    test('works for multiple consecutive line terminators', () {
      // This text includes multiple consecutive line terminators.
      const String textC = 'abcd efg hi\r\n\n\n\n\n\n\n\n\n\n\n\njklmno\npqrstuv';
      const ParagraphBoundary boundaryC = ParagraphBoundary(textC);
      // Position enclosed inside of paragraph, 'abcd efg hi\r\n\n\n\n\n\n|\n\n\n\n\n\njklmno\npqrstuv'.
      const int positionC = 18;
      expect(boundaryC.getLeadingTextBoundaryAt(positionC), 18);
      expect(boundaryC.getTrailingTextBoundaryAt(positionC), 19);

      const String textD = 'abcd efg hi\r\n\n\n\n';
      const ParagraphBoundary boundaryD = ParagraphBoundary(textD);
      // Position enclosed inside of paragraph, 'abcd efg hi\r\n\n|\n\n'.
      const int positionD = 14;
      expect(boundaryD.getLeadingTextBoundaryAt(positionD), 14);
      expect(boundaryD.getTrailingTextBoundaryAt(positionD), 15);
    });
  });

  test('document boundary works', () {
    const String text = 'abcd efg hi\njklmno\npqrstuv';
    const DocumentBoundary boundary = DocumentBoundary(text);
    expect(boundary, _hasConsistentTextRangeImplementationWithinRange(text.length));

    expect(boundary.getLeadingTextBoundaryAt(-1), null);
    expect(boundary.getTrailingTextBoundaryAt(-1), text.length);

    expect(boundary.getLeadingTextBoundaryAt(0), 0);
    expect(boundary.getTrailingTextBoundaryAt(0), text.length);

    expect(boundary.getLeadingTextBoundaryAt(10), 0);
    expect(boundary.getTrailingTextBoundaryAt(10), text.length);

    expect(boundary.getLeadingTextBoundaryAt(text.length), 0);
    expect(boundary.getTrailingTextBoundaryAt(text.length), null);

    expect(boundary.getLeadingTextBoundaryAt(text.length + 1), 0);
    expect(boundary.getTrailingTextBoundaryAt(text.length + 1), null);
  });
}

class TestTextLayoutMetrics extends TextLayoutMetrics {
  static const TextSelection lineAt3 = TextSelection(baseOffset: 0, extentOffset: 10);
  static const TextRange wordBoundaryAt3 = TextRange(start: 4, end: 7);

  @override
  TextSelection getLineAtOffset(TextPosition position) {
    if (position.offset == 3) {
      return lineAt3;
    }
    throw UnimplementedError();
  }

  @override
  TextPosition getTextPositionAbove(TextPosition position) {
    throw UnimplementedError();
  }

  @override
  TextPosition getTextPositionBelow(TextPosition position) {
    throw UnimplementedError();
  }

  @override
  TextRange getWordBoundary(TextPosition position) {
    if (position.offset == 3) {
      return wordBoundaryAt3;
    }
    throw UnimplementedError();
  }
}
