// 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 "flutter/shell/platform/darwin/common/framework/Source/FlutterBinaryMessengerRelay.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Test.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h"

#import <OCMock/OCMock.h>
#import <XCTest/XCTest.h>

#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h"
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/UIViewController+FlutterScreenAndSceneIfLoaded.h"

FLUTTER_ASSERT_ARC

@interface FlutterEngine ()
- (nonnull FlutterTextInputPlugin*)textInputPlugin;
@end

@interface FlutterTextInputView ()
@property(nonatomic, copy) NSString* autofillId;
- (void)setEditableTransform:(NSArray*)matrix;
- (void)setTextInputClient:(int)client;
- (void)setTextInputState:(NSDictionary*)state;
- (void)setMarkedRect:(CGRect)markedRect;
- (void)updateEditingState;
- (BOOL)isVisibleToAutofill;
- (id<FlutterTextInputDelegate>)textInputDelegate;
- (void)configureWithDictionary:(NSDictionary*)configuration;
@end

@interface FlutterTextInputViewSpy : FlutterTextInputView
@property(nonatomic, assign) UIAccessibilityNotifications receivedNotification;
@property(nonatomic, assign) id receivedNotificationTarget;
@property(nonatomic, assign) BOOL isAccessibilityFocused;

- (void)postAccessibilityNotification:(UIAccessibilityNotifications)notification target:(id)target;

@end

@implementation FlutterTextInputViewSpy {
}

- (void)postAccessibilityNotification:(UIAccessibilityNotifications)notification target:(id)target {
  self.receivedNotification = notification;
  self.receivedNotificationTarget = target;
}

- (BOOL)accessibilityElementIsFocused {
  return _isAccessibilityFocused;
}

@end

@interface FlutterSecureTextInputView : FlutterTextInputView
@property(nonatomic, strong) UITextField* textField;
@end

@interface FlutterTextInputPlugin ()
@property(nonatomic, assign) FlutterTextInputView* activeView;
@property(nonatomic, readonly) UIView* inputHider;
@property(nonatomic, readonly) UIView* keyboardViewContainer;
@property(nonatomic, readonly) UIView* keyboardView;
@property(nonatomic, assign) UIView* cachedFirstResponder;
@property(nonatomic, readonly) CGRect keyboardRect;
@property(nonatomic, readonly)
    NSMutableDictionary<NSString*, FlutterTextInputView*>* autofillContext;

- (void)cleanUpViewHierarchy:(BOOL)includeActiveView
                   clearText:(BOOL)clearText
                delayRemoval:(BOOL)delayRemoval;
- (NSArray<UIView*>*)textInputViews;
- (UIView*)hostView;
- (void)addToInputParentViewIfNeeded:(FlutterTextInputView*)inputView;
- (void)startLiveTextInput;
- (void)showKeyboardAndRemoveScreenshot;

@end

@interface FlutterTextInputPluginTest : XCTestCase
@end

@implementation FlutterTextInputPluginTest {
  NSDictionary* _template;
  NSDictionary* _passwordTemplate;
  id engine;
  FlutterTextInputPlugin* textInputPlugin;

  FlutterViewController* viewController;
}

- (void)setUp {
  [super setUp];
  engine = OCMClassMock([FlutterEngine class]);

  textInputPlugin = [[FlutterTextInputPlugin alloc] initWithDelegate:engine];

  viewController = [[FlutterViewController alloc] init];
  textInputPlugin.viewController = viewController;

  // Clear pasteboard between tests.
  UIPasteboard.generalPasteboard.items = @[];
}

- (void)tearDown {
  textInputPlugin = nil;
  engine = nil;
  [textInputPlugin.autofillContext removeAllObjects];
  [textInputPlugin cleanUpViewHierarchy:YES clearText:YES delayRemoval:NO];
  [[[[textInputPlugin textInputView] superview] subviews]
      makeObjectsPerformSelector:@selector(removeFromSuperview)];
  viewController = nil;
  [super tearDown];
}

- (void)setClientId:(int)clientId configuration:(NSDictionary*)config {
  FlutterMethodCall* setClientCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
                                        arguments:@[ [NSNumber numberWithInt:clientId], config ]];
  [textInputPlugin handleMethodCall:setClientCall
                             result:^(id _Nullable result){
                             }];
}

- (void)setTextInputShow {
  FlutterMethodCall* setClientCall = [FlutterMethodCall methodCallWithMethodName:@"TextInput.show"
                                                                       arguments:@[]];
  [textInputPlugin handleMethodCall:setClientCall
                             result:^(id _Nullable result){
                             }];
}

- (void)setTextInputHide {
  FlutterMethodCall* setClientCall = [FlutterMethodCall methodCallWithMethodName:@"TextInput.hide"
                                                                       arguments:@[]];
  [textInputPlugin handleMethodCall:setClientCall
                             result:^(id _Nullable result){
                             }];
}

- (void)flushScheduledAsyncBlocks {
  __block bool done = false;
  XCTestExpectation* expectation =
      [[XCTestExpectation alloc] initWithDescription:@"Testing on main queue"];
  dispatch_async(dispatch_get_main_queue(), ^{
    done = true;
  });
  dispatch_async(dispatch_get_main_queue(), ^{
    XCTAssertTrue(done);
    [expectation fulfill];
  });
  [self waitForExpectations:@[ expectation ] timeout:10];
}

- (NSMutableDictionary*)mutableTemplateCopy {
  if (!_template) {
    _template = @{
      @"inputType" : @{@"name" : @"TextInuptType.text"},
      @"keyboardAppearance" : @"Brightness.light",
      @"obscureText" : @NO,
      @"inputAction" : @"TextInputAction.unspecified",
      @"smartDashesType" : @"0",
      @"smartQuotesType" : @"0",
      @"autocorrect" : @YES,
      @"enableInteractiveSelection" : @YES,
    };
  }

  return [_template mutableCopy];
}

- (NSArray<FlutterTextInputView*>*)installedInputViews {
  return (NSArray<FlutterTextInputView*>*)[textInputPlugin.textInputViews
      filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self isKindOfClass: %@",
                                                                   [FlutterTextInputView class]]];
}

- (FlutterTextRange*)getLineRangeFromTokenizer:(id<UITextInputTokenizer>)tokenizer
                                       atIndex:(NSInteger)index {
  UITextRange* range =
      [tokenizer rangeEnclosingPosition:[FlutterTextPosition positionWithIndex:index]
                        withGranularity:UITextGranularityLine
                            inDirection:UITextLayoutDirectionRight];
  XCTAssertTrue([range isKindOfClass:[FlutterTextRange class]]);
  return (FlutterTextRange*)range;
}

- (void)updateConfig:(NSDictionary*)config {
  FlutterMethodCall* updateConfigCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.updateConfig" arguments:config];
  [textInputPlugin handleMethodCall:updateConfigCall
                             result:^(id _Nullable result){
                             }];
}

#pragma mark - Tests

- (void)testWillNotCrashWhenViewControllerIsNil {
  FlutterEngine* flutterEngine = [[FlutterEngine alloc] init];
  FlutterTextInputPlugin* inputPlugin =
      [[FlutterTextInputPlugin alloc] initWithDelegate:(id<FlutterTextInputDelegate>)flutterEngine];
  XCTAssertNil(inputPlugin.viewController);
  FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"TextInput.show"
                                                                    arguments:nil];
  XCTestExpectation* expectation = [[XCTestExpectation alloc] initWithDescription:@"result called"];

  [inputPlugin handleMethodCall:methodCall
                         result:^(id _Nullable result) {
                           XCTAssertNil(result);
                           [expectation fulfill];
                         }];
  XCTAssertNil(inputPlugin.activeView);
  [self waitForExpectations:@[ expectation ] timeout:1.0];
}

- (void)testInvokeStartLiveTextInput {
  FlutterMethodCall* methodCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.startLiveTextInput" arguments:nil];
  FlutterTextInputPlugin* mockPlugin = OCMPartialMock(textInputPlugin);
  [mockPlugin handleMethodCall:methodCall
                        result:^(id _Nullable result){
                        }];
  OCMVerify([mockPlugin startLiveTextInput]);
}

- (void)testNoDanglingEnginePointer {
  __weak FlutterTextInputPlugin* weakFlutterTextInputPlugin;
  FlutterViewController* flutterViewController = [[FlutterViewController alloc] init];
  __weak FlutterEngine* weakFlutterEngine;

  FlutterTextInputView* currentView;

  // The engine instance will be deallocated after the autorelease pool is drained.
  @autoreleasepool {
    FlutterEngine* flutterEngine = OCMClassMock([FlutterEngine class]);
    weakFlutterEngine = flutterEngine;
    NSAssert(weakFlutterEngine, @"flutter engine must not be nil");
    FlutterTextInputPlugin* flutterTextInputPlugin = [[FlutterTextInputPlugin alloc]
        initWithDelegate:(id<FlutterTextInputDelegate>)flutterEngine];
    weakFlutterTextInputPlugin = flutterTextInputPlugin;
    flutterTextInputPlugin.viewController = flutterViewController;

    // Set client so the text input plugin has an active view.
    NSDictionary* config = self.mutableTemplateCopy;
    FlutterMethodCall* setClientCall =
        [FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
                                          arguments:@[ [NSNumber numberWithInt:123], config ]];
    [flutterTextInputPlugin handleMethodCall:setClientCall
                                      result:^(id _Nullable result){
                                      }];
    currentView = flutterTextInputPlugin.activeView;
  }

  NSAssert(!weakFlutterEngine, @"flutter engine must be nil");
  NSAssert(currentView, @"current view must not be nil");

  XCTAssertNil(weakFlutterTextInputPlugin);
  // Verify that the view can no longer access the deallocated engine/text input plugin
  // instance.
  XCTAssertNil(currentView.textInputDelegate);
}

- (void)testSecureInput {
  NSDictionary* config = self.mutableTemplateCopy;
  [config setValue:@"YES" forKey:@"obscureText"];
  [self setClientId:123 configuration:config];

  // Find all the FlutterTextInputViews we created.
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;

  // There are no autofill and the mock framework requested a secure entry. The first and only
  // inserted FlutterTextInputView should be a secure text entry one.
  FlutterTextInputView* inputView = inputFields[0];

  // Verify secureTextEntry is set to the correct value.
  XCTAssertTrue(inputView.secureTextEntry);

  // Verify keyboardType is set to the default value.
  XCTAssertEqual(inputView.keyboardType, UIKeyboardTypeDefault);

  // We should have only ever created one FlutterTextInputView.
  XCTAssertEqual(inputFields.count, 1ul);

  // The one FlutterTextInputView we inserted into the view hierarchy should be the text input
  // plugin's active text input view.
  XCTAssertEqual(inputView, textInputPlugin.textInputView);

  // Despite not given an id in configuration, inputView has
  // an autofill id.
  XCTAssert(inputView.autofillId.length > 0);
}

- (void)testKeyboardType {
  NSDictionary* config = self.mutableTemplateCopy;
  [config setValue:@{@"name" : @"TextInputType.url"} forKey:@"inputType"];
  [self setClientId:123 configuration:config];

  // Find all the FlutterTextInputViews we created.
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;

  FlutterTextInputView* inputView = inputFields[0];

  // Verify keyboardType is set to the value specified in config.
  XCTAssertEqual(inputView.keyboardType, UIKeyboardTypeURL);
}

- (void)testVisiblePasswordUseAlphanumeric {
  NSDictionary* config = self.mutableTemplateCopy;
  [config setValue:@{@"name" : @"TextInputType.visiblePassword"} forKey:@"inputType"];
  [self setClientId:123 configuration:config];

  // Find all the FlutterTextInputViews we created.
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;

  FlutterTextInputView* inputView = inputFields[0];

  // Verify keyboardType is set to the value specified in config.
  XCTAssertEqual(inputView.keyboardType, UIKeyboardTypeASCIICapable);
}

- (void)testSettingKeyboardTypeNoneDisablesSystemKeyboard {
  NSDictionary* config = self.mutableTemplateCopy;
  [config setValue:@{@"name" : @"TextInputType.none"} forKey:@"inputType"];
  [self setClientId:123 configuration:config];

  // Verify the view's inputViewController is not nil;
  XCTAssertNotNil(textInputPlugin.activeView.inputViewController);

  [config setValue:@{@"name" : @"TextInputType.url"} forKey:@"inputType"];
  [self setClientId:124 configuration:config];
  XCTAssertNotNil(textInputPlugin.activeView);
  XCTAssertNil(textInputPlugin.activeView.inputViewController);
}

- (void)testAutocorrectionPromptRectAppearsBeforeIOS17AndDoesNotAppearAfterIOS17 {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView firstRectForRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]];

  if (@available(iOS 17.0, *)) {
    // Auto-correction prompt is disabled in iOS 17+.
    OCMVerify(never(), [engine flutterTextInputView:inputView
                           showAutocorrectionPromptRectForStart:0
                                                            end:1
                                                     withClient:0]);
  } else {
    OCMVerify([engine flutterTextInputView:inputView
        showAutocorrectionPromptRectForStart:0
                                         end:1
                                  withClient:0]);
  }
}

- (void)testIgnoresSelectionChangeIfSelectionIsDisabled {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  __block int updateCount = 0;
  OCMStub([engine flutterTextInputView:inputView updateEditingClient:0 withState:[OCMArg isNotNil]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });

  [inputView.text setString:@"Some initial text"];
  XCTAssertEqual(updateCount, 0);

  FlutterTextRange* textRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)];
  [inputView setSelectedTextRange:textRange];
  XCTAssertEqual(updateCount, 1);

  // Disable the interactive selection.
  NSDictionary* config = self.mutableTemplateCopy;
  [config setValue:@(NO) forKey:@"enableInteractiveSelection"];
  [config setValue:@(NO) forKey:@"obscureText"];
  [config setValue:@(NO) forKey:@"enableDeltaModel"];
  [inputView configureWithDictionary:config];

  textRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(2, 3)];
  [inputView setSelectedTextRange:textRange];
  // The update count does not change.
  XCTAssertEqual(updateCount, 1);
}

- (void)testAutocorrectionPromptRectDoesNotAppearDuringScribble {
  // Auto-correction prompt is disabled in iOS 17+.
  if (@available(iOS 17.0, *)) {
    return;
  }

  if (@available(iOS 14.0, *)) {
    FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];

    __block int callCount = 0;
    OCMStub([engine flutterTextInputView:inputView
                showAutocorrectionPromptRectForStart:0
                                                 end:1
                                          withClient:0])
        .andDo(^(NSInvocation* invocation) {
          callCount++;
        });

    [inputView firstRectForRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]];
    // showAutocorrectionPromptRectForStart fires in response to firstRectForRange
    XCTAssertEqual(callCount, 1);

    UIScribbleInteraction* scribbleInteraction =
        [[UIScribbleInteraction alloc] initWithDelegate:inputView];

    [inputView scribbleInteractionWillBeginWriting:scribbleInteraction];
    [inputView firstRectForRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]];
    // showAutocorrectionPromptRectForStart does not fire in response to setMarkedText during a
    // scribble interaction.firstRectForRange
    XCTAssertEqual(callCount, 1);

    [inputView scribbleInteractionDidFinishWriting:scribbleInteraction];
    [inputView resetScribbleInteractionStatusIfEnding];
    [inputView firstRectForRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]];
    // showAutocorrectionPromptRectForStart fires in response to firstRectForRange.
    XCTAssertEqual(callCount, 2);

    inputView.scribbleFocusStatus = FlutterScribbleFocusStatusFocusing;
    [inputView firstRectForRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]];
    // showAutocorrectionPromptRectForStart does not fire in response to firstRectForRange during a
    // scribble-initiated focus.
    XCTAssertEqual(callCount, 2);

    inputView.scribbleFocusStatus = FlutterScribbleFocusStatusFocused;
    [inputView firstRectForRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]];
    // showAutocorrectionPromptRectForStart does not fire in response to firstRectForRange after a
    // scribble-initiated focus.
    XCTAssertEqual(callCount, 2);

    inputView.scribbleFocusStatus = FlutterScribbleFocusStatusUnfocused;
    [inputView firstRectForRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]];
    // showAutocorrectionPromptRectForStart fires in response to firstRectForRange.
    XCTAssertEqual(callCount, 3);
  }
}

