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

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)
    NSMutableDictionary<NSString*, FlutterTextInputView*>* autofillContext;

- (void)cleanUpViewHierarchy:(BOOL)includeActiveView
                   clearText:(BOOL)clearText
                delayRemoval:(BOOL)delayRemoval;
- (NSArray<UIView*>*)textInputViews;
- (UIView*)hostView;
- (fml::WeakPtr<FlutterTextInputPlugin>)getWeakPtr;
- (void)addToInputParentViewIfNeeded:(FlutterTextInputView*)inputView;
- (void)startLiveTextInput;
@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){
                             }];
}

- (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;
}

#pragma mark - Tests

- (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)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)testAutocorrectionPromptRectAppears {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [inputView firstRectForRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]];

  // Verify behavior.
  OCMVerify([engine flutterTextInputView:inputView
      showAutocorrectionPromptRectForStart:0
                                       end:1
                                withClient:0]);
}

- (void)testIngoresSelectionChangeIfSelectionIsDisabled {
  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 {
  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)testTextRangeFromPositionMatchesUITextViewBehavior {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  FlutterTextPosition* fromPosition = [[FlutterTextPosition alloc] initWithIndex:2];
  FlutterTextPosition* toPosition = [[FlutterTextPosition alloc] initWithIndex: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, @"");
}

- (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]]);
}

#pragma mark - TextEditingDelta tests
- (void)testTextEditingDeltasAreGeneratedOnTextInput {
  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"];
  // Update the framework exactly once.
  XCTAssertEqual(updateCount, 1);

  // Verify correct delta is generated.
  OCMVerify([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);
                 }]]);

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

  OCMVerify([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);
                 }]]);

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

  OCMVerify([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);
                 }]]);

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

  OCMVerify([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);
                 }]]);

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

  OCMVerify([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);
                 }]]);

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

  OCMVerify([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);
                 }]]);
}

- (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;
  XCTAssertEqual(updateCount, 1);

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

  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);
                 }]]);
}

- (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"];
  XCTAssertEqual(updateCount, 0);

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

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

  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);
                 }]]);
}

- (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"];
  XCTAssertEqual(updateCount, 0);

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

  [inputView setMarkedText:@"tex" selectedRange:NSMakeRange(0, 1)];
  XCTAssertEqual(updateCount, 2);

  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);
                 }]]);
}

#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"];
  // 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)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"];
  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)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];

    XCTAssertFalse([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];
    XCTAssertFalse([mockInputView canPerformAction:@selector(copy:) withSender:NULL]);
    XCTAssertTrue([mockInputView canPerformAction:@selector(copy:) withSender:@"sender"]);
    XCTAssertFalse([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 {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
  [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 ];

  // 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]));
}

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

  FlutterTextRange* range = [FlutterTextRange rangeWithNSRange:NSMakeRange(1, 1)];
  CGRect testRect = CGRectMake(100, 100, 100, 100);
  [inputView setSelectionRects:@[
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(0, 0, 100, 100) position:0U],
    [FlutterTextSelectionRect selectionRectWithRect:testRect position:1U],
    [FlutterTextSelectionRect selectionRectWithRect:CGRectMake(200, 200, 100, 100) position:2U],
  ]];
  XCTAssertTrue(CGRectEqualToRect(testRect, [inputView firstRectForRange:range]));

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

- (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(1U, ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).index);

  // 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);

  // 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(3U, ((FlutterTextPosition*)[inputView closestPositionToPoint:point]).index);

  // 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);
}

- (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, 1)];
  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);

  // 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);
}

#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)testBoundsForFloatingCursor {
  FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];

  CGRect initialBounds = inputView.bounds;
  // Make sure the initial bounds.size is not as large.
  XCTAssertLessThan(inputView.bounds.size.width, 100);
  XCTAssertLessThan(inputView.bounds.size.height, 100);

  [inputView beginFloatingCursorAtPoint:CGPointMake(123, 321)];
  CGRect bounds = inputView.bounds;
  XCTAssertGreaterThan(bounds.size.width, 1000);
  XCTAssertGreaterThan(bounds.size.height, 1000);

  // Verify the caret is centered.
  XCTAssertEqual(
      CGRectGetMidX(bounds),
      CGRectGetMidX([inputView caretRectForPosition:[FlutterTextPosition positionWithIndex:1235]]));
  XCTAssertEqual(
      CGRectGetMidY(bounds),
      CGRectGetMidY([inputView caretRectForPosition:[FlutterTextPosition positionWithIndex:4567]]));

  [inputView updateFloatingCursorAtPoint:CGPointMake(456, 654)];
  bounds = inputView.bounds;
  XCTAssertGreaterThan(bounds.size.width, 1000);
  XCTAssertGreaterThan(bounds.size.height, 1000);

  // Verify the caret is centered.
  XCTAssertEqual(
      CGRectGetMidX(bounds),
      CGRectGetMidX([inputView caretRectForPosition:[FlutterTextPosition positionWithIndex:21]]));
  XCTAssertEqual(
      CGRectGetMidY(bounds),
      CGRectGetMidY([inputView caretRectForPosition:[FlutterTextPosition positionWithIndex:42]]));

  [inputView endFloatingCursor];
  XCTAssertTrue(CGRectEqualToRect(initialBounds, inputView.bounds));
}

#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)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)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.");
}

@end
