// 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 'dart:convert' show jsonDecode;

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

import 'text_input_utils.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('TextSelection', () {
    test('The invalid selection is a singleton', () {
      const TextSelection invalidSelection1 = TextSelection(
        baseOffset: -1,
        extentOffset: 0,
        isDirectional: true,
      );
      const TextSelection invalidSelection2 = TextSelection(baseOffset: 123,
        extentOffset: -1,
        affinity: TextAffinity.upstream,
      );
      expect(invalidSelection1, invalidSelection2);
      expect(invalidSelection1.hashCode, invalidSelection2.hashCode);
    });

    test('TextAffinity does not affect equivalence when the selection is not collapsed', () {
      const TextSelection selection1 = TextSelection(
        baseOffset: 1,
        extentOffset: 2,
      );
      const TextSelection selection2 = TextSelection(
        baseOffset: 1,
        extentOffset: 2,
        affinity: TextAffinity.upstream,
      );
      expect(selection1, selection2);
      expect(selection1.hashCode, selection2.hashCode);
    });
  });

  group('TextEditingValue', () {
    group('replaced', () {
      const String testText = 'From a false proposition, anything follows.';

      test('selection deletion', () {
        const TextSelection selection = TextSelection(baseOffset: 5, extentOffset: 13);
        expect(
          const TextEditingValue(text: testText, selection: selection).replaced(selection, ''),
          const TextEditingValue(text:  'From proposition, anything follows.', selection: TextSelection.collapsed(offset: 5)),
        );
      });

      test('reversed selection deletion', () {
        const TextSelection selection = TextSelection(baseOffset: 13, extentOffset: 5);
        expect(
          const TextEditingValue(text: testText, selection: selection).replaced(selection, ''),
          const TextEditingValue(text:  'From proposition, anything follows.', selection: TextSelection.collapsed(offset: 5)),
        );
      });

      test('insert', () {
        const TextSelection selection = TextSelection.collapsed(offset: 5);
        expect(
          const TextEditingValue(text: testText, selection: selection).replaced(selection, 'AA'),
          const TextEditingValue(
            text:  'From AAa false proposition, anything follows.',
            // The caret moves to the end of the text inserted.
            selection: TextSelection.collapsed(offset: 7),
          ),
        );
      });

      test('replace before selection', () {
        const TextSelection selection = TextSelection(baseOffset: 13, extentOffset: 5);
        expect(
          // From |a false |proposition, anything follows.
          // Replace the first whitespace with "AA".
          const TextEditingValue(text: testText, selection: selection).replaced(const TextRange(start: 4, end: 5), 'AA'),
          const TextEditingValue(text:  'FromAAa false proposition, anything follows.', selection: TextSelection(baseOffset: 14, extentOffset: 6)),
        );
      });

      test('replace after selection', () {
        const TextSelection selection = TextSelection(baseOffset: 13, extentOffset: 5);
        expect(
          // From |a false |proposition, anything follows.
          // replace the first "p" with "AA".
          const TextEditingValue(text: testText, selection: selection).replaced(const TextRange(start: 13, end: 14), 'AA'),
          const TextEditingValue(text:  'From a false AAroposition, anything follows.', selection: selection),
        );
      });

      test('replace inside selection - start boundary', () {
        const TextSelection selection = TextSelection(baseOffset: 13, extentOffset: 5);
        expect(
          // From |a false |proposition, anything follows.
          // replace the first "a" with "AA".
          const TextEditingValue(text: testText, selection: selection).replaced(const TextRange(start: 5, end: 6), 'AA'),
          const TextEditingValue(text:  'From AA false proposition, anything follows.', selection: TextSelection(baseOffset: 14, extentOffset: 5)),
        );
      });

      test('replace inside selection - end boundary', () {
        const TextSelection selection = TextSelection(baseOffset: 13, extentOffset: 5);
        expect(
          // From |a false |proposition, anything follows.
          // replace the second whitespace with "AA".
          const TextEditingValue(text: testText, selection: selection).replaced(const TextRange(start: 12, end: 13), 'AA'),
          const TextEditingValue(text:  'From a falseAAproposition, anything follows.', selection: TextSelection(baseOffset: 14, extentOffset: 5)),
        );
      });

      test('delete after selection', () {
        const TextSelection selection = TextSelection(baseOffset: 13, extentOffset: 5);
        expect(
          // From |a false |proposition, anything follows.
          // Delete the first "p".
          const TextEditingValue(text: testText, selection: selection).replaced(const TextRange(start: 13, end: 14), ''),
          const TextEditingValue(text:  'From a false roposition, anything follows.', selection: selection),
        );
      });

      test('delete inside selection - start boundary', () {
        const TextSelection selection = TextSelection(baseOffset: 13, extentOffset: 5);
        expect(
          // From |a false |proposition, anything follows.
          // Delete the first "a".
          const TextEditingValue(text: testText, selection: selection).replaced(const TextRange(start: 5, end: 6), ''),
          const TextEditingValue(text:  'From  false proposition, anything follows.', selection: TextSelection(baseOffset: 12, extentOffset: 5)),
        );
      });

      test('delete inside selection - end boundary', () {
        const TextSelection selection = TextSelection(baseOffset: 13, extentOffset: 5);
        expect(
          // From |a false |proposition, anything follows.
          // Delete the second whitespace.
          const TextEditingValue(text: testText, selection: selection).replaced(const TextRange(start: 12, end: 13), ''),
          const TextEditingValue(text:  'From a falseproposition, anything follows.', selection: TextSelection(baseOffset: 12, extentOffset: 5)),
        );
      });
    });
  });

  group('TextInput message channels', () {
    late FakeTextChannel fakeTextChannel;

    setUp(() {
      fakeTextChannel = FakeTextChannel((MethodCall call) async {});
      TextInput.setChannel(fakeTextChannel);
    });

    tearDown(() {
      TextInputConnection.debugResetId();
      TextInput.setChannel(SystemChannels.textInput);
    });

    test('text input client handler responds to reattach with setClient', () async {
      final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue(text: 'test1'));
      TextInput.attach(client, client.configuration);
      fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
        MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
      ]);

      fakeTextChannel.incoming!(const MethodCall('TextInputClient.requestExistingInputState'));

      expect(fakeTextChannel.outgoingCalls.length, 3);
      fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
        // From original attach
        MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
        // From requestExistingInputState
        MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
        MethodCall('TextInput.setEditingState', client.currentTextEditingValue.toJSON()),
      ]);
    });

    test('text input client handler responds to reattach with setClient (null TextEditingValue)', () async {
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      TextInput.attach(client, client.configuration);
      fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
        MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
      ]);

      fakeTextChannel.incoming!(const MethodCall('TextInputClient.requestExistingInputState'));

      expect(fakeTextChannel.outgoingCalls.length, 3);
      fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
        // From original attach
        MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
        // From original attach
        MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
        // From requestExistingInputState
        const MethodCall(
          'TextInput.setEditingState',
          <String, dynamic>{
            'text': '',
            'selectionBase': -1,
            'selectionExtent': -1,
            'selectionAffinity': 'TextAffinity.downstream',
            'selectionIsDirectional': false,
            'composingBase': -1,
            'composingExtent': -1,
          },
        ),
      ]);
    });

    test('Invalid TextRange fails loudly when being converted to JSON', () async {
      final List<FlutterErrorDetails> record = <FlutterErrorDetails>[];
      FlutterError.onError = (FlutterErrorDetails details) {
        record.add(details);
      };

      final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue(text: 'test3'));
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'method': 'TextInputClient.updateEditingState',
        'args': <dynamic>[-1, <String, dynamic>{
          'text': '1',
          'selectionBase': 2,
          'selectionExtent': 3,
        }],
      });

      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );
      expect(record.length, 1);
      // Verify the error message in parts because Web formats the message
      // differently from others.
      expect(record[0].exception.toString(), matches(RegExp(r'\brange.start >= 0 && range.start <= text.length\b')));
      expect(record[0].exception.toString(), matches(RegExp(r'\bRange start 2 is out of text of length 1\b')));
    });

    test('FloatingCursor coordinates type-casting', () async {
      // Regression test for https://github.com/flutter/flutter/issues/109632.
      final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[];
      FlutterError.onError = errors.add;

      final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue(text: 'test3'));
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'method': 'TextInputClient.updateFloatingCursor',
        'args': <dynamic>[
          -1,
          'FloatingCursorDragState.update',
          <String, dynamic>{ 'X': 2, 'Y': 3 },
        ],
      });

      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(errors, isEmpty);
    });
  });

  group('TextInputConfiguration', () {
    tearDown(() {
      TextInputConnection.debugResetId();
    });

    test('sets expected defaults', () {
      const TextInputConfiguration configuration = TextInputConfiguration();
      expect(configuration.inputType, TextInputType.text);
      expect(configuration.readOnly, false);
      expect(configuration.obscureText, false);
      expect(configuration.enableDeltaModel, false);
      expect(configuration.autocorrect, true);
      expect(configuration.actionLabel, null);
      expect(configuration.textCapitalization, TextCapitalization.none);
      expect(configuration.keyboardAppearance, Brightness.light);
    });

    test('text serializes to JSON', () async {
      const TextInputConfiguration configuration = TextInputConfiguration(
        readOnly: true,
        obscureText: true,
        autocorrect: false,
        actionLabel: 'xyzzy',
      );
      final Map<String, dynamic> json = configuration.toJson();
      expect(json['inputType'], <String, dynamic>{
        'name': 'TextInputType.text',
        'signed': null,
        'decimal': null,
      });
      expect(json['readOnly'], true);
      expect(json['obscureText'], true);
      expect(json['autocorrect'], false);
      expect(json['actionLabel'], 'xyzzy');
    });

    test('number serializes to JSON', () async {
      const TextInputConfiguration configuration = TextInputConfiguration(
        inputType: TextInputType.numberWithOptions(decimal: true),
        obscureText: true,
        autocorrect: false,
        actionLabel: 'xyzzy',
      );
      final Map<String, dynamic> json = configuration.toJson();
      expect(json['inputType'], <String, dynamic>{
        'name': 'TextInputType.number',
        'signed': false,
        'decimal': true,
      });
      expect(json['readOnly'], false);
      expect(json['obscureText'], true);
      expect(json['autocorrect'], false);
      expect(json['actionLabel'], 'xyzzy');
    });

    test('basic structure', () async {
      const TextInputType text = TextInputType.text;
      const TextInputType number = TextInputType.number;
      const TextInputType number2 = TextInputType.number;
      const TextInputType signed = TextInputType.numberWithOptions(signed: true);
      const TextInputType signed2 = TextInputType.numberWithOptions(signed: true);
      const TextInputType decimal = TextInputType.numberWithOptions(decimal: true);
      const TextInputType signedDecimal =
        TextInputType.numberWithOptions(signed: true, decimal: true);

      expect(text.toString(), 'TextInputType(name: TextInputType.text, signed: null, decimal: null)');
      expect(number.toString(), 'TextInputType(name: TextInputType.number, signed: false, decimal: false)');
      expect(signed.toString(), 'TextInputType(name: TextInputType.number, signed: true, decimal: false)');
      expect(decimal.toString(), 'TextInputType(name: TextInputType.number, signed: false, decimal: true)');
      expect(signedDecimal.toString(), 'TextInputType(name: TextInputType.number, signed: true, decimal: true)');
      expect(TextInputType.multiline.toString(), 'TextInputType(name: TextInputType.multiline, signed: null, decimal: null)');
      expect(TextInputType.phone.toString(), 'TextInputType(name: TextInputType.phone, signed: null, decimal: null)');
      expect(TextInputType.datetime.toString(), 'TextInputType(name: TextInputType.datetime, signed: null, decimal: null)');
      expect(TextInputType.emailAddress.toString(), 'TextInputType(name: TextInputType.emailAddress, signed: null, decimal: null)');
      expect(TextInputType.url.toString(), 'TextInputType(name: TextInputType.url, signed: null, decimal: null)');
      expect(TextInputType.visiblePassword.toString(), 'TextInputType(name: TextInputType.visiblePassword, signed: null, decimal: null)');
      expect(TextInputType.name.toString(), 'TextInputType(name: TextInputType.name, signed: null, decimal: null)');
      expect(TextInputType.streetAddress.toString(), 'TextInputType(name: TextInputType.address, signed: null, decimal: null)');
      expect(TextInputType.none.toString(), 'TextInputType(name: TextInputType.none, signed: null, decimal: null)');

      expect(text == number, false);
      expect(number == number2, true);
      expect(number == signed, false);
      expect(signed == signed2, true);
      expect(signed == decimal, false);
      expect(signed == signedDecimal, false);
      expect(decimal == signedDecimal, false);

      expect(text.hashCode == number.hashCode, false);
      expect(number.hashCode == number2.hashCode, true);
      expect(number.hashCode == signed.hashCode, false);
      expect(signed.hashCode == signed2.hashCode, true);
      expect(signed.hashCode == decimal.hashCode, false);
      expect(signed.hashCode == signedDecimal.hashCode, false);
      expect(decimal.hashCode == signedDecimal.hashCode, false);

      expect(TextInputType.text.index, 0);
      expect(TextInputType.multiline.index, 1);
      expect(TextInputType.number.index, 2);
      expect(TextInputType.phone.index, 3);
      expect(TextInputType.datetime.index, 4);
      expect(TextInputType.emailAddress.index, 5);
      expect(TextInputType.url.index, 6);
      expect(TextInputType.visiblePassword.index, 7);
      expect(TextInputType.name.index, 8);
      expect(TextInputType.streetAddress.index, 9);
      expect(TextInputType.none.index, 10);

      expect(TextEditingValue.empty.toString(),
          'TextEditingValue(text: \u2524\u251C, selection: ${const TextSelection.collapsed(offset: -1)}, composing: ${TextRange.empty})');
      expect(const TextEditingValue(text: 'Sample Text').toString(),
          'TextEditingValue(text: \u2524Sample Text\u251C, selection: ${const TextSelection.collapsed(offset: -1)}, composing: ${TextRange.empty})');
    });

    test('TextInputClient onConnectionClosed method is called', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue(text: 'test3'));
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      expect(client.latestMethodCall, isEmpty);

      // Send onConnectionClosed message.
      final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[1],
        'method': 'TextInputClient.onConnectionClosed',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(client.latestMethodCall, 'connectionClosed');
    });

    test('TextInputClient performSelectors method is called', () async {
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      expect(client.performedSelectors, isEmpty);
      expect(client.latestMethodCall, isEmpty);

      // Send performSelectors message.
      final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[
          1,
          <dynamic>[
            'selector1',
            'selector2',
          ]
        ],
        'method': 'TextInputClient.performSelectors',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(client.latestMethodCall, 'performSelector');
      expect(client.performedSelectors, <String>['selector1', 'selector2']);
    });

    test('TextInputClient performPrivateCommand method is called', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      expect(client.latestMethodCall, isEmpty);

      // Send performPrivateCommand message.
      final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[
          1,
          jsonDecode('{"action": "actionCommand", "data": {"input_context" : "abcdefg"}}'),
        ],
        'method': 'TextInputClient.performPrivateCommand',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(client.latestMethodCall, 'performPrivateCommand');
    });

    test('TextInputClient performPrivateCommand method is called with float', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      expect(client.latestMethodCall, isEmpty);

      // Send performPrivateCommand message.
      final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[
          1,
          jsonDecode('{"action": "actionCommand", "data": {"input_context" : 0.5}}'),
        ],
        'method': 'TextInputClient.performPrivateCommand',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(client.latestMethodCall, 'performPrivateCommand');
    });

    test('TextInputClient performPrivateCommand method is called with CharSequence array', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      expect(client.latestMethodCall, isEmpty);

      // Send performPrivateCommand message.
      final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[
          1,
          jsonDecode('{"action": "actionCommand", "data": {"input_context" : ["abc", "efg"]}}'),
        ],
        'method': 'TextInputClient.performPrivateCommand',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(client.latestMethodCall, 'performPrivateCommand');
    });

    test('TextInputClient performPrivateCommand method is called with CharSequence', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      expect(client.latestMethodCall, isEmpty);

      // Send performPrivateCommand message.
      final ByteData? messageBytes =
          const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[
          1,
          jsonDecode('{"action": "actionCommand", "data": {"input_context" : "abc"}}'),
        ],
        'method': 'TextInputClient.performPrivateCommand',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(client.latestMethodCall, 'performPrivateCommand');
    });

    test('TextInputClient performPrivateCommand method is called with float array', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      expect(client.latestMethodCall, isEmpty);

      // Send performPrivateCommand message.
      final ByteData? messageBytes =
          const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[
          1,
          jsonDecode('{"action": "actionCommand", "data": {"input_context" : [0.5, 0.8]}}'),
        ],
        'method': 'TextInputClient.performPrivateCommand',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(client.latestMethodCall, 'performPrivateCommand');
    });

    test('TextInputClient performPrivateCommand method is called with no data at all', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      expect(client.latestMethodCall, isEmpty);

      // Send performPrivateCommand message.
      final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[
          1,
          jsonDecode('{"action": "actionCommand"}'), // No `data` parameter.
        ],
        'method': 'TextInputClient.performPrivateCommand',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(client.latestMethodCall, 'performPrivateCommand');
      expect(client.latestPrivateCommandData, <String, dynamic>{});
    });

    test('TextInputClient showAutocorrectionPromptRect method is called', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      expect(client.latestMethodCall, isEmpty);

      // Send onConnectionClosed message.
      final ByteData? messageBytes =
          const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[1, 0, 1],
        'method': 'TextInputClient.showAutocorrectionPromptRect',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(client.latestMethodCall, 'showAutocorrectionPromptRect');
    });

    test('TextInputClient showToolbar method is called', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      expect(client.latestMethodCall, isEmpty);

      // Send showToolbar message.
      final ByteData? messageBytes =
          const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[1, 0, 1],
        'method': 'TextInputClient.showToolbar',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(client.latestMethodCall, 'showToolbar');
    });
  });

  group('Scribble interactions', () {
    tearDown(() {
      TextInputConnection.debugResetId();
    });

    test('TextInputClient scribbleInteractionBegan and scribbleInteractionFinished', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      final TextInputConnection connection = TextInput.attach(client, configuration);

      expect(connection.scribbleInProgress, false);

      // Send scribbleInteractionBegan message.
      ByteData? messageBytes =
          const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[1, 0, 1],
        'method': 'TextInputClient.scribbleInteractionBegan',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(connection.scribbleInProgress, true);

      // Send scribbleInteractionFinished message.
      messageBytes =
          const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[1, 0, 1],
        'method': 'TextInputClient.scribbleInteractionFinished',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      expect(connection.scribbleInProgress, false);
    });

    test('TextInputClient focusElement', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      final FakeScribbleElement targetElement = FakeScribbleElement(elementIdentifier: 'target');
      TextInput.registerScribbleElement(targetElement.elementIdentifier, targetElement);
      final FakeScribbleElement otherElement = FakeScribbleElement(elementIdentifier: 'other');
      TextInput.registerScribbleElement(otherElement.elementIdentifier, otherElement);

      expect(targetElement.latestMethodCall, isEmpty);
      expect(otherElement.latestMethodCall, isEmpty);

      // Send focusElement message.
      final ByteData? messageBytes =
          const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[targetElement.elementIdentifier, 0.0, 0.0],
        'method': 'TextInputClient.focusElement',
      });
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? _) {},
      );

      TextInput.unregisterScribbleElement(targetElement.elementIdentifier);
      TextInput.unregisterScribbleElement(otherElement.elementIdentifier);

      expect(targetElement.latestMethodCall, 'onScribbleFocus');
      expect(otherElement.latestMethodCall, isEmpty);
    });

    test('TextInputClient requestElementsInRect', () async {
      // Assemble a TextInputConnection so we can verify its change in state.
      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      const TextInputConfiguration configuration = TextInputConfiguration();
      TextInput.attach(client, configuration);

      final List<FakeScribbleElement> targetElements = <FakeScribbleElement>[
        FakeScribbleElement(elementIdentifier: 'target1', bounds: const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0)),
        FakeScribbleElement(elementIdentifier: 'target2', bounds: const Rect.fromLTWH(0.0, 100.0, 100.0, 100.0)),
      ];
      final List<FakeScribbleElement> otherElements = <FakeScribbleElement>[
        FakeScribbleElement(elementIdentifier: 'other1', bounds: const Rect.fromLTWH(100.0, 0.0, 100.0, 100.0)),
        FakeScribbleElement(elementIdentifier: 'other2', bounds: const Rect.fromLTWH(100.0, 100.0, 100.0, 100.0)),
      ];

      void registerElements(FakeScribbleElement element) => TextInput.registerScribbleElement(element.elementIdentifier, element);
      void unregisterElements(FakeScribbleElement element) => TextInput.unregisterScribbleElement(element.elementIdentifier);

      <FakeScribbleElement>[...targetElements, ...otherElements].forEach(registerElements);

      // Send requestElementsInRect message.
      final ByteData? messageBytes =
          const JSONMessageCodec().encodeMessage(<String, dynamic>{
        'args': <dynamic>[0.0, 50.0, 50.0, 100.0],
        'method': 'TextInputClient.requestElementsInRect',
      });
      ByteData? responseBytes;
      await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
        'flutter/textinput',
        messageBytes,
        (ByteData? response) {
          responseBytes = response;
        },
      );

      <FakeScribbleElement>[...targetElements, ...otherElements].forEach(unregisterElements);

      final List<List<dynamic>> responses = (const JSONMessageCodec().decodeMessage(responseBytes) as List<dynamic>).cast<List<dynamic>>();
      expect(responses.first.length, 2);
      expect(responses.first.first, containsAllInOrder(<dynamic>[targetElements.first.elementIdentifier, 0.0, 0.0, 100.0, 100.0]));
      expect(responses.first.last, containsAllInOrder(<dynamic>[targetElements.last.elementIdentifier, 0.0, 100.0, 100.0, 100.0]));
    });
  });

  test('TextEditingValue.isComposingRangeValid', () async {
    // The composing range is empty.
    expect(TextEditingValue.empty.isComposingRangeValid, isFalse);

    expect(
      const TextEditingValue(text: 'test', composing: TextRange(start: 1, end: 0)).isComposingRangeValid,
      isFalse,
    );

    // The composing range is out of range for the text.
    expect(
      const TextEditingValue(text: 'test', composing: TextRange(start: 1, end: 5)).isComposingRangeValid,
      isFalse,
    );

    // The composing range is out of range for the text.
    expect(
      const TextEditingValue(text: 'test', composing: TextRange(start: -1, end: 4)).isComposingRangeValid,
      isFalse,
    );

    expect(
      const TextEditingValue(text: 'test', composing: TextRange(start: 1, end: 4)).isComposingRangeValid,
      isTrue,
    );
  });

  group('TextInputControl', () {
    late FakeTextChannel fakeTextChannel;

    setUp(() {
      fakeTextChannel = FakeTextChannel((MethodCall call) async {});
      TextInput.setChannel(fakeTextChannel);
    });

    tearDown(() {
      TextInput.restorePlatformInputControl();
      TextInputConnection.debugResetId();
      TextInput.setChannel(SystemChannels.textInput);
    });

    test('gets attached and detached', () {
      final FakeTextInputControl control = FakeTextInputControl();
      TextInput.setInputControl(control);

      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      final TextInputConnection connection = TextInput.attach(client, const TextInputConfiguration());

      final List<String> expectedMethodCalls = <String>['attach'];
      expect(control.methodCalls, expectedMethodCalls);

      connection.close();
      expectedMethodCalls.add('detach');
      expect(control.methodCalls, expectedMethodCalls);
    });

    test('receives text input state changes', () {
      final FakeTextInputControl control = FakeTextInputControl();
      TextInput.setInputControl(control);

      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      final TextInputConnection connection = TextInput.attach(client, const TextInputConfiguration());
      control.methodCalls.clear();

      final List<String> expectedMethodCalls = <String>[];

      connection.updateConfig(const TextInputConfiguration());
      expectedMethodCalls.add('updateConfig');
      expect(control.methodCalls, expectedMethodCalls);

      connection.setEditingState(TextEditingValue.empty);
      expectedMethodCalls.add('setEditingState');
      expect(control.methodCalls, expectedMethodCalls);

      connection.close();
      expectedMethodCalls.add('detach');
      expect(control.methodCalls, expectedMethodCalls);
    });

    test('does not interfere with platform text input', () {
      final FakeTextInputControl control = FakeTextInputControl();
      TextInput.setInputControl(control);

      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      TextInput.attach(client, const TextInputConfiguration());

      fakeTextChannel.outgoingCalls.clear();

      fakeTextChannel.incoming!(MethodCall('TextInputClient.updateEditingState', <dynamic>[1, TextEditingValue.empty.toJSON()]));

      expect(client.latestMethodCall, 'updateEditingValue');
      expect(control.methodCalls, <String>['attach', 'setEditingState']);
      expect(fakeTextChannel.outgoingCalls, isEmpty);
    });

    test('both input controls receive requests', () async {
      final FakeTextInputControl control = FakeTextInputControl();
      TextInput.setInputControl(control);

      const TextInputConfiguration textConfig = TextInputConfiguration();
      const TextInputConfiguration numberConfig = TextInputConfiguration(inputType: TextInputType.number);
      const TextInputConfiguration noneConfig = TextInputConfiguration(inputType: TextInputType.none);

      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      final TextInputConnection connection = TextInput.attach(client, textConfig);

      final List<String> expectedMethodCalls = <String>['attach'];
      expect(control.methodCalls, expectedMethodCalls);
      expect(control.inputType, TextInputType.text);
      fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
        // When there's a custom text input control installed, the platform text
        // input control receives TextInputType.none
        MethodCall('TextInput.setClient', <dynamic>[1, noneConfig.toJson()]),
      ]);

      connection.show();
      expectedMethodCalls.add('show');
      expect(control.methodCalls, expectedMethodCalls);
      expect(fakeTextChannel.outgoingCalls.length, 2);
      expect(fakeTextChannel.outgoingCalls.last.method, 'TextInput.show');

      connection.updateConfig(numberConfig);
      expectedMethodCalls.add('updateConfig');
      expect(control.methodCalls, expectedMethodCalls);
      expect(control.inputType, TextInputType.number);
      expect(fakeTextChannel.outgoingCalls.length, 3);
      fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
        // When there's a custom text input control installed, the platform text
        // input control receives TextInputType.none
        MethodCall('TextInput.setClient', <dynamic>[1, noneConfig.toJson()]),
        const MethodCall('TextInput.show'),
        MethodCall('TextInput.updateConfig', noneConfig.toJson()),
      ]);

      connection.setComposingRect(Rect.zero);
      expectedMethodCalls.add('setComposingRect');
      expect(control.methodCalls, expectedMethodCalls);
      expect(fakeTextChannel.outgoingCalls.length, 4);
      expect(fakeTextChannel.outgoingCalls.last.method, 'TextInput.setMarkedTextRect');

      connection.setCaretRect(Rect.zero);
      expectedMethodCalls.add('setCaretRect');
      expect(control.methodCalls, expectedMethodCalls);
      expect(fakeTextChannel.outgoingCalls.length, 5);
      expect(fakeTextChannel.outgoingCalls.last.method, 'TextInput.setCaretRect');

      connection.setEditableSizeAndTransform(Size.zero, Matrix4.identity());
      expectedMethodCalls.add('setEditableSizeAndTransform');
      expect(control.methodCalls, expectedMethodCalls);
      expect(fakeTextChannel.outgoingCalls.length, 6);
      expect(fakeTextChannel.outgoingCalls.last.method, 'TextInput.setEditableSizeAndTransform');

      connection.setSelectionRects(const <SelectionRect>[SelectionRect(position: 1, bounds: Rect.fromLTWH(2, 3, 4, 5), direction: TextDirection.rtl)]);
      expectedMethodCalls.add('setSelectionRects');
      expect(control.methodCalls, expectedMethodCalls);
      expect(fakeTextChannel.outgoingCalls.length, 7);
      expect(fakeTextChannel.outgoingCalls.last.arguments, const TypeMatcher<List<List<num>>>());
      final List<List<num>> sentList = fakeTextChannel.outgoingCalls.last.arguments as List<List<num>>;
      expect(sentList.length, 1);
      expect(sentList[0].length, 6);
      expect(sentList[0][0], 2); // left
      expect(sentList[0][1], 3); // top
      expect(sentList[0][2], 4); // width
      expect(sentList[0][3], 5); // height
      expect(sentList[0][4], 1); // position
      expect(sentList[0][5], TextDirection.rtl.index); // direction
      expect(fakeTextChannel.outgoingCalls.last.method, 'TextInput.setSelectionRects');

      connection.setStyle(
        fontFamily: null,
        fontSize: null,
        fontWeight: null,
        textDirection: TextDirection.ltr,
        textAlign: TextAlign.left,
      );
      expectedMethodCalls.add('setStyle');
      expect(control.methodCalls, expectedMethodCalls);
      expect(fakeTextChannel.outgoingCalls.length, 8);
      expect(fakeTextChannel.outgoingCalls.last.method, 'TextInput.setStyle');

      connection.close();
      expectedMethodCalls.add('detach');
      expect(control.methodCalls, expectedMethodCalls);
      expect(fakeTextChannel.outgoingCalls.length, 9);
      expect(fakeTextChannel.outgoingCalls.last.method, 'TextInput.clearClient');

      expectedMethodCalls.add('hide');
      final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
      await binding.runAsync(() async {});
      await expectLater(control.methodCalls, expectedMethodCalls);
      expect(fakeTextChannel.outgoingCalls.length, 10);
      expect(fakeTextChannel.outgoingCalls.last.method, 'TextInput.hide');
    });

    test('notifies changes to the attached client', () async {
      final FakeTextInputControl control = FakeTextInputControl();
      TextInput.setInputControl(control);

      final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
      final TextInputConnection connection = TextInput.attach(client, const TextInputConfiguration());

      TextInput.setInputControl(null);
      expect(client.latestMethodCall, 'didChangeInputControl');

      connection.show();
      expect(client.latestMethodCall, 'didChangeInputControl');
    });
  });
}