- (void)testInputHiderOverlapWithTextWhenScribbleIsDisabledAfterIOS17AndDoesNotOverlapBeforeIOS17 {
  FlutterTextInputPlugin* myInputPlugin =
      [[FlutterTextInputPlugin alloc] initWithDelegate:OCMClassMock([FlutterEngine class])];

  FlutterMethodCall* setClientCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
                                        arguments:@[ @(123), self.mutableTemplateCopy ]];
  [myInputPlugin handleMethodCall:setClientCall
                           result:^(id _Nullable result){
                           }];

  FlutterTextInputView* mockInputView = OCMPartialMock(myInputPlugin.activeView);
  OCMStub([mockInputView isScribbleAvailable]).andReturn(NO);

  // yOffset = 200.
  NSArray* yOffsetMatrix = @[ @1, @0, @0, @0, @0, @1, @0, @0, @0, @0, @1, @0, @0, @200, @0, @1 ];

  FlutterMethodCall* setPlatformViewClientCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.setEditableSizeAndTransform"
                                        arguments:@{@"transform" : yOffsetMatrix}];
  [myInputPlugin handleMethodCall:setPlatformViewClientCall
                           result:^(id _Nullable result){
                           }];

  if (@available(iOS 17, *)) {
    XCTAssert(CGRectEqualToRect(myInputPlugin.inputHider.frame, CGRectMake(0, 200, 0, 0)),
              @"The input hider should overlap with the text on and after iOS 17");

  } else {
    XCTAssert(CGRectEqualToRect(myInputPlugin.inputHider.frame, CGRectZero),
              @"The input hider should be on the origin of screen on and before iOS 16.");
  }
}

- (void)testTextRangeFromPositionMatchesUITextViewBehavior {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  FlutterTextPosition* fromPosition = [FlutterTextPosition positionWithIndex:2];
  FlutterTextPosition* toPosition = [FlutterTextPosition positionWithIndex:0];

  FlutterTextRange* flutterRange = (FlutterTextRange*)[inputView textRangeFromPosition:fromPosition
                                                                            toPosition:toPosition];
  NSRange range = flutterRange.range;

  XCTAssertEqual(range.location, 0ul);
  XCTAssertEqual(range.length, 2ul);
}

- (void)testTextInRange {
  NSDictionary* config = self.mutableTemplateCopy;
  [config setValue:@{@"name" : @"TextInputType.url"} forKey:@"inputType"];
  [self setClientId:123 configuration:config];
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;
  FlutterTextInputView* inputView = inputFields[0];

  [inputView insertText:@"test"];

  UITextRange* range = [FlutterTextRange rangeWithNSRange:NSMakeRange(0, 20)];
  NSString* substring = [inputView textInRange:range];
  XCTAssertEqual(substring.length, 4ul);

  range = [FlutterTextRange rangeWithNSRange:NSMakeRange(10, 20)];
  substring = [inputView textInRange:range];
  XCTAssertEqual(substring.length, 0ul);
}

- (void)testStandardEditActions {
  NSDictionary* config = self.mutableTemplateCopy;
  [self setClientId:123 configuration:config];
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;
  FlutterTextInputView* inputView = inputFields[0];

  [inputView insertText:@"aaaa"];
  [inputView selectAll:nil];
  [inputView cut:nil];
  [inputView insertText:@"bbbb"];
  XCTAssertTrue([inputView canPerformAction:@selector(paste:) withSender:nil]);
  [inputView paste:nil];
  [inputView selectAll:nil];
  [inputView copy:nil];
  [inputView paste:nil];
  [inputView selectAll:nil];
  [inputView delete:nil];
  [inputView paste:nil];
  [inputView paste:nil];

  UITextRange* range = [FlutterTextRange rangeWithNSRange:NSMakeRange(0, 30)];
  NSString* substring = [inputView textInRange:range];
  XCTAssertEqualObjects(substring, @"bbbbaaaabbbbaaaa");
}

- (void)testDeletingBackward {
  NSDictionary* config = self.mutableTemplateCopy;
  [self setClientId:123 configuration:config];
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;
  FlutterTextInputView* inputView = inputFields[0];

  [inputView insertText:@"ឹ😀 text 🥰👨‍👩‍👧‍👦🇺🇳ดี "];
  [inputView deleteBackward];
  [inputView deleteBackward];

  // Thai vowel is removed.
  XCTAssertEqualObjects(inputView.text, @"ឹ😀 text 🥰👨‍👩‍👧‍👦🇺🇳ด");
  [inputView deleteBackward];
  XCTAssertEqualObjects(inputView.text, @"ឹ😀 text 🥰👨‍👩‍👧‍👦🇺🇳");
  [inputView deleteBackward];
  XCTAssertEqualObjects(inputView.text, @"ឹ😀 text 🥰👨‍👩‍👧‍👦");
  [inputView deleteBackward];
  XCTAssertEqualObjects(inputView.text, @"ឹ😀 text 🥰");
  [inputView deleteBackward];

  XCTAssertEqualObjects(inputView.text, @"ឹ😀 text ");
  [inputView deleteBackward];
  [inputView deleteBackward];
  [inputView deleteBackward];
  [inputView deleteBackward];
  [inputView deleteBackward];
  [inputView deleteBackward];

  XCTAssertEqualObjects(inputView.text, @"ឹ😀");
  [inputView deleteBackward];
  XCTAssertEqualObjects(inputView.text, @"ឹ");
  [inputView deleteBackward];
  XCTAssertEqualObjects(inputView.text, @"");
}

// This tests the workaround to fix an iOS 16 bug
// See: https://github.com/flutter/flutter/issues/111494
- (void)testSystemOnlyAddingPartialComposedCharacter {
  NSDictionary* config = self.mutableTemplateCopy;
  [self setClientId:123 configuration:config];
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;
  FlutterTextInputView* inputView = inputFields[0];

  [inputView insertText:@"👨‍👩‍👧‍👦"];
  [inputView deleteBackward];

  // Insert the first unichar in the emoji.
  [inputView insertText:[@"👨‍👩‍👧‍👦" substringWithRange:NSMakeRange(0, 1)]];
  [inputView insertText:@"아"];

  XCTAssertEqualObjects(inputView.text, @"👨‍👩‍👧‍👦아");

  // Deleting 아.
  [inputView deleteBackward];
  // 👨‍👩‍👧‍👦 should be the current string.

  [inputView insertText:@"😀"];
  [inputView deleteBackward];
  // Insert the first unichar in the emoji.
  [inputView insertText:[@"😀" substringWithRange:NSMakeRange(0, 1)]];
  [inputView insertText:@"아"];
  XCTAssertEqualObjects(inputView.text, @"👨‍👩‍👧‍👦😀아");

  // Deleting 아.
  [inputView deleteBackward];
  // 👨‍👩‍👧‍👦😀 should be the current string.

  [inputView deleteBackward];
  // Insert the first unichar in the emoji.
  [inputView insertText:[@"😀" substringWithRange:NSMakeRange(0, 1)]];
  [inputView insertText:@"아"];

  XCTAssertEqualObjects(inputView.text, @"👨‍👩‍👧‍👦😀아");
}

- (void)testCachedComposedCharacterClearedAtKeyboardInteraction {
  NSDictionary* config = self.mutableTemplateCopy;
  [self setClientId:123 configuration:config];
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;
  FlutterTextInputView* inputView = inputFields[0];

  [inputView insertText:@"👨‍👩‍👧‍👦"];
  [inputView deleteBackward];
  [inputView shouldChangeTextInRange:OCMClassMock([UITextRange class]) replacementText:@""];

  // Insert the first unichar in the emoji.
  NSString* brokenEmoji = [@"👨‍👩‍👧‍👦" substringWithRange:NSMakeRange(0, 1)];
  [inputView insertText:brokenEmoji];
  [inputView insertText:@"아"];

  NSString* finalText = [NSString stringWithFormat:@"%@아", brokenEmoji];
  XCTAssertEqualObjects(inputView.text, finalText);
}

- (void)testPastingNonTextDisallowed {
  NSDictionary* config = self.mutableTemplateCopy;
  [self setClientId:123 configuration:config];
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;
  FlutterTextInputView* inputView = inputFields[0];

  UIPasteboard.generalPasteboard.color = UIColor.redColor;
  XCTAssertNil(UIPasteboard.generalPasteboard.string);
  XCTAssertFalse([inputView canPerformAction:@selector(paste:) withSender:nil]);
  [inputView paste:nil];

  XCTAssertEqualObjects(inputView.text, @"");
}

- (void)testNoZombies {
  // Regression test for https://github.com/flutter/flutter/issues/62501.
  FlutterSecureTextInputView* passwordView =
      [[FlutterSecureTextInputView alloc] initWithOwner:textInputPlugin];

  @autoreleasepool {
    // Initialize the lazy textField.
    [passwordView.textField description];
  }
  XCTAssert([[passwordView.textField description] containsString:@"TextField"]);
}

- (void)testInputViewCrash {
  FlutterTextInputView* activeView = nil;
  @autoreleasepool {
    FlutterEngine* flutterEngine = [[FlutterEngine alloc] init];
    FlutterTextInputPlugin* inputPlugin = [[FlutterTextInputPlugin alloc]
        initWithDelegate:(id<FlutterTextInputDelegate>)flutterEngine];
    activeView = inputPlugin.activeView;
  }
  [activeView updateEditingState];
}

- (void)testDoNotReuseInputViews {
  NSDictionary* config = self.mutableTemplateCopy;
  [self setClientId:123 configuration:config];
  FlutterTextInputView* currentView = textInputPlugin.activeView;
  [self setClientId:456 configuration:config];

  XCTAssertNotNil(currentView);
  XCTAssertNotNil(textInputPlugin.activeView);
  XCTAssertNotEqual(currentView, textInputPlugin.activeView);
}

- (void)ensureOnlyActiveViewCanBecomeFirstResponder {
  for (FlutterTextInputView* inputView in self.installedInputViews) {
    XCTAssertEqual(inputView.canBecomeFirstResponder, inputView == textInputPlugin.activeView);
  }
}

- (void)testPropagatePressEventsToViewController {
  FlutterViewController* mockViewController = OCMPartialMock(viewController);
  OCMStub([mockViewController pressesBegan:[OCMArg isNotNil] withEvent:[OCMArg isNotNil]]);
  OCMStub([mockViewController pressesEnded:[OCMArg isNotNil] withEvent:[OCMArg isNotNil]]);

  textInputPlugin.viewController = mockViewController;

  NSDictionary* config = self.mutableTemplateCopy;
  [self setClientId:123 configuration:config];
  FlutterTextInputView* currentView = textInputPlugin.activeView;
  [self setTextInputShow];

  [currentView pressesBegan:[NSSet setWithObjects:OCMClassMock([UIPress class]), nil]
                  withEvent:OCMClassMock([UIPressesEvent class])];

  OCMVerify(times(1), [mockViewController pressesBegan:[OCMArg isNotNil]
                                             withEvent:[OCMArg isNotNil]]);
  OCMVerify(times(0), [mockViewController pressesEnded:[OCMArg isNotNil]
                                             withEvent:[OCMArg isNotNil]]);

  [currentView pressesEnded:[NSSet setWithObjects:OCMClassMock([UIPress class]), nil]
                  withEvent:OCMClassMock([UIPressesEvent class])];

  OCMVerify(times(1), [mockViewController pressesBegan:[OCMArg isNotNil]
                                             withEvent:[OCMArg isNotNil]]);
  OCMVerify(times(1), [mockViewController pressesEnded:[OCMArg isNotNil]
                                             withEvent:[OCMArg isNotNil]]);
}

- (void)testPropagatePressEventsToViewController2 {
  FlutterViewController* mockViewController = OCMPartialMock(viewController);
  OCMStub([mockViewController pressesBegan:[OCMArg isNotNil] withEvent:[OCMArg isNotNil]]);
  OCMStub([mockViewController pressesEnded:[OCMArg isNotNil] withEvent:[OCMArg isNotNil]]);

  textInputPlugin.viewController = mockViewController;

  NSDictionary* config = self.mutableTemplateCopy;
  [self setClientId:123 configuration:config];
  [self setTextInputShow];
  FlutterTextInputView* currentView = textInputPlugin.activeView;

  [currentView pressesBegan:[NSSet setWithObjects:OCMClassMock([UIPress class]), nil]
                  withEvent:OCMClassMock([UIPressesEvent class])];

  OCMVerify(times(1), [mockViewController pressesBegan:[OCMArg isNotNil]
                                             withEvent:[OCMArg isNotNil]]);
  OCMVerify(times(0), [mockViewController pressesEnded:[OCMArg isNotNil]
                                             withEvent:[OCMArg isNotNil]]);

  // Switch focus to a different view.
  [self setClientId:321 configuration:config];
  [self setTextInputShow];
  NSAssert(textInputPlugin.activeView, @"active view must not be nil");
  NSAssert(textInputPlugin.activeView != currentView, @"active view must change");
  currentView = textInputPlugin.activeView;
  [currentView pressesEnded:[NSSet setWithObjects:OCMClassMock([UIPress class]), nil]
                  withEvent:OCMClassMock([UIPressesEvent class])];

  OCMVerify(times(1), [mockViewController pressesBegan:[OCMArg isNotNil]
                                             withEvent:[OCMArg isNotNil]]);
  OCMVerify(times(1), [mockViewController pressesEnded:[OCMArg isNotNil]
                                             withEvent:[OCMArg isNotNil]]);
}

- (void)testUpdateSecureTextEntry {
  NSDictionary* config = self.mutableTemplateCopy;
  [config setValue:@"YES" forKey:@"obscureText"];
  [self setClientId:123 configuration:config];

  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;
  FlutterTextInputView* inputView = OCMPartialMock(inputFields[0]);

  __block int callCount = 0;
  OCMStub([inputView reloadInputViews]).andDo(^(NSInvocation* invocation) {
    callCount++;
  });

  XCTAssertTrue(inputView.isSecureTextEntry);

  config = self.mutableTemplateCopy;
  [config setValue:@"NO" forKey:@"obscureText"];
  [self updateConfig:config];

  XCTAssertEqual(callCount, 1);
  XCTAssertFalse(inputView.isSecureTextEntry);
}

- (void)testInputActionContinueAction {
  id mockBinaryMessenger = OCMClassMock([FlutterBinaryMessengerRelay class]);
  FlutterEngine* testEngine = [[FlutterEngine alloc] init];
  [testEngine setBinaryMessenger:mockBinaryMessenger];
  [testEngine runWithEntrypoint:FlutterDefaultDartEntrypoint initialRoute:@"test"];

  FlutterTextInputPlugin* inputPlugin =
      [[FlutterTextInputPlugin alloc] initWithDelegate:(id<FlutterTextInputDelegate>)testEngine];
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:inputPlugin];

  [testEngine flutterTextInputView:inputView
                     performAction:FlutterTextInputActionContinue
                        withClient:123];

  FlutterMethodCall* methodCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInputClient.performAction"
                                        arguments:@[ @(123), @"TextInputAction.continueAction" ]];
  NSData* encodedMethodCall = [[FlutterJSONMethodCodec sharedInstance] encodeMethodCall:methodCall];
  OCMVerify([mockBinaryMessenger sendOnChannel:@"flutter/textinput" message:encodedMethodCall]);
}

