// 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/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  test('TextSpan equals', () {
    const TextSpan a1 = TextSpan(text: 'a');
    const TextSpan a2 = TextSpan(text: 'a');
    const TextSpan b1 = TextSpan(children: <TextSpan>[ a1 ]);
    const TextSpan b2 = TextSpan(children: <TextSpan>[ a2 ]);
    const TextSpan c1 = TextSpan();
    const TextSpan c2 = TextSpan();

    expect(a1 == a2, isTrue);
    expect(b1 == b2, isTrue);
    expect(c1 == c2, isTrue);

    expect(a1 == b2, isFalse);
    expect(b1 == c2, isFalse);
    expect(c1 == a2, isFalse);

    expect(a1 == c2, isFalse);
    expect(b1 == a2, isFalse);
    expect(c1 == b2, isFalse);

    void callback1(PointerEnterEvent _) {}
    void callback2(PointerEnterEvent _) {}

    final TextSpan d1 = TextSpan(text: 'a', onEnter: callback1);
    final TextSpan d2 = TextSpan(text: 'a', onEnter: callback1);
    final TextSpan d3 = TextSpan(text: 'a', onEnter: callback2);
    final TextSpan e1 = TextSpan(text: 'a', onEnter: callback2, mouseCursor: SystemMouseCursors.forbidden);
    final TextSpan e2 = TextSpan(text: 'a', onEnter: callback2, mouseCursor: SystemMouseCursors.forbidden);

    expect(a1 == d1, isFalse);
    expect(d1 == d2, isTrue);
    expect(d2 == d3, isFalse);
    expect(d3 == e1, isFalse);
    expect(e1 == e2, isTrue);
  });

  test('TextSpan toStringDeep', () {
    const TextSpan test = TextSpan(
      text: 'a',
      style: TextStyle(
        fontSize: 10.0,
      ),
      children: <TextSpan>[
        TextSpan(
          text: 'b',
          children: <TextSpan>[
            TextSpan(),
          ],
        ),
        TextSpan(
          text: 'c',
        ),
      ],
    );
    expect(test.toStringDeep(), equals(
      'TextSpan:\n'
      '  inherit: true\n'
      '  size: 10.0\n'
      '  "a"\n'
      '  TextSpan:\n'
      '    "b"\n'
      '    TextSpan:\n'
      '      (empty)\n'
      '  TextSpan:\n'
      '    "c"\n',
    ));
  });

  test('TextSpan toStringDeep for mouse', () {
    const TextSpan test1 = TextSpan(
      text: 'a',
    );
    expect(test1.toStringDeep(), equals(
      'TextSpan:\n'
      '  "a"\n',
    ));

    final TextSpan test2 = TextSpan(
      text: 'a',
      onEnter: (_) {},
      onExit: (_) {},
      mouseCursor: SystemMouseCursors.forbidden,
    );
    expect(test2.toStringDeep(), equals(
      'TextSpan:\n'
      '  "a"\n'
      '  callbacks: enter, exit\n'
      '  mouseCursor: SystemMouseCursor(forbidden)\n',
    ));
  });


  test('TextSpan toPlainText', () {
    const TextSpan textSpan = TextSpan(
      text: 'a',
      children: <TextSpan>[
        TextSpan(text: 'b'),
        TextSpan(text: 'c'),
      ],
    );
    expect(textSpan.toPlainText(), 'abc');
  });

  test('WidgetSpan toPlainText', () {
    const TextSpan textSpan = TextSpan(
      text: 'a',
      children: <InlineSpan>[
        TextSpan(text: 'b'),
        WidgetSpan(child: SizedBox(width: 10, height: 10)),
        TextSpan(text: 'c'),
      ],
    );
    expect(textSpan.toPlainText(), 'ab\uFFFCc');
  });

  test('TextSpan toPlainText with semanticsLabel', () {
    const TextSpan textSpan = TextSpan(
      text: 'a',
      children: <TextSpan>[
        TextSpan(text: 'b', semanticsLabel: 'foo'),
        TextSpan(text: 'c'),
      ],
    );
    expect(textSpan.toPlainText(), 'afooc');
    expect(textSpan.toPlainText(includeSemanticsLabels: false), 'abc');
  });

  test('TextSpan widget change test', () {
    const TextSpan textSpan1 = TextSpan(
      text: 'a',
      children: <InlineSpan>[
        TextSpan(text: 'b'),
        WidgetSpan(child: SizedBox(width: 10, height: 10)),
        TextSpan(text: 'c'),
      ],
    );

    const TextSpan textSpan2 = TextSpan(
      text: 'a',
      children: <InlineSpan>[
        TextSpan(text: 'b'),
        WidgetSpan(child: SizedBox(width: 10, height: 10)),
        TextSpan(text: 'c'),
      ],
    );

    const TextSpan textSpan3 = TextSpan(
      text: 'a',
      children: <InlineSpan>[
        TextSpan(text: 'b'),
        WidgetSpan(child: SizedBox(width: 11, height: 10)),
        TextSpan(text: 'c'),
      ],
    );

    const TextSpan textSpan4 = TextSpan(
      text: 'a',
      children: <InlineSpan>[
        TextSpan(text: 'b'),
        WidgetSpan(child: Text('test')),
        TextSpan(text: 'c'),
      ],
    );

    const TextSpan textSpan5 = TextSpan(
      text: 'a',
      children: <InlineSpan>[
        TextSpan(text: 'b'),
        WidgetSpan(child: Text('different!')),
        TextSpan(text: 'c'),
      ],
    );

    const TextSpan textSpan6 = TextSpan(
      text: 'a',
      children: <InlineSpan>[
        TextSpan(text: 'b'),
        WidgetSpan(
          child: SizedBox(width: 10, height: 10),
          alignment: PlaceholderAlignment.top,
        ),
        TextSpan(text: 'c'),
      ],
    );

    expect(textSpan1.compareTo(textSpan3), RenderComparison.layout);
    expect(textSpan1.compareTo(textSpan4), RenderComparison.layout);
    expect(textSpan1.compareTo(textSpan1), RenderComparison.identical);
    expect(textSpan2.compareTo(textSpan2), RenderComparison.identical);
    expect(textSpan3.compareTo(textSpan3), RenderComparison.identical);
    expect(textSpan2.compareTo(textSpan3), RenderComparison.layout);
    expect(textSpan4.compareTo(textSpan5), RenderComparison.layout);
    expect(textSpan3.compareTo(textSpan5), RenderComparison.layout);
    expect(textSpan2.compareTo(textSpan5), RenderComparison.layout);
    expect(textSpan1.compareTo(textSpan5), RenderComparison.layout);
    expect(textSpan1.compareTo(textSpan6), RenderComparison.layout);
  });

  test('TextSpan nested widget change test', () {
    const TextSpan textSpan1 = TextSpan(
      text: 'a',
      children: <InlineSpan>[
        TextSpan(text: 'b'),
        WidgetSpan(
          child: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                WidgetSpan(child: SizedBox(width: 10, height: 10)),
                TextSpan(text: 'The sky is falling :)'),
              ],
            ),
          ),
        ),
        TextSpan(text: 'c'),
      ],
    );

    const TextSpan textSpan2 = TextSpan(
      text: 'a',
      children: <InlineSpan>[
        TextSpan(text: 'b'),
        WidgetSpan(
          child: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                WidgetSpan(child: SizedBox(width: 10, height: 11)),
                TextSpan(text: 'The sky is falling :)'),
              ],
            ),
          ),
        ),
        TextSpan(text: 'c'),
      ],
    );

    expect(textSpan1.compareTo(textSpan2), RenderComparison.layout);
    expect(textSpan1.compareTo(textSpan1), RenderComparison.identical);
    expect(textSpan2.compareTo(textSpan2), RenderComparison.identical);
  });

  test('GetSpanForPosition with WidgetSpan', () {
    const TextSpan textSpan = TextSpan(
      text: 'a',
      children: <InlineSpan>[
        TextSpan(text: 'b'),
        WidgetSpan(
          child: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                WidgetSpan(child: SizedBox(width: 10, height: 10)),
                TextSpan(text: 'The sky is falling :)'),
              ],
            ),
          ),
        ),
        TextSpan(text: 'c'),
      ],
    );

    expect(textSpan.getSpanForPosition(const TextPosition(offset: 0)).runtimeType, TextSpan);
    expect(textSpan.getSpanForPosition(const TextPosition(offset: 1)).runtimeType, TextSpan);
    expect(textSpan.getSpanForPosition(const TextPosition(offset: 2)).runtimeType, WidgetSpan);
    expect(textSpan.getSpanForPosition(const TextPosition(offset: 3)).runtimeType, TextSpan);
  });

  test('TextSpan computeSemanticsInformation', () {
    final List<InlineSpanSemanticsInformation> collector = <InlineSpanSemanticsInformation>[];
    const TextSpan(text: 'aaa', semanticsLabel: 'bbb').computeSemanticsInformation(collector);
    expect(collector[0].text, 'aaa');
    expect(collector[0].semanticsLabel, 'bbb');
  });

  testWidgets('handles mouse cursor', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: Text.rich(
            TextSpan(
              text: 'xxxxx',
              children: <InlineSpan>[
                TextSpan(
                  text: 'yyyyy',
                  mouseCursor: SystemMouseCursors.forbidden,
                ),
                TextSpan(
                  text: 'xxxxx',
                ),
              ],
            ),
            textAlign: TextAlign.center,
          ),
        ),
      ),
    );

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);

    await gesture.moveTo(tester.getCenter(find.byType(RichText)) - const Offset(40, 0));
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);

    await gesture.moveTo(tester.getCenter(find.byType(RichText)));
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden);

    await gesture.moveTo(tester.getCenter(find.byType(RichText)) + const Offset(40, 0));
    expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
  });

  testWidgets('handles onEnter and onExit', (WidgetTester tester) async {
    final List<PointerEvent> logEvents = <PointerEvent>[];
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: Text.rich(
            TextSpan(
              text: 'xxxxx',
              children: <InlineSpan>[
                TextSpan(
                  text: 'yyyyy',
                  onEnter: (PointerEnterEvent event) {
                    logEvents.add(event);
                  },
                  onExit: (PointerExitEvent event) {
                    logEvents.add(event);
                  },
                ),
                const TextSpan(
                  text: 'xxxxx',
                ),
              ],
            ),
            textAlign: TextAlign.center,
          ),
        ),
      ),
    );

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);

    await gesture.moveTo(tester.getCenter(find.byType(RichText)) - const Offset(40, 0));
    expect(logEvents, isEmpty);

    await gesture.moveTo(tester.getCenter(find.byType(RichText)));
    expect(logEvents.length, 1);
    expect(logEvents[0], isA<PointerEnterEvent>());

    await gesture.moveTo(tester.getCenter(find.byType(RichText)) + const Offset(40, 0));
    expect(logEvents.length, 2);
    expect(logEvents[1], isA<PointerExitEvent>());
  });

  testWidgets('TextSpan can compute StringAttributes', (WidgetTester tester) async {
    const TextSpan span = TextSpan(
      text: 'aaaaa',
      spellOut: true,
      children: <InlineSpan>[
        TextSpan(text: 'yyyyy', locale: Locale('es', 'MX')),
        TextSpan(
          text: 'xxxxx',
          spellOut: false,
          children: <InlineSpan>[
            TextSpan(text: 'zzzzz'),
            TextSpan(text: 'bbbbb', spellOut: true),
          ]
        ),
      ],
    );
    final List<InlineSpanSemanticsInformation> collector = <InlineSpanSemanticsInformation>[];
    span.computeSemanticsInformation(collector);
    expect(collector.length, 5);
    expect(collector[0].stringAttributes.length, 1);
    expect(collector[0].stringAttributes[0], isA<SpellOutStringAttribute>());
    expect(collector[0].stringAttributes[0].range, const TextRange(start: 0, end: 5));
    expect(collector[1].stringAttributes.length, 2);
    expect(collector[1].stringAttributes[0], isA<SpellOutStringAttribute>());
    expect(collector[1].stringAttributes[0].range, const TextRange(start: 0, end: 5));
    expect(collector[1].stringAttributes[1], isA<LocaleStringAttribute>());
    expect(collector[1].stringAttributes[1].range, const TextRange(start: 0, end: 5));
    final LocaleStringAttribute localeStringAttribute = collector[1].stringAttributes[1] as LocaleStringAttribute;
    expect(localeStringAttribute.locale, const Locale('es', 'MX'));
    expect(collector[2].stringAttributes.length, 0);
    expect(collector[3].stringAttributes.length, 0);
    expect(collector[4].stringAttributes.length, 1);
    expect(collector[4].stringAttributes[0], isA<SpellOutStringAttribute>());
    expect(collector[4].stringAttributes[0].range, const TextRange(start: 0, end: 5));

    final List<InlineSpanSemanticsInformation> combined = combineSemanticsInfo(collector);
    expect(combined.length, 1);
    expect(combined[0].stringAttributes.length, 4);
    expect(combined[0].stringAttributes[0], isA<SpellOutStringAttribute>());
    expect(combined[0].stringAttributes[0].range, const TextRange(start: 0, end: 5));
    expect(combined[0].stringAttributes[1], isA<SpellOutStringAttribute>());
    expect(combined[0].stringAttributes[1].range, const TextRange(start: 5, end: 10));
    expect(combined[0].stringAttributes[2], isA<LocaleStringAttribute>());
    expect(combined[0].stringAttributes[2].range, const TextRange(start: 5, end: 10));
    final LocaleStringAttribute combinedLocaleStringAttribute = combined[0].stringAttributes[2] as LocaleStringAttribute;
    expect(combinedLocaleStringAttribute.locale, const Locale('es', 'MX'));
    expect(combined[0].stringAttributes[3], isA<SpellOutStringAttribute>());
    expect(combined[0].stringAttributes[3].range, const TextRange(start: 20, end: 25));
  });
}