class FakeTextInputClient with TextInputClient {
  FakeTextInputClient(this.currentTextEditingValue);

  String latestMethodCall = '';
  final List<String> performedSelectors = <String>[];
  late Map<String, dynamic>? latestPrivateCommandData;

  @override
  TextEditingValue currentTextEditingValue;

  @override
  AutofillScope? get currentAutofillScope => null;

  @override
  void performAction(TextInputAction action) {
    latestMethodCall = 'performAction';
  }

  @override
  void performPrivateCommand(String action, Map<String, dynamic>? data) {
    latestMethodCall = 'performPrivateCommand';
    latestPrivateCommandData = data;
  }

  @override
  void updateEditingValue(TextEditingValue value) {
    latestMethodCall = 'updateEditingValue';
  }

  @override
  void updateFloatingCursor(RawFloatingCursorPoint point) {
    latestMethodCall = 'updateFloatingCursor';
  }

  @override
  void connectionClosed() {
    latestMethodCall = 'connectionClosed';
  }

  @override
  void showAutocorrectionPromptRect(int start, int end) {
    latestMethodCall = 'showAutocorrectionPromptRect';
  }

  @override
  void showToolbar() {
    latestMethodCall = 'showToolbar';
  }

  TextInputConfiguration get configuration => const TextInputConfiguration();