- (void)testDisablingAutocorrectDisablesSpellChecking {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];

  // Disable the interactive selection.
  NSDictionary* config = self.mutableTemplateCopy;
  [inputView configureWithDictionary:config];

  XCTAssertEqual(inputView.autocorrectionType, UITextAutocorrectionTypeDefault);
  XCTAssertEqual(inputView.spellCheckingType, UITextSpellCheckingTypeDefault);

  [config setValue:@(NO) forKey:@"autocorrect"];
  [inputView configureWithDictionary:config];

  XCTAssertEqual(inputView.autocorrectionType, UITextAutocorrectionTypeNo);
  XCTAssertEqual(inputView.spellCheckingType, UITextSpellCheckingTypeNo);
}

- (void)testReplaceTestLocalAdjustSelectionAndMarkedTextRange {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setMarkedText:@"test text" selectedRange:NSMakeRange(0, 5)];
  NSRange selectedTextRange = ((FlutterTextRange*)inputView.selectedTextRange).range;
  const NSRange markedTextRange = ((FlutterTextRange*)inputView.markedTextRange).range;
  XCTAssertEqual(selectedTextRange.location, 0ul);
  XCTAssertEqual(selectedTextRange.length, 5ul);
  XCTAssertEqual(markedTextRange.location, 0ul);
  XCTAssertEqual(markedTextRange.length, 9ul);

  // Replaces space with space.
  [inputView replaceRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(4, 1)] withText:@" "];
  selectedTextRange = ((FlutterTextRange*)inputView.selectedTextRange).range;

  XCTAssertEqual(selectedTextRange.location, 5ul);
  XCTAssertEqual(selectedTextRange.length, 0ul);
  XCTAssertEqual(inputView.markedTextRange, nil);
}

- (void)testFlutterTextInputViewOnlyRespondsToInsertionPointColorBelowIOS17 {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  BOOL respondsToInsertionPointColor =
      [inputView respondsToSelector:@selector(insertionPointColor)];
  if (@available(iOS 17, *)) {
    XCTAssertFalse(respondsToInsertionPointColor);
  } else {
    XCTAssertTrue(respondsToInsertionPointColor);
  }
}

#pragma mark - TextEditingDelta tests
- (void)testTextEditingDeltasAreGeneratedOnTextInput {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  inputView.enableDeltaModel = YES;

  __block int updateCount = 0;

  [inputView insertText:@"text to insert"];
  OCMExpect(
      [engine
          flutterTextInputView:inputView
           updateEditingClient:0
                     withDelta:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                       return ([[state[@"deltas"] objectAtIndex:0][@"oldText"]
                                  isEqualToString:@""]) &&
                              ([[state[@"deltas"] objectAtIndex:0][@"deltaText"]
                                  isEqualToString:@"text to insert"]) &&
                              ([[state[@"deltas"] objectAtIndex:0][@"deltaStart"] intValue] == 0) &&
                              ([[state[@"deltas"] objectAtIndex:0][@"deltaEnd"] intValue] == 0);
                     }]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });
  XCTAssertEqual(updateCount, 0);

  [self flushScheduledAsyncBlocks];

  // Update the framework exactly once.
  XCTAssertEqual(updateCount, 1);

  [inputView deleteBackward];
  OCMExpect([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withDelta:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                                 return ([[state[@"deltas"] objectAtIndex:0][@"oldText"]
                                            isEqualToString:@"text to insert"]) &&
                                        ([[state[@"deltas"] objectAtIndex:0][@"deltaText"]
                                            isEqualToString:@""]) &&
                                        ([[state[@"deltas"] objectAtIndex:0][@"deltaStart"]
                                             intValue] == 13) &&
                                        ([[state[@"deltas"] objectAtIndex:0][@"deltaEnd"]
                                             intValue] == 14);
                               }]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 2);

  inputView.selectedTextRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)];
  OCMExpect([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withDelta:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                                 return ([[state[@"deltas"] objectAtIndex:0][@"oldText"]
                                            isEqualToString:@"text to inser"]) &&
                                        ([[state[@"deltas"] objectAtIndex:0][@"deltaText"]
                                            isEqualToString:@""]) &&
                                        ([[state[@"deltas"] objectAtIndex:0][@"deltaStart"]
                                             intValue] == -1) &&
                                        ([[state[@"deltas"] objectAtIndex:0][@"deltaEnd"]
                                             intValue] == -1);
                               }]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 3);

  [inputView replaceRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]
                 withText:@"replace text"];
  OCMExpect(
      [engine
          flutterTextInputView:inputView
           updateEditingClient:0
                     withDelta:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                       return ([[state[@"deltas"] objectAtIndex:0][@"oldText"]
                                  isEqualToString:@"text to inser"]) &&
                              ([[state[@"deltas"] objectAtIndex:0][@"deltaText"]
                                  isEqualToString:@"replace text"]) &&
                              ([[state[@"deltas"] objectAtIndex:0][@"deltaStart"] intValue] == 0) &&
                              ([[state[@"deltas"] objectAtIndex:0][@"deltaEnd"] intValue] == 1);
                     }]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 4);

  [inputView setMarkedText:@"marked text" selectedRange:NSMakeRange(0, 1)];
  OCMExpect([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withDelta:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                                 return ([[state[@"deltas"] objectAtIndex:0][@"oldText"]
                                            isEqualToString:@"replace textext to inser"]) &&
                                        ([[state[@"deltas"] objectAtIndex:0][@"deltaText"]
                                            isEqualToString:@"marked text"]) &&
                                        ([[state[@"deltas"] objectAtIndex:0][@"deltaStart"]
                                             intValue] == 12) &&
                                        ([[state[@"deltas"] objectAtIndex:0][@"deltaEnd"]
                                             intValue] == 12);
                               }]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 5);

  [inputView unmarkText];
  OCMExpect([engine
                flutterTextInputView:inputView
                 updateEditingClient:0
                           withDelta:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                             return ([[state[@"deltas"] objectAtIndex:0][@"oldText"]
                                        isEqualToString:@"replace textmarked textext to inser"]) &&
                                    ([[state[@"deltas"] objectAtIndex:0][@"deltaText"]
                                        isEqualToString:@""]) &&
                                    ([[state[@"deltas"] objectAtIndex:0][@"deltaStart"] intValue] ==
                                     -1) &&
                                    ([[state[@"deltas"] objectAtIndex:0][@"deltaEnd"] intValue] ==
                                     -1);
                           }]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });
  [self flushScheduledAsyncBlocks];

  XCTAssertEqual(updateCount, 6);
  OCMVerifyAll(engine);
}

- (void)testTextEditingDeltasAreBatchedAndForwardedToFramework {
  // Setup
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  inputView.enableDeltaModel = YES;

  // Expected call.
  OCMExpect([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withDelta:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                                 NSArray* deltas = state[@"deltas"];
                                 NSDictionary* firstDelta = deltas[0];
                                 NSDictionary* secondDelta = deltas[1];
                                 NSDictionary* thirdDelta = deltas[2];
                                 return [firstDelta[@"oldText"] isEqualToString:@""] &&
                                        [firstDelta[@"deltaText"] isEqualToString:@"-"] &&
                                        [firstDelta[@"deltaStart"] intValue] == 0 &&
                                        [firstDelta[@"deltaEnd"] intValue] == 0 &&
                                        [secondDelta[@"oldText"] isEqualToString:@"-"] &&
                                        [secondDelta[@"deltaText"] isEqualToString:@""] &&
                                        [secondDelta[@"deltaStart"] intValue] == 0 &&
                                        [secondDelta[@"deltaEnd"] intValue] == 1 &&
                                        [thirdDelta[@"oldText"] isEqualToString:@""] &&
                                        [thirdDelta[@"deltaText"] isEqualToString:@"—"] &&
                                        [thirdDelta[@"deltaStart"] intValue] == 0 &&
                                        [thirdDelta[@"deltaEnd"] intValue] == 0;
                               }]]);

  // Simulate user input.
  [inputView insertText:@"-"];
  [inputView deleteBackward];
  [inputView insertText:@"—"];

  [self flushScheduledAsyncBlocks];
  OCMVerifyAll(engine);
}

- (void)testTextEditingDeltasAreGeneratedOnSetMarkedTextReplacement {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  inputView.enableDeltaModel = YES;

  __block int updateCount = 0;
  OCMStub([engine flutterTextInputView:inputView updateEditingClient:0 withDelta:[OCMArg isNotNil]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });

  [inputView.text setString:@"Some initial text"];
  XCTAssertEqual(updateCount, 0);

  UITextRange* range = [FlutterTextRange rangeWithNSRange:NSMakeRange(13, 4)];
  inputView.markedTextRange = range;
  inputView.selectedTextRange = nil;
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 1);

  [inputView setMarkedText:@"new marked text." selectedRange:NSMakeRange(0, 1)];
  OCMVerify([engine
      flutterTextInputView:inputView
       updateEditingClient:0
                 withDelta:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                   return ([[state[@"deltas"] objectAtIndex:0][@"oldText"]
                              isEqualToString:@"Some initial text"]) &&
                          ([[state[@"deltas"] objectAtIndex:0][@"deltaText"]
                              isEqualToString:@"new marked text."]) &&
                          ([[state[@"deltas"] objectAtIndex:0][@"deltaStart"] intValue] == 13) &&
                          ([[state[@"deltas"] objectAtIndex:0][@"deltaEnd"] intValue] == 17);
                 }]]);
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 2);
}

- (void)testTextEditingDeltasAreGeneratedOnSetMarkedTextInsertion {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  inputView.enableDeltaModel = YES;

  __block int updateCount = 0;
  OCMStub([engine flutterTextInputView:inputView updateEditingClient:0 withDelta:[OCMArg isNotNil]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });

  [inputView.text setString:@"Some initial text"];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 0);

  UITextRange* range = [FlutterTextRange rangeWithNSRange:NSMakeRange(13, 4)];
  inputView.markedTextRange = range;
  inputView.selectedTextRange = nil;
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 1);

  [inputView setMarkedText:@"text." selectedRange:NSMakeRange(0, 1)];
  OCMVerify([engine
      flutterTextInputView:inputView
       updateEditingClient:0
                 withDelta:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                   return ([[state[@"deltas"] objectAtIndex:0][@"oldText"]
                              isEqualToString:@"Some initial text"]) &&
                          ([[state[@"deltas"] objectAtIndex:0][@"deltaText"]
                              isEqualToString:@"text."]) &&
                          ([[state[@"deltas"] objectAtIndex:0][@"deltaStart"] intValue] == 13) &&
                          ([[state[@"deltas"] objectAtIndex:0][@"deltaEnd"] intValue] == 17);
                 }]]);
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 2);
}

- (void)testTextEditingDeltasAreGeneratedOnSetMarkedTextDeletion {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  inputView.enableDeltaModel = YES;

  __block int updateCount = 0;
  OCMStub([engine flutterTextInputView:inputView updateEditingClient:0 withDelta:[OCMArg isNotNil]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });

  [inputView.text setString:@"Some initial text"];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 0);

  UITextRange* range = [FlutterTextRange rangeWithNSRange:NSMakeRange(13, 4)];
  inputView.markedTextRange = range;
  inputView.selectedTextRange = nil;
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 1);

  [inputView setMarkedText:@"tex" selectedRange:NSMakeRange(0, 1)];
  OCMVerify([engine
      flutterTextInputView:inputView
       updateEditingClient:0
                 withDelta:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                   return ([[state[@"deltas"] objectAtIndex:0][@"oldText"]
                              isEqualToString:@"Some initial text"]) &&
                          ([[state[@"deltas"] objectAtIndex:0][@"deltaText"]
                              isEqualToString:@"tex"]) &&
                          ([[state[@"deltas"] objectAtIndex:0][@"deltaStart"] intValue] == 13) &&
                          ([[state[@"deltas"] objectAtIndex:0][@"deltaEnd"] intValue] == 17);
                 }]]);
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 2);
}

#pragma mark - EditingState tests

- (void)testUITextInputCallsUpdateEditingStateOnce {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];

  __block int updateCount = 0;
  OCMStub([engine flutterTextInputView:inputView updateEditingClient:0 withState:[OCMArg isNotNil]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });

  [inputView insertText:@"text to insert"];
  // Update the framework exactly once.
  XCTAssertEqual(updateCount, 1);

  [inputView deleteBackward];
  XCTAssertEqual(updateCount, 2);

  inputView.selectedTextRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)];
  XCTAssertEqual(updateCount, 3);

  [inputView replaceRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]
                 withText:@"replace text"];
  XCTAssertEqual(updateCount, 4);

  [inputView setMarkedText:@"marked text" selectedRange:NSMakeRange(0, 1)];
  XCTAssertEqual(updateCount, 5);

  [inputView unmarkText];
  XCTAssertEqual(updateCount, 6);
}

- (void)testUITextInputCallsUpdateEditingStateWithDeltaOnce {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  inputView.enableDeltaModel = YES;

  __block int updateCount = 0;
  OCMStub([engine flutterTextInputView:inputView updateEditingClient:0 withDelta:[OCMArg isNotNil]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });

  [inputView insertText:@"text to insert"];
  [self flushScheduledAsyncBlocks];
  // Update the framework exactly once.
  XCTAssertEqual(updateCount, 1);

  [inputView deleteBackward];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 2);

  inputView.selectedTextRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 3);

  [inputView replaceRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]
                 withText:@"replace text"];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 4);

  [inputView setMarkedText:@"marked text" selectedRange:NSMakeRange(0, 1)];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 5);

  [inputView unmarkText];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 6);
}

- (void)testTextChangesDoNotTriggerUpdateEditingClient {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];

  __block int updateCount = 0;
  OCMStub([engine flutterTextInputView:inputView updateEditingClient:0 withState:[OCMArg isNotNil]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });

  [inputView.text setString:@"BEFORE"];
  XCTAssertEqual(updateCount, 0);

  inputView.markedTextRange = nil;
  inputView.selectedTextRange = nil;
  XCTAssertEqual(updateCount, 1);

  // Text changes don't trigger an update.
  XCTAssertEqual(updateCount, 1);
  [inputView setTextInputState:@{@"text" : @"AFTER"}];
  XCTAssertEqual(updateCount, 1);
  [inputView setTextInputState:@{@"text" : @"AFTER"}];
  XCTAssertEqual(updateCount, 1);

  // Selection changes don't trigger an update.
  [inputView
      setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @0, @"selectionExtent" : @3}];
  XCTAssertEqual(updateCount, 1);
  [inputView
      setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @1, @"selectionExtent" : @3}];
  XCTAssertEqual(updateCount, 1);

  // Composing region changes don't trigger an update.
  [inputView
      setTextInputState:@{@"text" : @"COMPOSING", @"composingBase" : @1, @"composingExtent" : @2}];
  XCTAssertEqual(updateCount, 1);
  [inputView
      setTextInputState:@{@"text" : @"COMPOSING", @"composingBase" : @1, @"composingExtent" : @3}];
  XCTAssertEqual(updateCount, 1);
}

- (void)testTextChangesDoNotTriggerUpdateEditingClientWithDelta {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  inputView.enableDeltaModel = YES;

  __block int updateCount = 0;
  OCMStub([engine flutterTextInputView:inputView updateEditingClient:0 withDelta:[OCMArg isNotNil]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });

  [inputView.text setString:@"BEFORE"];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 0);

  inputView.markedTextRange = nil;
  inputView.selectedTextRange = nil;
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 1);

  // Text changes don't trigger an update.
  XCTAssertEqual(updateCount, 1);
  [inputView setTextInputState:@{@"text" : @"AFTER"}];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 1);

  [inputView setTextInputState:@{@"text" : @"AFTER"}];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 1);

  // Selection changes don't trigger an update.
  [inputView
      setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @0, @"selectionExtent" : @3}];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 1);

  [inputView
      setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @1, @"selectionExtent" : @3}];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 1);

  // Composing region changes don't trigger an update.
  [inputView
      setTextInputState:@{@"text" : @"COMPOSING", @"composingBase" : @1, @"composingExtent" : @2}];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 1);

  [inputView
      setTextInputState:@{@"text" : @"COMPOSING", @"composingBase" : @1, @"composingExtent" : @3}];
  [self flushScheduledAsyncBlocks];
  XCTAssertEqual(updateCount, 1);
}

- (void)testUITextInputAvoidUnnecessaryUndateEditingClientCalls {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];

  __block int updateCount = 0;
  OCMStub([engine flutterTextInputView:inputView updateEditingClient:0 withState:[OCMArg isNotNil]])
      .andDo(^(NSInvocation* invocation) {
        updateCount++;
      });

  [inputView unmarkText];
  // updateEditingClient shouldn't fire as the text is already unmarked.
  XCTAssertEqual(updateCount, 0);

  [inputView setMarkedText:@"marked text" selectedRange:NSMakeRange(0, 1)];
  // updateEditingClient fires in response to setMarkedText.
  XCTAssertEqual(updateCount, 1);

  [inputView unmarkText];
  // updateEditingClient fires in response to unmarkText.
  XCTAssertEqual(updateCount, 2);
}

- (void)testCanCopyPasteWithScribbleEnabled {
  if (@available(iOS 14.0, *)) {
    NSDictionary* config = self.mutableTemplateCopy;
    [self setClientId:123 configuration:config];
    NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;
    FlutterTextInputView* inputView = inputFields[0];

    FlutterTextInputView* mockInputView = OCMPartialMock(inputView);
    OCMStub([mockInputView isScribbleAvailable]).andReturn(YES);

    [mockInputView insertText:@"aaaa"];
    [mockInputView selectAll:nil];

    XCTAssertTrue([mockInputView canPerformAction:@selector(copy:) withSender:NULL]);
    XCTAssertTrue([mockInputView canPerformAction:@selector(copy:) withSender:@"sender"]);
    XCTAssertFalse([mockInputView canPerformAction:@selector(paste:) withSender:NULL]);
    XCTAssertFalse([mockInputView canPerformAction:@selector(paste:) withSender:@"sender"]);

    [mockInputView copy:NULL];
    XCTAssertTrue([mockInputView canPerformAction:@selector(copy:) withSender:NULL]);
    XCTAssertTrue([mockInputView canPerformAction:@selector(copy:) withSender:@"sender"]);
    XCTAssertTrue([mockInputView canPerformAction:@selector(paste:) withSender:NULL]);
    XCTAssertTrue([mockInputView canPerformAction:@selector(paste:) withSender:@"sender"]);
  }
}

- (void)testSetMarkedTextDuringScribbleDoesNotTriggerUpdateEditingClient {
  if (@available(iOS 14.0, *)) {
    FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];

    __block int updateCount = 0;
    OCMStub([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withState:[OCMArg isNotNil]])
        .andDo(^(NSInvocation* invocation) {
          updateCount++;
        });

    [inputView setMarkedText:@"marked text" selectedRange:NSMakeRange(0, 1)];
    // updateEditingClient fires in response to setMarkedText.
    XCTAssertEqual(updateCount, 1);

    UIScribbleInteraction* scribbleInteraction =
        [[UIScribbleInteraction alloc] initWithDelegate:inputView];

    [inputView scribbleInteractionWillBeginWriting:scribbleInteraction];
    [inputView setMarkedText:@"during writing" selectedRange:NSMakeRange(1, 2)];
    // updateEditingClient does not fire in response to setMarkedText during a scribble interaction.
    XCTAssertEqual(updateCount, 1);

    [inputView scribbleInteractionDidFinishWriting:scribbleInteraction];
    [inputView resetScribbleInteractionStatusIfEnding];
    [inputView setMarkedText:@"marked text" selectedRange:NSMakeRange(0, 1)];
    // updateEditingClient fires in response to setMarkedText.
    XCTAssertEqual(updateCount, 2);

    inputView.scribbleFocusStatus = FlutterScribbleFocusStatusFocusing;
    [inputView setMarkedText:@"during focus" selectedRange:NSMakeRange(1, 2)];
    // updateEditingClient does not fire in response to setMarkedText during a scribble-initiated
    // focus.
    XCTAssertEqual(updateCount, 2);

    inputView.scribbleFocusStatus = FlutterScribbleFocusStatusFocused;
    [inputView setMarkedText:@"after focus" selectedRange:NSMakeRange(2, 3)];
    // updateEditingClient does not fire in response to setMarkedText after a scribble-initiated
    // focus.
    XCTAssertEqual(updateCount, 2);

    inputView.scribbleFocusStatus = FlutterScribbleFocusStatusUnfocused;
    [inputView setMarkedText:@"marked text" selectedRange:NSMakeRange(0, 1)];
    // updateEditingClient fires in response to setMarkedText.
    XCTAssertEqual(updateCount, 3);
  }
}

- (void)testUpdateEditingClientNegativeSelection {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];

  [inputView.text setString:@"SELECTION"];
  inputView.markedTextRange = nil;
  inputView.selectedTextRange = nil;

  [inputView setTextInputState:@{
    @"text" : @"SELECTION",
    @"selectionBase" : @-1,
    @"selectionExtent" : @-1
  }];
  [inputView updateEditingState];
  OCMVerify([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withState:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                                 return ([state[@"selectionBase"] intValue]) == 0 &&
                                        ([state[@"selectionExtent"] intValue] == 0);
                               }]]);

  // Returns (0, 0) when either end goes below 0.
  [inputView
      setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @-1, @"selectionExtent" : @1}];
  [inputView updateEditingState];
  OCMVerify([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withState:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                                 return ([state[@"selectionBase"] intValue]) == 0 &&
                                        ([state[@"selectionExtent"] intValue] == 0);
                               }]]);

  [inputView
      setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @1, @"selectionExtent" : @-1}];
  [inputView updateEditingState];
  OCMVerify([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withState:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                                 return ([state[@"selectionBase"] intValue]) == 0 &&
                                        ([state[@"selectionExtent"] intValue] == 0);
                               }]]);
}

- (void)testUpdateEditingClientSelectionClamping {
  // Regression test for https://github.com/flutter/flutter/issues/62992.
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];

  [inputView.text setString:@"SELECTION"];
  inputView.markedTextRange = nil;
  inputView.selectedTextRange = nil;

  [inputView
      setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @0, @"selectionExtent" : @0}];
  [inputView updateEditingState];
  OCMVerify([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withState:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                                 return ([state[@"selectionBase"] intValue]) == 0 &&
                                        ([state[@"selectionExtent"] intValue] == 0);
                               }]]);

  // Needs clamping.
  [inputView setTextInputState:@{
    @"text" : @"SELECTION",
    @"selectionBase" : @0,
    @"selectionExtent" : @9999
  }];
  [inputView updateEditingState];

  OCMVerify([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withState:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                                 return ([state[@"selectionBase"] intValue]) == 0 &&
                                        ([state[@"selectionExtent"] intValue] == 9);
                               }]]);

  // No clamping needed, but in reverse direction.
  [inputView
      setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @1, @"selectionExtent" : @0}];
  [inputView updateEditingState];
  OCMVerify([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withState:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                                 return ([state[@"selectionBase"] intValue]) == 0 &&
                                        ([state[@"selectionExtent"] intValue] == 1);
                               }]]);

  // Both ends need clamping.
  [inputView setTextInputState:@{
    @"text" : @"SELECTION",
    @"selectionBase" : @9999,
    @"selectionExtent" : @9999
  }];
  [inputView updateEditingState];
  OCMVerify([engine flutterTextInputView:inputView
                     updateEditingClient:0
                               withState:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                                 return ([state[@"selectionBase"] intValue]) == 9 &&
                                        ([state[@"selectionExtent"] intValue] == 9);
                               }]]);
}

- (void)testInputViewsHasNonNilInputDelegate {
  if (@available(iOS 13.0, *)) {
    FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
    [UIApplication.sharedApplication.keyWindow addSubview:inputView];

    [inputView setTextInputClient:123];
    [inputView reloadInputViews];
    [inputView becomeFirstResponder];
    NSAssert(inputView.isFirstResponder, @"inputView is not first responder");
    inputView.inputDelegate = nil;

    FlutterTextInputView* mockInputView = OCMPartialMock(inputView);
    [mockInputView setTextInputState:@{
      @"text" : @"COMPOSING",
      @"composingBase" : @1,
      @"composingExtent" : @3
    }];
    OCMVerify([mockInputView setInputDelegate:[OCMArg isNotNil]]);
    [inputView removeFromSuperview];
  }
}

- (void)testInputViewsDoNotHaveUITextInteractions {
  if (@available(iOS 13.0, *)) {
    FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
    BOOL hasTextInteraction = NO;
    for (id interaction in inputView.interactions) {
      hasTextInteraction = [interaction isKindOfClass:[UITextInteraction class]];
      if (hasTextInteraction) {
        break;
      }
    }
    XCTAssertFalse(hasTextInteraction);
  }
}

#pragma mark - UITextInput methods - Tests

- (void)testUpdateFirstRectForRange {
  [self setClientId:123 configuration:self.mutableTemplateCopy];

  FlutterTextInputView* inputView = textInputPlugin.activeView;
  textInputPlugin.viewController.view.frame = CGRectMake(0, 0, 0, 0);

  [inputView
      setTextInputState:@{@"text" : @"COMPOSING", @"composingBase" : @1, @"composingExtent" : @3}];

  CGRect kInvalidFirstRect = CGRectMake(-1, -1, 9999, 9999);
  FlutterTextRange* range = [FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)];
  // yOffset = 200.
  NSArray* yOffsetMatrix = @[ @1, @0, @0, @0, @0, @1, @0, @0, @0, @0, @1, @0, @0, @200, @0, @1 ];
  NSArray* zeroMatrix = @[ @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0 ];
  // This matrix can be generated by running this dart code snippet:
  // Matrix4.identity()..scale(3.0)..rotateZ(math.pi/2)..translate(1.0, 2.0,
  // 3.0);
  NSArray* affineMatrix = @[
    @(0.0), @(3.0), @(0.0), @(0.0), @(-3.0), @(0.0), @(0.0), @(0.0), @(0.0), @(0.0), @(3.0), @(0.0),
    @(-6.0), @(3.0), @(9.0), @(1.0)
  ];

  // Invalid since we don't have the transform or the rect.
  XCTAssertTrue(CGRectEqualToRect(kInvalidFirstRect, [inputView firstRectForRange:range]));

  [inputView setEditableTransform:yOffsetMatrix];
  // Invalid since we don't have the rect.
  XCTAssertTrue(CGRectEqualToRect(kInvalidFirstRect, [inputView firstRectForRange:range]));

  // Valid rect and transform.
  CGRect testRect = CGRectMake(0, 0, 100, 100);
  [inputView setMarkedRect:testRect];

  CGRect finalRect = CGRectOffset(testRect, 0, 200);
  XCTAssertTrue(CGRectEqualToRect(finalRect, [inputView firstRectForRange:range]));
  // Idempotent.
  XCTAssertTrue(CGRectEqualToRect(finalRect, [inputView firstRectForRange:range]));

  // Use an invalid matrix:
  [inputView setEditableTransform:zeroMatrix];
  // Invalid matrix is invalid.
  XCTAssertTrue(CGRectEqualToRect(kInvalidFirstRect, [inputView firstRectForRange:range]));
  XCTAssertTrue(CGRectEqualToRect(kInvalidFirstRect, [inputView firstRectForRange:range]));

  // Revert the invalid matrix change.
  [inputView setEditableTransform:yOffsetMatrix];
  [inputView setMarkedRect:testRect];
  XCTAssertTrue(CGRectEqualToRect(finalRect, [inputView firstRectForRange:range]));

  // Use an invalid rect:
  [inputView setMarkedRect:kInvalidFirstRect];
  // Invalid marked rect is invalid.
  XCTAssertTrue(CGRectEqualToRect(kInvalidFirstRect, [inputView firstRectForRange:range]));
  XCTAssertTrue(CGRectEqualToRect(kInvalidFirstRect, [inputView firstRectForRange:range]));

  // Use a 3d affine transform that does 3d-scaling, z-index rotating and 3d translation.
  [inputView setEditableTransform:affineMatrix];
  [inputView setMarkedRect:testRect];
  XCTAssertTrue(
      CGRectEqualToRect(CGRectMake(-306, 3, 300, 300), [inputView firstRectForRange:range]));

  NSAssert(inputView.superview, @"inputView is not in the view hierarchy!");
  const CGPoint offset = CGPointMake(113, 119);
  CGRect currentFrame = inputView.frame;
  currentFrame.origin = offset;
  inputView.frame = currentFrame;
  // Moving the input view within the FlutterView shouldn't affect the coordinates,
  // since the framework sends us global coordinates.
  XCTAssertTrue(CGRectEqualToRect(CGRectMake(-306 - 113, 3 - 119, 300, 300),
                                  [inputView firstRectForRange:range]));
}

- (void)testFirstRectForRangeReturnsNoneZeroRectWhenScribbleIsEnabled {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  FlutterTextInputView* mockInputView = OCMPartialMock(inputView);
  OCMStub([mockInputView isScribbleAvailable]).andReturn(YES);

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 0, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 0, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 0, 100, 100) position:3U],
  ]];

  FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 3)];

  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(100, 0, 300, 100),
                                    [inputView firstRectForRange:multiRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(100, 0, 100, 100),
                                    [inputView firstRectForRange:multiRectRange]));
  }
}

- (void)testFirstRectForRangeReturnsCorrectRectOnASingleLineLeftToRight {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 0, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 0, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 0, 100, 100) position:3U],
  ]];
  FlutterTextRange* singleRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 1)];
  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(100, 0, 100, 100),
                                    [inputView firstRectForRange:singleRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:singleRectRange]));
  }

  FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 3)];

  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(100, 0, 300, 100),
                                    [inputView firstRectForRange:multiRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:multiRectRange]));
  }

  [inputView setTextInputState:@{@"text" : @"COM"}];
  FlutterTextRange* rangeOutsideBounds = [FlutterTextRange rangeWithNSRange:NSMakeRange(3, 1)];
  XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:rangeOutsideBounds]));
}

- (void)testFirstRectForRangeReturnsCorrectRectOnASingleLineRightToLeft {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 0, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 0, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:3U],
  ]];
  FlutterTextRange* singleRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 1)];
  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(200, 0, 100, 100),
                                    [inputView firstRectForRange:singleRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:singleRectRange]));
  }

  FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 3)];
  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(0, 0, 300, 100),
                                    [inputView firstRectForRange:multiRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:multiRectRange]));
  }

  [inputView setTextInputState:@{@"text" : @"COM"}];
  FlutterTextRange* rangeOutsideBounds = [FlutterTextRange rangeWithNSRange:NSMakeRange(3, 1)];
  XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:rangeOutsideBounds]));
}

- (void)testFirstRectForRangeReturnsCorrectRectOnMultipleLinesLeftToRight {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 0, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 0, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 0, 100, 100) position:3U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 100, 100, 100) position:4U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 100, 100, 100) position:5U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 100, 100, 100) position:6U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 100, 100, 100) position:7U],
  ]];
  FlutterTextRange* singleRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 1)];
  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(100, 0, 100, 100),
                                    [inputView firstRectForRange:singleRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:singleRectRange]));
  }

  FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 4)];

  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(100, 0, 300, 100),
                                    [inputView firstRectForRange:multiRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:multiRectRange]));
  }
}

- (void)testFirstRectForRangeReturnsCorrectRectOnMultipleLinesRightToLeft {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 0, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 0, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:3U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 100, 100, 100) position:4U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 100, 100, 100) position:5U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 100, 100, 100) position:6U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 100, 100, 100) position:7U],
  ]];
  FlutterTextRange* singleRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 1)];
  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(200, 0, 100, 100),
                                    [inputView firstRectForRange:singleRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:singleRectRange]));
  }

  FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 4)];
  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(0, 0, 300, 100),
                                    [inputView firstRectForRange:multiRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:multiRectRange]));
  }
}