  @override
  void didChangeInputControl(TextInputControl? oldControl, TextInputControl? newControl) {
    latestMethodCall = 'didChangeInputControl';
  }

  @override
  void insertTextPlaceholder(Size size) {
    latestMethodCall = 'insertTextPlaceholder';
  }

  @override
  void removeTextPlaceholder() {
    latestMethodCall = 'removeTextPlaceholder';
  }

  @override
  void performSelector(String selectorName) {
    latestMethodCall = 'performSelector';
    performedSelectors.add(selectorName);
  }
}

class FakeTextInputControl with TextInputControl {
  final List<String> methodCalls = <String>[];
  late TextInputType inputType;

  @override
  void attach(TextInputClient client, TextInputConfiguration configuration) {
    methodCalls.add('attach');
    inputType = configuration.inputType;
  }

  @override
  void detach(TextInputClient client) {
    methodCalls.add('detach');
  }

  @override
  void setEditingState(TextEditingValue value) {
    methodCalls.add('setEditingState');
  }

  @override
  void updateConfig(TextInputConfiguration configuration) {
    methodCalls.add('updateConfig');
    inputType = configuration.inputType;
  }

  @override
  void show() {
    methodCalls.add('show');
  }

  @override
  void hide() {
    methodCalls.add('hide');
  }

  @override
  void setComposingRect(Rect rect) {
    methodCalls.add('setComposingRect');
  }

  @override
  void setCaretRect(Rect rect) {
    methodCalls.add('setCaretRect');
  }

  @override
  void setEditableSizeAndTransform(Size editableBoxSize, Matrix4 transform) {
    methodCalls.add('setEditableSizeAndTransform');
  }

  @override
  void setSelectionRects(List<SelectionRect> selectionRects) {
    methodCalls.add('setSelectionRects');
  }

  @override
  void setStyle({
    required String? fontFamily,
    required double? fontSize,
    required FontWeight? fontWeight,
    required TextDirection textDirection,
    required TextAlign textAlign,
  }) {
    methodCalls.add('setStyle');
  }

  @override
  void finishAutofillContext({bool shouldSave = true}) {
    methodCalls.add('finishAutofillContext');
  }

  @override
  void requestAutofill() {
    methodCalls.add('requestAutofill');
  }
}