- (void)testFirstRectForRangeReturnsCorrectRectOnSingleLineWithVaryingMinYAndMaxYLeftToRight {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 10, 100, 80)
                                           position:1U],  // shorter
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, -10, 100, 120)
                                           position:2U],  // taller
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 0, 100, 100) position:3U],
  ]];

  FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 3)];

  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(100, -10, 300, 120),
                                    [inputView firstRectForRange:multiRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:multiRectRange]));
  }
}

- (void)testFirstRectForRangeReturnsCorrectRectOnSingleLineWithVaryingMinYAndMaxYRightToLeft {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, -10, 100, 120)
                                           position:1U],  // taller
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 10, 100, 80)
                                           position:2U],  // shorter
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:3U],
  ]];

  FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 3)];

  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(0, -10, 300, 120),
                                    [inputView firstRectForRange:multiRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:multiRectRange]));
  }
}

- (void)testFirstRectForRangeReturnsCorrectRectWithOverlappingRectsExceedingThresholdLeftToRight {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 0, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 0, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 0, 100, 100) position:3U],
    // y=60 exceeds threshold, so treat it as a new line.
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 60, 100, 100) position:4U],
  ]];

  FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 4)];

  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(100, 0, 300, 100),
                                    [inputView firstRectForRange:multiRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:multiRectRange]));
  }
}

- (void)testFirstRectForRangeReturnsCorrectRectWithOverlappingRectsExceedingThresholdRightToLeft {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 0, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 0, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:3U],
    // y=60 exceeds threshold, so treat it as a new line.
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 60, 100, 100) position:4U],
  ]];

  FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 4)];

  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(0, 0, 300, 100),
                                    [inputView firstRectForRange:multiRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:multiRectRange]));
  }
}

- (void)testFirstRectForRangeReturnsCorrectRectWithOverlappingRectsWithinThresholdLeftToRight {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 0, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 0, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 0, 100, 100) position:3U],
    // y=40 is within line threshold, so treat it as the same line
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(400, 40, 100, 100) position:4U],
  ]];

  FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 4)];

  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(100, 0, 400, 140),
                                    [inputView firstRectForRange:multiRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:multiRectRange]));
  }
}

- (void)testFirstRectForRangeReturnsCorrectRectWithOverlappingRectsWithinThresholdRightToLeft {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(400, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 0, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 0, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 0, 100, 100) position:3U],
    // y=40 is within line threshold, so treat it as the same line
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 40, 100, 100) position:4U],
  ]];

  FlutterTextRange* multiRectRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 4)];

  if (@available(iOS 17, *)) {
    XCTAssertTrue(CGRectEqualToRect(CGRectMake(0, 0, 400, 140),
                                    [inputView firstRectForRange:multiRectRange]));
  } else {
    XCTAssertTrue(CGRectEqualToRect(CGRectZero, [inputView firstRectForRange:multiRectRange]));
  }
}

- (void)testClosestPositionToPoint {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  // Minimize the vertical distance from the center of the rects first
  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 100, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 200, 100, 100) position:2U],
  ]];
  CGPoint point = CGPointMake(150, 150);
  XCTAssertEqual(2U, ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).index);
  XCTAssertEqual(UITextStorageDirectionBackward,
                 ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).affinity);

  // Then, if the point is above the bottom of the closest rects vertically, get the closest x
  // origin
  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 100, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 100, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 100, 100, 100) position:3U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 200, 100, 100) position:4U],
  ]];
  point = CGPointMake(125, 150);
  XCTAssertEqual(2U, ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).index);
  XCTAssertEqual(UITextStorageDirectionForward,
                 ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).affinity);

  // However, if the point is below the bottom of the closest rects vertically, get the position
  // farthest to the right
  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 100, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 100, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 100, 100, 100) position:3U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 300, 100, 100) position:4U],
  ]];
  point = CGPointMake(125, 201);
  XCTAssertEqual(4U, ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).index);
  XCTAssertEqual(UITextStorageDirectionBackward,
                 ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).affinity);

  // Also check a point at the right edge of the last selection rect
  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 100, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 100, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 100, 100, 100) position:3U],
  ]];
  point = CGPointMake(125, 250);
  XCTAssertEqual(4U, ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).index);
  XCTAssertEqual(UITextStorageDirectionBackward,
                 ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).affinity);

  // Minimize vertical distance if the difference is more than 1 point.
  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 2, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 2, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 0, 100, 100) position:2U],
  ]];
  point = CGPointMake(110, 50);
  XCTAssertEqual(2U, ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).index);
  XCTAssertEqual(UITextStorageDirectionForward,
                 ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).affinity);

  // In floating cursor mode, the vertical difference is allowed to be 10 points.
  // The closest horizontal position will now win.
  [inputView beginFloatingCursorAtPoint:CGPointZero];
  XCTAssertEqual(1U, ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).index);
  XCTAssertEqual(UITextStorageDirectionForward,
                 ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).affinity);
  [inputView endFloatingCursor];
}

- (void)testClosestPositionToPointRTL {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 0, 100, 100)
                                           position:0U
                                   writingDirection:NSWritingDirectionRightToLeft],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 0, 100, 100)
                                           position:1U
                                   writingDirection:NSWritingDirectionRightToLeft],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100)
                                           position:2U
                                   writingDirection:NSWritingDirectionRightToLeft],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 100, 100, 100)
                                           position:3U
                                   writingDirection:NSWritingDirectionRightToLeft],
  ]];
  FlutterTextPosition* position =
      (FlutterTextPosition*)[inputView closestPositionToPoint:CGPointMake(275, 50)];
  XCTAssertEqual(0U, position.index);
  XCTAssertEqual(UITextStorageDirectionForward, position.affinity);
  position = (FlutterTextPosition*)[inputView closestPositionToPoint:CGPointMake(225, 50)];
  XCTAssertEqual(1U, position.index);
  XCTAssertEqual(UITextStorageDirectionBackward, position.affinity);
  position = (FlutterTextPosition*)[inputView closestPositionToPoint:CGPointMake(175, 50)];
  XCTAssertEqual(1U, position.index);
  XCTAssertEqual(UITextStorageDirectionForward, position.affinity);
  position = (FlutterTextPosition*)[inputView closestPositionToPoint:CGPointMake(125, 50)];
  XCTAssertEqual(2U, position.index);
  XCTAssertEqual(UITextStorageDirectionBackward, position.affinity);
  position = (FlutterTextPosition*)[inputView closestPositionToPoint:CGPointMake(75, 50)];
  XCTAssertEqual(2U, position.index);
  XCTAssertEqual(UITextStorageDirectionForward, position.affinity);
  position = (FlutterTextPosition*)[inputView closestPositionToPoint:CGPointMake(25, 50)];
  XCTAssertEqual(3U, position.index);
  XCTAssertEqual(UITextStorageDirectionBackward, position.affinity);
  position = (FlutterTextPosition*)[inputView closestPositionToPoint:CGPointMake(-25, 50)];
  XCTAssertEqual(3U, position.index);
  XCTAssertEqual(UITextStorageDirectionBackward, position.affinity);
}

- (void)testSelectionRectsForRange {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  CGRect testRect0 = CGRectMake(100, 100, 100, 100);
  CGRect testRect1 = CGRectMake(200, 200, 100, 100);
  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:testRect0 position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:testRect1 position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 300, 100, 100) position:3U],
  ]];

  // Returns the matching rects within a range
  FlutterTextRange* range = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 2)];
  XCTAssertTrue(CGRectEqualToRect(testRect0, [inputView selectionRectsForRange:range][0].rect));
  XCTAssertTrue(CGRectEqualToRect(testRect1, [inputView selectionRectsForRange:range][1].rect));
  XCTAssertEqual(2U, [[inputView selectionRectsForRange:range] count]);

  // Returns a 0 width rect for a 0-length range
  range = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 0)];
  XCTAssertEqual(1U, [[inputView selectionRectsForRange:range] count]);
  XCTAssertTrue(CGRectEqualToRect(
      CGRectMake(testRect0.origin.x, testRect0.origin.y, 0, testRect0.size.height),
      [inputView selectionRectsForRange:range][0].rect));
}

- (void)testClosestPositionToPointWithinRange {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  // Do not return a position before the start of the range
  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 100, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 100, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 100, 100, 100) position:3U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 200, 100, 100) position:4U],
  ]];
  CGPoint point = CGPointMake(125, 150);
  FlutterTextRange* range = [[FlutterTextRange rangeWithNSRange:NSMakeRange(3, 2)] copy];
  XCTAssertEqual(
      3U, ((FlutterTextPosition*)[inputView closestPositionToPoint:point withinRange:range]).index);
  XCTAssertEqual(
      UITextStorageDirectionForward,
      ((FlutterTextPosition*)[inputView closestPositionToPoint:point withinRange:range]).affinity);

  // Do not return a position after the end of the range
  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 100, 100, 100) position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 100, 100, 100) position:2U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 100, 100, 100) position:3U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 200, 100, 100) position:4U],
  ]];
  point = CGPointMake(125, 150);
  range = [[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)] copy];
  XCTAssertEqual(
      1U, ((FlutterTextPosition*)[inputView closestPositionToPoint:point withinRange:range]).index);
  XCTAssertEqual(
      UITextStorageDirectionForward,
      ((FlutterTextPosition*)[inputView closestPositionToPoint:point withinRange:range]).affinity);
}

- (void)testClosestPositionToPointWithPartialSelectionRects {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{@"text" : @"COMPOSING"}];

  [inputView setSelectionRects:@[ [FlutterTextSelectionRect
                                   selectionRectWithRect:CGRectMake(0, 0, 100, 100)
                                                position:0U] ]];
  // Asking with a position at the end of selection rects should give you the trailing edge of
  // the last rect.
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:1
                                                   affinity:UITextStorageDirectionForward]],
      CGRectMake(100, 0, 0, 100)));
  // Asking with a position beyond the end of selection rects should return CGRectZero without
  // crashing.
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:2
                                                   affinity:UITextStorageDirectionForward]],
      CGRectZero));
}

#pragma mark - Floating Cursor - Tests

- (void)testFloatingCursorDoesNotThrow {
  // The keyboard implementation may send unbalanced calls to the input view.
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView beginFloatingCursorAtPoint:CGPointMake(123, 321)];
  [inputView beginFloatingCursorAtPoint:CGPointMake(123, 321)];
  [inputView endFloatingCursor];
  [inputView beginFloatingCursorAtPoint:CGPointMake(123, 321)];
  [inputView endFloatingCursor];
}

- (void)testFloatingCursor {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView setTextInputState:@{
    @"text" : @"test",
    @"selectionBase" : @1,
    @"selectionExtent" : @1,
  }];

  FlutterTextSelectionRect* first =
      [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U];
  FlutterTextSelectionRect* second =
      [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 100, 100, 100) position:1U];
  FlutterTextSelectionRect* third =
      [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 200, 100, 100) position:2U];
  FlutterTextSelectionRect* fourth =
      [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 300, 100, 100) position:3U];
  [inputView setSelectionRects:@[ first, second, third, fourth ]];

  // Verify zeroth caret rect is based on left edge of first character.
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:0
                                                   affinity:UITextStorageDirectionForward]],
      CGRectMake(0, 0, 0, 100)));
  // Since the textAffinity is downstream, the caret rect will be based on the
  // left edge of the succeeding character.
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:1
                                                   affinity:UITextStorageDirectionForward]],
      CGRectMake(100, 100, 0, 100)));
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:2
                                                   affinity:UITextStorageDirectionForward]],
      CGRectMake(200, 200, 0, 100)));
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:3
                                                   affinity:UITextStorageDirectionForward]],
      CGRectMake(300, 300, 0, 100)));
  // There is no subsequent character for the last position, so the caret rect
  // will be based on the right edge of the preceding character.
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:4
                                                   affinity:UITextStorageDirectionForward]],
      CGRectMake(400, 300, 0, 100)));
  // Verify no caret rect for out-of-range character.
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:5
                                                   affinity:UITextStorageDirectionForward]],
      CGRectZero));

  // Check caret rects again again when text affinity is upstream.
  [inputView setTextInputState:@{
    @"text" : @"test",
    @"selectionBase" : @2,
    @"selectionExtent" : @2,
  }];
  // Verify zeroth caret rect is based on left edge of first character.
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:0
                                                   affinity:UITextStorageDirectionBackward]],
      CGRectMake(0, 0, 0, 100)));
  // Since the textAffinity is upstream, all below caret rects will be based on
  // the right edge of the preceding character.
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:1
                                                   affinity:UITextStorageDirectionBackward]],
      CGRectMake(100, 0, 0, 100)));
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:2
                                                   affinity:UITextStorageDirectionBackward]],
      CGRectMake(200, 100, 0, 100)));
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:3
                                                   affinity:UITextStorageDirectionBackward]],
      CGRectMake(300, 200, 0, 100)));
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:4
                                                   affinity:UITextStorageDirectionBackward]],
      CGRectMake(400, 300, 0, 100)));
  // Verify no caret rect for out-of-range character.
  XCTAssertTrue(CGRectEqualToRect(
      [inputView caretRectForPosition:[FlutterTextPosition
                                          positionWithIndex:5
                                                   affinity:UITextStorageDirectionBackward]],
      CGRectZero));

  // Verify floating cursor updates are relative to original position, and that there is no bounds
  // change.
  CGRect initialBounds = inputView.bounds;
  [inputView beginFloatingCursorAtPoint:CGPointMake(123, 321)];
  XCTAssertTrue(CGRectEqualToRect(initialBounds, inputView.bounds));
  OCMVerify([engine flutterTextInputView:inputView
                    updateFloatingCursor:FlutterFloatingCursorDragStateStart
                              withClient:0
                            withPosition:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                              return ([state[@"X"] isEqualToNumber:@(0)]) &&
                                     ([state[@"Y"] isEqualToNumber:@(0)]);
                            }]]);

  [inputView updateFloatingCursorAtPoint:CGPointMake(456, 654)];
  XCTAssertTrue(CGRectEqualToRect(initialBounds, inputView.bounds));
  OCMVerify([engine flutterTextInputView:inputView
                    updateFloatingCursor:FlutterFloatingCursorDragStateUpdate
                              withClient:0
                            withPosition:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                              return ([state[@"X"] isEqualToNumber:@(333)]) &&
                                     ([state[@"Y"] isEqualToNumber:@(333)]);
                            }]]);

  [inputView endFloatingCursor];
  XCTAssertTrue(CGRectEqualToRect(initialBounds, inputView.bounds));
  OCMVerify([engine flutterTextInputView:inputView
                    updateFloatingCursor:FlutterFloatingCursorDragStateEnd
                              withClient:0
                            withPosition:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
                              return ([state[@"X"] isEqualToNumber:@(0)]) &&
                                     ([state[@"Y"] isEqualToNumber:@(0)]);
                            }]]);
}

#pragma mark - UIKeyInput Overrides - Tests

- (void)testInsertTextAddsPlaceholderSelectionRects {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView
      setTextInputState:@{@"text" : @"test", @"selectionBase" : @1, @"selectionExtent" : @1}];

  FlutterTextSelectionRect* first =
      [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U];
  FlutterTextSelectionRect* second =
      [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(100, 100, 100, 100) position:1U];
  FlutterTextSelectionRect* third =
      [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 200, 100, 100) position:2U];
  FlutterTextSelectionRect* fourth =
      [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(300, 300, 100, 100) position:3U];
  [inputView setSelectionRects:@[ first, second, third, fourth ]];

  // Inserts additional selection rects at the selection start
  [inputView insertText:@"in"];
  NSArray* selectionRects =
      [inputView selectionRectsForRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 6)]];
  XCTAssertEqual(6U, [selectionRects count]);

  XCTAssertEqual(first.position, ((FlutterTextSelectionRect*)selectionRects[0]).position);
  XCTAssertTrue(CGRectEqualToRect(first.rect, ((FlutterTextSelectionRect*)selectionRects[0]).rect));

  XCTAssertEqual(second.position, ((FlutterTextSelectionRect*)selectionRects[1]).position);
  XCTAssertTrue(
      CGRectEqualToRect(second.rect, ((FlutterTextSelectionRect*)selectionRects[1]).rect));

  XCTAssertEqual(second.position + 1, ((FlutterTextSelectionRect*)selectionRects[2]).position);
  XCTAssertTrue(
      CGRectEqualToRect(second.rect, ((FlutterTextSelectionRect*)selectionRects[2]).rect));

  XCTAssertEqual(second.position + 2, ((FlutterTextSelectionRect*)selectionRects[3]).position);
  XCTAssertTrue(
      CGRectEqualToRect(second.rect, ((FlutterTextSelectionRect*)selectionRects[3]).rect));

  XCTAssertEqual(third.position + 2, ((FlutterTextSelectionRect*)selectionRects[4]).position);
  XCTAssertTrue(CGRectEqualToRect(third.rect, ((FlutterTextSelectionRect*)selectionRects[4]).rect));

  XCTAssertEqual(fourth.position + 2, ((FlutterTextSelectionRect*)selectionRects[5]).position);
  XCTAssertTrue(
      CGRectEqualToRect(fourth.rect, ((FlutterTextSelectionRect*)selectionRects[5]).rect));
}

#pragma mark - Autofill - Utilities

- (NSMutableDictionary*)mutablePasswordTemplateCopy {
  if (!_passwordTemplate) {
    _passwordTemplate = @{
      @"inputType" : @{@"name" : @"TextInuptType.text"},
      @"keyboardAppearance" : @"Brightness.light",
      @"obscureText" : @YES,
      @"inputAction" : @"TextInputAction.unspecified",
      @"smartDashesType" : @"0",
      @"smartQuotesType" : @"0",
      @"autocorrect" : @YES
    };
  }

  return [_passwordTemplate mutableCopy];
}

- (NSArray<FlutterTextInputView*>*)viewsVisibleToAutofill {
  return [self.installedInputViews
      filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"isVisibleToAutofill == YES"]];
}

- (void)commitAutofillContextAndVerify {
  FlutterMethodCall* methodCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.finishAutofillContext"
                                        arguments:@YES];
  [textInputPlugin handleMethodCall:methodCall
                             result:^(id _Nullable result){
                             }];

  XCTAssertEqual(self.viewsVisibleToAutofill.count,
                 [textInputPlugin.activeView isVisibleToAutofill] ? 1ul : 0ul);
  XCTAssertNotEqual(textInputPlugin.textInputView, nil);
  // The active view should still be installed so it doesn't get
  // deallocated.
  XCTAssertEqual(self.installedInputViews.count, 1ul);
  XCTAssertEqual(textInputPlugin.autofillContext.count, 0ul);
}

#pragma mark - Autofill - Tests

- (void)testDisablingAutofillOnInputClient {
  NSDictionary* config = self.mutableTemplateCopy;
  [config setValue:@"YES" forKey:@"obscureText"];

  [self setClientId:123 configuration:config];

  FlutterTextInputView* inputView = self.installedInputViews[0];
  XCTAssertEqualObjects(inputView.textContentType, @"");
}

- (void)testAutofillEnabledByDefault {
  NSDictionary* config = self.mutableTemplateCopy;
  [config setValue:@"NO" forKey:@"obscureText"];
  [config setValue:@{@"uniqueIdentifier" : @"field1", @"editingValue" : @{@"text" : @""}}
            forKey:@"autofill"];

  [self setClientId:123 configuration:config];

  FlutterTextInputView* inputView = self.installedInputViews[0];
  XCTAssertNil(inputView.textContentType);
}

- (void)testAutofillContext {
  NSMutableDictionary* field1 = self.mutableTemplateCopy;

  [field1 setValue:@{
    @"uniqueIdentifier" : @"field1",
    @"hints" : @[ @"hint1" ],
    @"editingValue" : @{@"text" : @""}
  }
            forKey:@"autofill"];

  NSMutableDictionary* field2 = self.mutablePasswordTemplateCopy;
  [field2 setValue:@{
    @"uniqueIdentifier" : @"field2",
    @"hints" : @[ @"hint2" ],
    @"editingValue" : @{@"text" : @""}
  }
            forKey:@"autofill"];

  NSMutableDictionary* config = [field1 mutableCopy];
  [config setValue:@[ field1, field2 ] forKey:@"fields"];

  [self setClientId:123 configuration:config];
  XCTAssertEqual(self.viewsVisibleToAutofill.count, 2ul);

  XCTAssertEqual(textInputPlugin.autofillContext.count, 2ul);

  [textInputPlugin cleanUpViewHierarchy:NO clearText:YES delayRemoval:NO];
  XCTAssertEqual(self.installedInputViews.count, 2ul);
  XCTAssertEqual(textInputPlugin.textInputView, textInputPlugin.autofillContext[@"field1"]);
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  // The configuration changes.
  NSMutableDictionary* field3 = self.mutablePasswordTemplateCopy;
  [field3 setValue:@{
    @"uniqueIdentifier" : @"field3",
    @"hints" : @[ @"hint3" ],
    @"editingValue" : @{@"text" : @""}
  }
            forKey:@"autofill"];

  NSMutableDictionary* oldContext = textInputPlugin.autofillContext;
  // Replace field2 with field3.
  [config setValue:@[ field1, field3 ] forKey:@"fields"];

  [self setClientId:123 configuration:config];

  XCTAssertEqual(self.viewsVisibleToAutofill.count, 2ul);
  XCTAssertEqual(textInputPlugin.autofillContext.count, 3ul);

  [textInputPlugin cleanUpViewHierarchy:NO clearText:YES delayRemoval:NO];
  XCTAssertEqual(self.installedInputViews.count, 3ul);
  XCTAssertEqual(textInputPlugin.textInputView, textInputPlugin.autofillContext[@"field1"]);
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  // Old autofill input fields are still installed and reused.
  for (NSString* key in oldContext.allKeys) {
    XCTAssertEqual(oldContext[key], textInputPlugin.autofillContext[key]);
  }

  // Switch to a password field that has no contentType and is not in an AutofillGroup.
  config = self.mutablePasswordTemplateCopy;

  oldContext = textInputPlugin.autofillContext;
  [self setClientId:124 configuration:config];
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  XCTAssertEqual(self.viewsVisibleToAutofill.count, 1ul);
  XCTAssertEqual(textInputPlugin.autofillContext.count, 3ul);

  [textInputPlugin cleanUpViewHierarchy:NO clearText:YES delayRemoval:NO];
  XCTAssertEqual(self.installedInputViews.count, 4ul);

  // Old autofill input fields are still installed and reused.
  for (NSString* key in oldContext.allKeys) {
    XCTAssertEqual(oldContext[key], textInputPlugin.autofillContext[key]);
  }
  // The active view should change.
  XCTAssertNotEqual(textInputPlugin.textInputView, textInputPlugin.autofillContext[@"field1"]);
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  // Switch to a similar password field, the previous field should be reused.
  oldContext = textInputPlugin.autofillContext;
  [self setClientId:200 configuration:config];

  // Reuse the input view instance from the last time.
  XCTAssertEqual(self.viewsVisibleToAutofill.count, 1ul);
  XCTAssertEqual(textInputPlugin.autofillContext.count, 3ul);

  [textInputPlugin cleanUpViewHierarchy:NO clearText:YES delayRemoval:NO];
  XCTAssertEqual(self.installedInputViews.count, 4ul);

  // Old autofill input fields are still installed and reused.
  for (NSString* key in oldContext.allKeys) {
    XCTAssertEqual(oldContext[key], textInputPlugin.autofillContext[key]);
  }
  XCTAssertNotEqual(textInputPlugin.textInputView, textInputPlugin.autofillContext[@"field1"]);
  [self ensureOnlyActiveViewCanBecomeFirstResponder];
}

- (void)testCommitAutofillContext {
  NSMutableDictionary* field1 = self.mutableTemplateCopy;
  [field1 setValue:@{
    @"uniqueIdentifier" : @"field1",
    @"hints" : @[ @"hint1" ],
    @"editingValue" : @{@"text" : @""}
  }
            forKey:@"autofill"];

  NSMutableDictionary* field2 = self.mutablePasswordTemplateCopy;
  [field2 setValue:@{
    @"uniqueIdentifier" : @"field2",
    @"hints" : @[ @"hint2" ],
    @"editingValue" : @{@"text" : @""}
  }
            forKey:@"autofill"];

  NSMutableDictionary* field3 = self.mutableTemplateCopy;
  [field3 setValue:@{
    @"uniqueIdentifier" : @"field3",
    @"hints" : @[ @"hint3" ],
    @"editingValue" : @{@"text" : @""}
  }
            forKey:@"autofill"];

  NSMutableDictionary* config = [field1 mutableCopy];
  [config setValue:@[ field1, field2 ] forKey:@"fields"];

  [self setClientId:123 configuration:config];
  XCTAssertEqual(self.viewsVisibleToAutofill.count, 2ul);
  XCTAssertEqual(textInputPlugin.autofillContext.count, 2ul);
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  [self commitAutofillContextAndVerify];
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  // Install the password field again.
  [self setClientId:123 configuration:config];
  // Switch to a regular autofill group.
  [self setClientId:124 configuration:field3];
  XCTAssertEqual(self.viewsVisibleToAutofill.count, 1ul);

  [textInputPlugin cleanUpViewHierarchy:NO clearText:YES delayRemoval:NO];
  XCTAssertEqual(self.installedInputViews.count, 3ul);
  XCTAssertEqual(textInputPlugin.autofillContext.count, 2ul);
  XCTAssertNotEqual(textInputPlugin.textInputView, nil);
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  [self commitAutofillContextAndVerify];
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  // Now switch to an input field that does not autofill.
  [self setClientId:125 configuration:self.mutableTemplateCopy];

  XCTAssertEqual(self.viewsVisibleToAutofill.count, 0ul);
  // The active view should still be installed so it doesn't get
  // deallocated.

  [textInputPlugin cleanUpViewHierarchy:NO clearText:YES delayRemoval:NO];
  XCTAssertEqual(self.installedInputViews.count, 1ul);
  XCTAssertEqual(textInputPlugin.autofillContext.count, 0ul);
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  [self commitAutofillContextAndVerify];
  [self ensureOnlyActiveViewCanBecomeFirstResponder];
}

- (void)testAutofillInputViews {
  NSMutableDictionary* field1 = self.mutableTemplateCopy;
  [field1 setValue:@{
    @"uniqueIdentifier" : @"field1",
    @"hints" : @[ @"hint1" ],
    @"editingValue" : @{@"text" : @""}
  }
            forKey:@"autofill"];

  NSMutableDictionary* field2 = self.mutablePasswordTemplateCopy;
  [field2 setValue:@{
    @"uniqueIdentifier" : @"field2",
    @"hints" : @[ @"hint2" ],
    @"editingValue" : @{@"text" : @""}
  }
            forKey:@"autofill"];

  NSMutableDictionary* config = [field1 mutableCopy];
  [config setValue:@[ field1, field2 ] forKey:@"fields"];

  [self setClientId:123 configuration:config];
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  // Find all the FlutterTextInputViews we created.
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;

  // Both fields are installed and visible because it's a password group.
  XCTAssertEqual(inputFields.count, 2ul);
  XCTAssertEqual(self.viewsVisibleToAutofill.count, 2ul);

  // Find the inactive autofillable input field.
  FlutterTextInputView* inactiveView = inputFields[1];
  [inactiveView replaceRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 0)]
                    withText:@"Autofilled!"];
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  // Verify behavior.
  OCMVerify([engine flutterTextInputView:inactiveView
                     updateEditingClient:0
                               withState:[OCMArg isNotNil]
                                 withTag:@"field2"]);
}

- (void)testPasswordAutofillHack {
  NSDictionary* config = self.mutableTemplateCopy;
  [config setValue:@"YES" forKey:@"obscureText"];
  [self setClientId:123 configuration:config];

  // Find all the FlutterTextInputViews we created.
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;

  FlutterTextInputView* inputView = inputFields[0];

  XCTAssert([inputView isKindOfClass:[UITextField class]]);
  // FlutterSecureTextInputView does not respond to font,
  // but it should return the default UITextField.font.
  XCTAssertNotEqual([inputView performSelector:@selector(font)], nil);
}

- (void)testClearAutofillContextClearsSelection {
  NSMutableDictionary* regularField = self.mutableTemplateCopy;
  NSDictionary* editingValue = @{
    @"text" : @"REGULAR_TEXT_FIELD",
    @"composingBase" : @0,
    @"composingExtent" : @3,
    @"selectionBase" : @1,
    @"selectionExtent" : @4
  };
  [regularField setValue:@{
    @"uniqueIdentifier" : @"field2",
    @"hints" : @[ @"hint2" ],
    @"editingValue" : editingValue,
  }
                  forKey:@"autofill"];
  [regularField addEntriesFromDictionary:editingValue];
  [self setClientId:123 configuration:regularField];
  [self ensureOnlyActiveViewCanBecomeFirstResponder];
  XCTAssertEqual(self.installedInputViews.count, 1ul);

  FlutterTextInputView* oldInputView = self.installedInputViews[0];
  XCTAssert([oldInputView.text isEqualToString:@"REGULAR_TEXT_FIELD"]);
  FlutterTextRange* selectionRange = (FlutterTextRange*)oldInputView.selectedTextRange;
  XCTAssert(NSEqualRanges(selectionRange.range, NSMakeRange(1, 3)));

  // Replace the original password field with new one. This should remove
  // the old password field, but not immediately.
  [self setClientId:124 configuration:self.mutablePasswordTemplateCopy];
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  XCTAssertEqual(self.installedInputViews.count, 2ul);

  [textInputPlugin cleanUpViewHierarchy:NO clearText:YES delayRemoval:NO];
  XCTAssertEqual(self.installedInputViews.count, 1ul);

  // Verify the old input view is properly cleaned up.
  XCTAssert([oldInputView.text isEqualToString:@""]);
  selectionRange = (FlutterTextRange*)oldInputView.selectedTextRange;
  XCTAssert(NSEqualRanges(selectionRange.range, NSMakeRange(0, 0)));
}

- (void)testGarbageInputViewsAreNotRemovedImmediately {
  // Add a password field that should autofill.
  [self setClientId:123 configuration:self.mutablePasswordTemplateCopy];
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  XCTAssertEqual(self.installedInputViews.count, 1ul);
  // Add an input field that doesn't autofill. This should remove the password
  // field, but not immediately.
  [self setClientId:124 configuration:self.mutableTemplateCopy];
  [self ensureOnlyActiveViewCanBecomeFirstResponder];

  XCTAssertEqual(self.installedInputViews.count, 2ul);

  [self commitAutofillContextAndVerify];
}

- (void)testScribbleSetSelectionRects {
  NSMutableDictionary* regularField = self.mutableTemplateCopy;
  NSDictionary* editingValue = @{
    @"text" : @"REGULAR_TEXT_FIELD",
    @"composingBase" : @0,
    @"composingExtent" : @3,
    @"selectionBase" : @1,
    @"selectionExtent" : @4
  };
  [regularField setValue:@{
    @"uniqueIdentifier" : @"field1",
    @"hints" : @[ @"hint2" ],
    @"editingValue" : editingValue,
  }
                  forKey:@"autofill"];
  [regularField addEntriesFromDictionary:editingValue];
  [self setClientId:123 configuration:regularField];
  XCTAssertEqual(self.installedInputViews.count, 1ul);
  XCTAssertEqual([textInputPlugin.activeView.selectionRects count], 0u);

  NSArray<NSNumber*>* selectionRect = [NSArray arrayWithObjects:@0, @0, @100, @100, @0, @1, nil];
  NSArray* selectionRects = [NSArray arrayWithObjects:selectionRect, nil];
  FlutterMethodCall* methodCall =
      [FlutterMethodCall methodCallWithMethodName:@"Scribble.setSelectionRects"
                                        arguments:selectionRects];
  [textInputPlugin handleMethodCall:methodCall
                             result:^(id _Nullable result){
                             }];

  XCTAssertEqual([textInputPlugin.activeView.selectionRects count], 1u);
}

- (void)testDecommissionedViewAreNotReusedByAutofill {
  // Regression test for https://github.com/flutter/flutter/issues/84407.
  NSMutableDictionary* configuration = self.mutableTemplateCopy;
  [configuration setValue:@{
    @"uniqueIdentifier" : @"field1",
    @"hints" : @[ UITextContentTypePassword ],
    @"editingValue" : @{@"text" : @""}
  }
                   forKey:@"autofill"];
  [configuration setValue:@[ [configuration copy] ] forKey:@"fields"];

  [self setClientId:123 configuration:configuration];

  [self setTextInputHide];
  UIView* previousActiveView = textInputPlugin.activeView;

  [self setClientId:124 configuration:configuration];

  // Make sure the autofillable view is reused.
  XCTAssertEqual(previousActiveView, textInputPlugin.activeView);
  XCTAssertNotNil(previousActiveView);
  // Does not crash.
}

- (void)testInitialActiveViewCantAccessTextInputDelegate {
  // Before the framework sends the first text input configuration,
  // the dummy "activeView" we use should never have access to
  // its textInputDelegate.
  XCTAssertNil(textInputPlugin.activeView.textInputDelegate);
}

#pragma mark - Accessibility - Tests

- (void)testUITextInputAccessibilityNotHiddenWhenShowed {
  [self setClientId:123 configuration:self.mutableTemplateCopy];

  // Send show text input method call.
  [self setTextInputShow];
  // Find all the FlutterTextInputViews we created.
  NSArray<FlutterTextInputView*>* inputFields = self.installedInputViews;

  // The input view should not be hidden.
  XCTAssertEqual([inputFields count], 1u);

  // Send hide text input method call.
  [self setTextInputHide];

  inputFields = self.installedInputViews;

  // The input view should be hidden.
  XCTAssertEqual([inputFields count], 0u);
}

- (void)testFlutterTextInputViewDirectFocusToBackingTextInput {
  FlutterTextInputViewSpy* inputView =
      [[FlutterTextInputViewSpy alloc] initWithOwner:textInputPlugin];
  UIView* container = [[UIView alloc] init];
  UIAccessibilityElement* backing =
      [[UIAccessibilityElement alloc] initWithAccessibilityContainer:container];
  inputView.backingTextInputAccessibilityObject = backing;
  // Simulate accessibility focus.
  inputView.isAccessibilityFocused = YES;
  [inputView accessibilityElementDidBecomeFocused];

  XCTAssertEqual(inputView.receivedNotification, UIAccessibilityScreenChangedNotification);
  XCTAssertEqual(inputView.receivedNotificationTarget, backing);
}

- (void)testFlutterTokenizerCanParseLines {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  id<UITextInputTokenizer> tokenizer = [inputView tokenizer];

  // The tokenizer returns zero range When text is empty.
  FlutterTextRange* range = [self getLineRangeFromTokenizer:tokenizer atIndex:0];
  XCTAssertEqual(range.range.location, 0u);
  XCTAssertEqual(range.range.length, 0u);

  [inputView insertText:@"how are you\nI am fine, Thank you"];

  range = [self getLineRangeFromTokenizer:tokenizer atIndex:0];
  XCTAssertEqual(range.range.location, 0u);
  XCTAssertEqual(range.range.length, 11u);

  range = [self getLineRangeFromTokenizer:tokenizer atIndex:2];
  XCTAssertEqual(range.range.location, 0u);
  XCTAssertEqual(range.range.length, 11u);

  range = [self getLineRangeFromTokenizer:tokenizer atIndex:11];
  XCTAssertEqual(range.range.location, 0u);
  XCTAssertEqual(range.range.length, 11u);

  range = [self getLineRangeFromTokenizer:tokenizer atIndex:12];
  XCTAssertEqual(range.range.location, 12u);
  XCTAssertEqual(range.range.length, 20u);

  range = [self getLineRangeFromTokenizer:tokenizer atIndex:15];
  XCTAssertEqual(range.range.location, 12u);
  XCTAssertEqual(range.range.length, 20u);

  range = [self getLineRangeFromTokenizer:tokenizer atIndex:32];
  XCTAssertEqual(range.range.location, 12u);
  XCTAssertEqual(range.range.length, 20u);
}

- (void)testFlutterTokenizerLineEnclosingEndOfDocumentInBackwardDirectionShouldNotReturnNil {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView insertText:@"0123456789\n012345"];
  id<UITextInputTokenizer> tokenizer = [inputView tokenizer];

  FlutterTextRange* range =
      (FlutterTextRange*)[tokenizer rangeEnclosingPosition:[inputView endOfDocument]
                                           withGranularity:UITextGranularityLine
                                               inDirection:UITextStorageDirectionBackward];
  XCTAssertEqual(range.range.location, 11u);
  XCTAssertEqual(range.range.length, 6u);
}

- (void)testFlutterTokenizerLineEnclosingEndOfDocumentInForwardDirectionShouldReturnNilOnIOS17 {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView insertText:@"0123456789\n012345"];
  id<UITextInputTokenizer> tokenizer = [inputView tokenizer];

  FlutterTextRange* range =
      (FlutterTextRange*)[tokenizer rangeEnclosingPosition:[inputView endOfDocument]
                                           withGranularity:UITextGranularityLine
                                               inDirection:UITextStorageDirectionForward];
  if (@available(iOS 17.0, *)) {
    XCTAssertNil(range);
  } else {
    XCTAssertEqual(range.range.location, 11u);
    XCTAssertEqual(range.range.length, 6u);
  }
}

- (void)testFlutterTokenizerLineEnclosingOutOfRangePositionShouldReturnNilOnIOS17 {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView insertText:@"0123456789\n012345"];
  id<UITextInputTokenizer> tokenizer = [inputView tokenizer];

  FlutterTextPosition* position = [FlutterTextPosition positionWithIndex:100];
  FlutterTextRange* range =
      (FlutterTextRange*)[tokenizer rangeEnclosingPosition:position
                                           withGranularity:UITextGranularityLine
                                               inDirection:UITextStorageDirectionForward];
  if (@available(iOS 17.0, *)) {
    XCTAssertNil(range);
  } else {
    XCTAssertEqual(range.range.location, 0u);
    XCTAssertEqual(range.range.length, 0u);
  }
}

- (void)testFlutterTextInputPluginRetainsFlutterTextInputView {
  FlutterViewController* flutterViewController = [[FlutterViewController alloc] init];
  FlutterTextInputPlugin* myInputPlugin = [[FlutterTextInputPlugin alloc] initWithDelegate:engine];
  myInputPlugin.viewController = flutterViewController;

  __weak UIView* activeView;
  @autoreleasepool {
    FlutterMethodCall* setClientCall = [FlutterMethodCall
        methodCallWithMethodName:@"TextInput.setClient"
                       arguments:@[
                         [NSNumber numberWithInt:123], self.mutablePasswordTemplateCopy
                       ]];
    [myInputPlugin handleMethodCall:setClientCall
                             result:^(id _Nullable result){
                             }];
    activeView = myInputPlugin.textInputView;
    FlutterMethodCall* hideCall = [FlutterMethodCall methodCallWithMethodName:@"TextInput.hide"
                                                                    arguments:@[]];
    [myInputPlugin handleMethodCall:hideCall
                             result:^(id _Nullable result){
                             }];
    XCTAssertNotNil(activeView);
  }
  // This assert proves the myInputPlugin.textInputView is not deallocated.
  XCTAssertNotNil(activeView);
}

- (void)testFlutterTextInputPluginHostViewNilCrash {
  FlutterTextInputPlugin* myInputPlugin = [[FlutterTextInputPlugin alloc] initWithDelegate:engine];
  myInputPlugin.viewController = nil;
  XCTAssertThrows([myInputPlugin hostView], @"Throws exception if host view is nil");
}

- (void)testFlutterTextInputPluginHostViewNotNil {
  FlutterViewController* flutterViewController = [[FlutterViewController alloc] init];
  FlutterEngine* flutterEngine = [[FlutterEngine alloc] init];
  [flutterEngine runWithEntrypoint:nil];
  flutterEngine.viewController = flutterViewController;
  XCTAssertNotNil(flutterEngine.textInputPlugin.viewController);
  XCTAssertNotNil([flutterEngine.textInputPlugin hostView]);
}

- (void)testSetPlatformViewClient {
  FlutterViewController* flutterViewController = [[FlutterViewController alloc] init];
  FlutterTextInputPlugin* myInputPlugin = [[FlutterTextInputPlugin alloc] initWithDelegate:engine];
  myInputPlugin.viewController = flutterViewController;

  FlutterMethodCall* setClientCall = [FlutterMethodCall
      methodCallWithMethodName:@"TextInput.setClient"
                     arguments:@[ [NSNumber numberWithInt:123], self.mutablePasswordTemplateCopy ]];
  [myInputPlugin handleMethodCall:setClientCall
                           result:^(id _Nullable result){
                           }];
  UIView* activeView = myInputPlugin.textInputView;
  XCTAssertNotNil(activeView.superview, @"activeView must be added to the view hierarchy.");
  FlutterMethodCall* setPlatformViewClientCall = [FlutterMethodCall
      methodCallWithMethodName:@"TextInput.setPlatformViewClient"
                     arguments:@{@"platformViewId" : [NSNumber numberWithLong:456]}];
  [myInputPlugin handleMethodCall:setPlatformViewClientCall
                           result:^(id _Nullable result){
                           }];
  XCTAssertNil(activeView.superview, @"activeView must be removed from view hierarchy.");
}

- (void)testInteractiveKeyboardAfterUserScrollWillResignFirstResponder {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [UIApplication.sharedApplication.keyWindow addSubview:inputView];

  [inputView setTextInputClient:123];
  [inputView reloadInputViews];
  [inputView becomeFirstResponder];
  XCTAssert(inputView.isFirstResponder);

  CGRect keyboardFrame = CGRectMake(0, 500, 500, 500);
  [NSNotificationCenter.defaultCenter
      postNotificationName:UIKeyboardWillShowNotification
                    object:nil
                  userInfo:@{UIKeyboardFrameEndUserInfoKey : @(keyboardFrame)}];
  FlutterMethodCall* onPointerMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(500)}];
  [textInputPlugin handleMethodCall:onPointerMoveCall
                             result:^(id _Nullable result){
                             }];
  XCTAssertFalse(inputView.isFirstResponder);
  textInputPlugin.cachedFirstResponder = nil;
}

- (void)testInteractiveKeyboardAfterUserScrollToTopOfKeyboardWillTakeScreenshot {
  NSSet<UIScene*>* scenes = UIApplication.sharedApplication.connectedScenes;
  XCTAssertEqual(scenes.count, 1UL, @"There must only be 1 scene for test");
  UIScene* scene = scenes.anyObject;
  XCTAssert([scene isKindOfClass:[UIWindowScene class]], @"Must be a window scene for test");
  UIWindowScene* windowScene = (UIWindowScene*)scene;
  XCTAssert(windowScene.windows.count > 0, @"There must be at least 1 window for test");
  UIWindow* window = windowScene.windows[0];
  [window addSubview:viewController.view];

  [viewController loadView];

  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [UIApplication.sharedApplication.keyWindow addSubview:inputView];

  [inputView setTextInputClient:123];
  [inputView reloadInputViews];
  [inputView becomeFirstResponder];

  if (textInputPlugin.keyboardView.superview != nil) {
    for (UIView* subView in textInputPlugin.keyboardViewContainer.subviews) {
      [subView removeFromSuperview];
    }
  }
  XCTAssert(textInputPlugin.keyboardView.superview == nil);
  CGRect keyboardFrame = CGRectMake(0, 500, 500, 500);
  [NSNotificationCenter.defaultCenter
      postNotificationName:UIKeyboardWillShowNotification
                    object:nil
                  userInfo:@{UIKeyboardFrameEndUserInfoKey : @(keyboardFrame)}];
  FlutterMethodCall* onPointerMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(510)}];
  [textInputPlugin handleMethodCall:onPointerMoveCall
                             result:^(id _Nullable result){
                             }];
  XCTAssertFalse(textInputPlugin.keyboardView.superview == nil);
  for (UIView* subView in textInputPlugin.keyboardViewContainer.subviews) {
    [subView removeFromSuperview];
  }
  textInputPlugin.cachedFirstResponder = nil;
}

- (void)testInteractiveKeyboardScreenshotWillBeMovedDownAfterUserScroll {
  NSSet<UIScene*>* scenes = UIApplication.sharedApplication.connectedScenes;
  XCTAssertEqual(scenes.count, 1UL, @"There must only be 1 scene for test");
  UIScene* scene = scenes.anyObject;
  XCTAssert([scene isKindOfClass:[UIWindowScene class]], @"Must be a window scene for test");
  UIWindowScene* windowScene = (UIWindowScene*)scene;
  XCTAssert(windowScene.windows.count > 0, @"There must be at least 1 window for test");
  UIWindow* window = windowScene.windows[0];
  [window addSubview:viewController.view];

  [viewController loadView];

  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [UIApplication.sharedApplication.keyWindow addSubview:inputView];

  [inputView setTextInputClient:123];
  [inputView reloadInputViews];
  [inputView becomeFirstResponder];

  CGRect keyboardFrame = CGRectMake(0, 500, 500, 500);
  [NSNotificationCenter.defaultCenter
      postNotificationName:UIKeyboardWillShowNotification
                    object:nil
                  userInfo:@{UIKeyboardFrameEndUserInfoKey : @(keyboardFrame)}];
  FlutterMethodCall* onPointerMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(510)}];
  [textInputPlugin handleMethodCall:onPointerMoveCall
                             result:^(id _Nullable result){
                             }];
  XCTAssert(textInputPlugin.keyboardView.superview != nil);

  XCTAssertEqual(textInputPlugin.keyboardViewContainer.frame.origin.y, keyboardFrame.origin.y);

  FlutterMethodCall* onPointerMoveCallMove =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(600)}];
  [textInputPlugin handleMethodCall:onPointerMoveCallMove
                             result:^(id _Nullable result){
                             }];
  XCTAssert(textInputPlugin.keyboardView.superview != nil);

  XCTAssertEqual(textInputPlugin.keyboardViewContainer.frame.origin.y, 600.0);

  for (UIView* subView in textInputPlugin.keyboardViewContainer.subviews) {
    [subView removeFromSuperview];
  }
  textInputPlugin.cachedFirstResponder = nil;
}

- (void)testInteractiveKeyboardScreenshotWillBeMovedToOrginalPositionAfterUserScroll {
  NSSet<UIScene*>* scenes = UIApplication.sharedApplication.connectedScenes;
  XCTAssertEqual(scenes.count, 1UL, @"There must only be 1 scene for test");
  UIScene* scene = scenes.anyObject;
  XCTAssert([scene isKindOfClass:[UIWindowScene class]], @"Must be a window scene for test");
  UIWindowScene* windowScene = (UIWindowScene*)scene;
  XCTAssert(windowScene.windows.count > 0, @"There must be at least 1 window for test");
  UIWindow* window = windowScene.windows[0];
  [window addSubview:viewController.view];

  [viewController loadView];

  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [UIApplication.sharedApplication.keyWindow addSubview:inputView];

  [inputView setTextInputClient:123];
  [inputView reloadInputViews];
  [inputView becomeFirstResponder];

  CGRect keyboardFrame = CGRectMake(0, 500, 500, 500);
  [NSNotificationCenter.defaultCenter
      postNotificationName:UIKeyboardWillShowNotification
                    object:nil
                  userInfo:@{UIKeyboardFrameEndUserInfoKey : @(keyboardFrame)}];
  FlutterMethodCall* onPointerMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(500)}];
  [textInputPlugin handleMethodCall:onPointerMoveCall
                             result:^(id _Nullable result){
                             }];
  XCTAssert(textInputPlugin.keyboardView.superview != nil);
  XCTAssertEqual(textInputPlugin.keyboardViewContainer.frame.origin.y, keyboardFrame.origin.y);

  FlutterMethodCall* onPointerMoveCallMove =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(600)}];
  [textInputPlugin handleMethodCall:onPointerMoveCallMove
                             result:^(id _Nullable result){
                             }];
  XCTAssert(textInputPlugin.keyboardView.superview != nil);
  XCTAssertEqual(textInputPlugin.keyboardViewContainer.frame.origin.y, 600.0);

  FlutterMethodCall* onPointerMoveCallBackUp =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(10)}];
  [textInputPlugin handleMethodCall:onPointerMoveCallBackUp
                             result:^(id _Nullable result){
                             }];
  XCTAssert(textInputPlugin.keyboardView.superview != nil);
  XCTAssertEqual(textInputPlugin.keyboardViewContainer.frame.origin.y, keyboardFrame.origin.y);
  for (UIView* subView in textInputPlugin.keyboardViewContainer.subviews) {
    [subView removeFromSuperview];
  }
  textInputPlugin.cachedFirstResponder = nil;
}

- (void)testInteractiveKeyboardFindFirstResponderRecursive {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [UIApplication.sharedApplication.keyWindow addSubview:inputView];
  [inputView setTextInputClient:123];
  [inputView reloadInputViews];
  [inputView becomeFirstResponder];

  UIView* firstResponder = UIApplication.sharedApplication.keyWindow.flutterFirstResponder;
  XCTAssertEqualObjects(inputView, firstResponder);
  textInputPlugin.cachedFirstResponder = nil;
}

- (void)testInteractiveKeyboardFindFirstResponderRecursiveInMultipleSubviews {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  FlutterTextInputView* subInputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  FlutterTextInputView* otherSubInputView =
      [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  FlutterTextInputView* subFirstResponderInputView =
      [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [subInputView addSubview:subFirstResponderInputView];
  [inputView addSubview:subInputView];
  [inputView addSubview:otherSubInputView];
  [UIApplication.sharedApplication.keyWindow addSubview:inputView];
  [inputView setTextInputClient:123];
  [inputView reloadInputViews];
  [subInputView setTextInputClient:123];
  [subInputView reloadInputViews];
  [otherSubInputView setTextInputClient:123];
  [otherSubInputView reloadInputViews];
  [subFirstResponderInputView setTextInputClient:123];
  [subFirstResponderInputView reloadInputViews];
  [subFirstResponderInputView becomeFirstResponder];

  UIView* firstResponder = UIApplication.sharedApplication.keyWindow.flutterFirstResponder;
  XCTAssertEqualObjects(subFirstResponderInputView, firstResponder);
  textInputPlugin.cachedFirstResponder = nil;
}

- (void)testInteractiveKeyboardFindFirstResponderIsNilRecursive {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [UIApplication.sharedApplication.keyWindow addSubview:inputView];
  [inputView setTextInputClient:123];
  [inputView reloadInputViews];

  UIView* firstResponder = UIApplication.sharedApplication.keyWindow.flutterFirstResponder;
  XCTAssertNil(firstResponder);
  textInputPlugin.cachedFirstResponder = nil;
}

- (void)testInteractiveKeyboardDidResignFirstResponderDelegateisCalledAfterDismissedKeyboard {
  NSSet<UIScene*>* scenes = UIApplication.sharedApplication.connectedScenes;
  XCTAssertEqual(scenes.count, 1UL, @"There must only be 1 scene for test");
  UIScene* scene = scenes.anyObject;
  XCTAssert([scene isKindOfClass:[UIWindowScene class]], @"Must be a window scene for test");
  UIWindowScene* windowScene = (UIWindowScene*)scene;
  XCTAssert(windowScene.windows.count > 0, @"There must be at least 1 window for test");
  UIWindow* window = windowScene.windows[0];
  [window addSubview:viewController.view];

  [viewController loadView];

  XCTestExpectation* expectation = [[XCTestExpectation alloc]
      initWithDescription:
          @"didResignFirstResponder is called after screenshot keyboard dismissed."];
  OCMStub([engine flutterTextInputView:[OCMArg any] didResignFirstResponderWithTextInputClient:0])
      .andDo(^(NSInvocation* invocation) {
        [expectation fulfill];
      });
  CGRect keyboardFrame = CGRectMake(0, 500, 500, 500);
  [NSNotificationCenter.defaultCenter
      postNotificationName:UIKeyboardWillShowNotification
                    object:nil
                  userInfo:@{UIKeyboardFrameEndUserInfoKey : @(keyboardFrame)}];
  FlutterMethodCall* initialMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(500)}];
  [textInputPlugin handleMethodCall:initialMoveCall
                             result:^(id _Nullable result){
                             }];
  FlutterMethodCall* subsequentMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(1000)}];
  [textInputPlugin handleMethodCall:subsequentMoveCall
                             result:^(id _Nullable result){
                             }];

  FlutterMethodCall* pointerUpCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerUpForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(1000)}];
  [textInputPlugin handleMethodCall:pointerUpCall
                             result:^(id _Nullable result){
                             }];

  [self waitForExpectations:@[ expectation ] timeout:2.0];
  textInputPlugin.cachedFirstResponder = nil;
}

- (void)testInteractiveKeyboardScreenshotDismissedAfterPointerLiftedAboveMiddleYOfKeyboard {
  NSSet<UIScene*>* scenes = UIApplication.sharedApplication.connectedScenes;
  XCTAssertEqual(scenes.count, 1UL, @"There must only be 1 scene for test");
  UIScene* scene = scenes.anyObject;
  XCTAssert([scene isKindOfClass:[UIWindowScene class]], @"Must be a window scene for test");
  UIWindowScene* windowScene = (UIWindowScene*)scene;
  XCTAssert(windowScene.windows.count > 0, @"There must be at least 1 window for test");
  UIWindow* window = windowScene.windows[0];
  [window addSubview:viewController.view];

  [viewController loadView];

  CGRect keyboardFrame = CGRectMake(0, 500, 500, 500);
  [NSNotificationCenter.defaultCenter
      postNotificationName:UIKeyboardWillShowNotification
                    object:nil
                  userInfo:@{UIKeyboardFrameEndUserInfoKey : @(keyboardFrame)}];
  FlutterMethodCall* initialMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(500)}];
  [textInputPlugin handleMethodCall:initialMoveCall
                             result:^(id _Nullable result){
                             }];
  FlutterMethodCall* subsequentMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(1000)}];
  [textInputPlugin handleMethodCall:subsequentMoveCall
                             result:^(id _Nullable result){
                             }];

  FlutterMethodCall* subsequentMoveBackUpCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(0)}];
  [textInputPlugin handleMethodCall:subsequentMoveBackUpCall
                             result:^(id _Nullable result){
                             }];

  FlutterMethodCall* pointerUpCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerUpForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(0)}];
  [textInputPlugin handleMethodCall:pointerUpCall
                             result:^(id _Nullable result){
                             }];
  NSPredicate* predicate = [NSPredicate predicateWithBlock:^BOOL(id item, NSDictionary* bindings) {
    return textInputPlugin.keyboardViewContainer.subviews.count == 0;
  }];
  XCTNSPredicateExpectation* expectation =
      [[XCTNSPredicateExpectation alloc] initWithPredicate:predicate object:nil];
  [self waitForExpectations:@[ expectation ] timeout:10.0];
  textInputPlugin.cachedFirstResponder = nil;
}

- (void)testInteractiveKeyboardKeyboardReappearsAfterPointerLiftedAboveMiddleYOfKeyboard {
  NSSet<UIScene*>* scenes = UIApplication.sharedApplication.connectedScenes;
  XCTAssertEqual(scenes.count, 1UL, @"There must only be 1 scene for test");
  UIScene* scene = scenes.anyObject;
  XCTAssert([scene isKindOfClass:[UIWindowScene class]], @"Must be a window scene for test");
  UIWindowScene* windowScene = (UIWindowScene*)scene;
  XCTAssert(windowScene.windows.count > 0, @"There must be at least 1 window for test");
  UIWindow* window = windowScene.windows[0];
  [window addSubview:viewController.view];

  [viewController loadView];

  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [UIApplication.sharedApplication.keyWindow addSubview:inputView];

  [inputView setTextInputClient:123];
  [inputView reloadInputViews];
  [inputView becomeFirstResponder];

  CGRect keyboardFrame = CGRectMake(0, 500, 500, 500);
  [NSNotificationCenter.defaultCenter
      postNotificationName:UIKeyboardWillShowNotification
                    object:nil
                  userInfo:@{UIKeyboardFrameEndUserInfoKey : @(keyboardFrame)}];
  FlutterMethodCall* initialMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(500)}];
  [textInputPlugin handleMethodCall:initialMoveCall
                             result:^(id _Nullable result){
                             }];
  FlutterMethodCall* subsequentMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(1000)}];
  [textInputPlugin handleMethodCall:subsequentMoveCall
                             result:^(id _Nullable result){
                             }];

  FlutterMethodCall* subsequentMoveBackUpCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(0)}];
  [textInputPlugin handleMethodCall:subsequentMoveBackUpCall
                             result:^(id _Nullable result){
                             }];

  FlutterMethodCall* pointerUpCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerUpForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(0)}];
  [textInputPlugin handleMethodCall:pointerUpCall
                             result:^(id _Nullable result){
                             }];
  NSPredicate* predicate = [NSPredicate predicateWithBlock:^BOOL(id item, NSDictionary* bindings) {
    return textInputPlugin.cachedFirstResponder.isFirstResponder;
  }];
  XCTNSPredicateExpectation* expectation =
      [[XCTNSPredicateExpectation alloc] initWithPredicate:predicate object:nil];
  [self waitForExpectations:@[ expectation ] timeout:10.0];
  textInputPlugin.cachedFirstResponder = nil;
}

- (void)testInteractiveKeyboardKeyboardAnimatesToOriginalPositionalOnPointerUp {
  NSSet<UIScene*>* scenes = UIApplication.sharedApplication.connectedScenes;
  XCTAssertEqual(scenes.count, 1UL, @"There must only be 1 scene for test");
  UIScene* scene = scenes.anyObject;
  XCTAssert([scene isKindOfClass:[UIWindowScene class]], @"Must be a window scene for test");
  UIWindowScene* windowScene = (UIWindowScene*)scene;
  XCTAssert(windowScene.windows.count > 0, @"There must be at least 1 window for test");
  UIWindow* window = windowScene.windows[0];
  [window addSubview:viewController.view];

  [viewController loadView];

  XCTestExpectation* expectation =
      [[XCTestExpectation alloc] initWithDescription:@"Keyboard animates to proper position."];
  CGRect keyboardFrame = CGRectMake(0, 500, 500, 500);
  [NSNotificationCenter.defaultCenter
      postNotificationName:UIKeyboardWillShowNotification
                    object:nil
                  userInfo:@{UIKeyboardFrameEndUserInfoKey : @(keyboardFrame)}];
  FlutterMethodCall* initialMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(500)}];
  [textInputPlugin handleMethodCall:initialMoveCall
                             result:^(id _Nullable result){
                             }];
  FlutterMethodCall* subsequentMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(1000)}];
  [textInputPlugin handleMethodCall:subsequentMoveCall
                             result:^(id _Nullable result){
                             }];
  FlutterMethodCall* upwardVelocityMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(500)}];
  [textInputPlugin handleMethodCall:upwardVelocityMoveCall
                             result:^(id _Nullable result){
                             }];

  FlutterMethodCall* pointerUpCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerUpForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(0)}];
  [textInputPlugin
      handleMethodCall:pointerUpCall
                result:^(id _Nullable result) {
                  XCTAssertEqual(textInputPlugin.keyboardViewContainer.frame.origin.y,
                                 viewController.flutterScreenIfViewLoaded.bounds.size.height -
                                     keyboardFrame.origin.y);
                  [expectation fulfill];
                }];
  textInputPlugin.cachedFirstResponder = nil;
}

- (void)testInteractiveKeyboardKeyboardAnimatesToDismissalPositionalOnPointerUp {
  NSSet<UIScene*>* scenes = UIApplication.sharedApplication.connectedScenes;
  XCTAssertEqual(scenes.count, 1UL, @"There must only be 1 scene for test");
  UIScene* scene = scenes.anyObject;
  XCTAssert([scene isKindOfClass:[UIWindowScene class]], @"Must be a window scene for test");
  UIWindowScene* windowScene = (UIWindowScene*)scene;
  XCTAssert(windowScene.windows.count > 0, @"There must be at least 1 window for test");
  UIWindow* window = windowScene.windows[0];
  [window addSubview:viewController.view];

  [viewController loadView];

  XCTestExpectation* expectation =
      [[XCTestExpectation alloc] initWithDescription:@"Keyboard animates to proper position."];
  CGRect keyboardFrame = CGRectMake(0, 500, 500, 500);
  [NSNotificationCenter.defaultCenter
      postNotificationName:UIKeyboardWillShowNotification
                    object:nil
                  userInfo:@{UIKeyboardFrameEndUserInfoKey : @(keyboardFrame)}];
  FlutterMethodCall* initialMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(500)}];
  [textInputPlugin handleMethodCall:initialMoveCall
                             result:^(id _Nullable result){
                             }];
  FlutterMethodCall* subsequentMoveCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerMoveForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(1000)}];
  [textInputPlugin handleMethodCall:subsequentMoveCall
                             result:^(id _Nullable result){
                             }];

  FlutterMethodCall* pointerUpCall =
      [FlutterMethodCall methodCallWithMethodName:@"TextInput.onPointerUpForInteractiveKeyboard"
                                        arguments:@{@"pointerY" : @(1000)}];
  [textInputPlugin
      handleMethodCall:pointerUpCall
                result:^(id _Nullable result) {
                  XCTAssertEqual(textInputPlugin.keyboardViewContainer.frame.origin.y,
                                 viewController.flutterScreenIfViewLoaded.bounds.size.height);
                  [expectation fulfill];
                }];
  textInputPlugin.cachedFirstResponder = nil;
}
- (void)testInteractiveKeyboardShowKeyboardAndRemoveScreenshotAnimationIsNotImmediatelyEnable {
  [UIView setAnimationsEnabled:YES];
  [textInputPlugin showKeyboardAndRemoveScreenshot];
  XCTAssertFalse(
      UIView.areAnimationsEnabled,
      @"The animation should still be disabled following showKeyboardAndRemoveScreenshot");
}

- (void)testInteractiveKeyboardShowKeyboardAndRemoveScreenshotAnimationIsReenabledAfterDelay {
  [UIView setAnimationsEnabled:YES];
  [textInputPlugin showKeyboardAndRemoveScreenshot];

  NSPredicate* predicate = [NSPredicate predicateWithBlock:^BOOL(id item, NSDictionary* bindings) {
    // This will be enabled after a delay
    return UIView.areAnimationsEnabled;
  }];
  XCTNSPredicateExpectation* expectation =
      [[XCTNSPredicateExpectation alloc] initWithPredicate:predicate object:nil];
  [self waitForExpectations:@[ expectation ] timeout:10.0];
}

@end
