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

#include <Carbon/Carbon.h>
#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>

#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyPrimaryResponder.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyboardManager.h"
#include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
#import "flutter/testing/testing.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"

namespace {

using flutter::testing::keycodes::kLogicalBracketLeft;
using flutter::testing::keycodes::kLogicalDigit1;
using flutter::testing::keycodes::kLogicalDigit2;
using flutter::testing::keycodes::kLogicalKeyA;
using flutter::testing::keycodes::kLogicalKeyM;
using flutter::testing::keycodes::kLogicalKeyQ;
using flutter::testing::keycodes::kLogicalKeyT;

using flutter::LayoutClue;

typedef BOOL (^BoolGetter)();
typedef void (^AsyncKeyCallbackHandler)(FlutterAsyncKeyCallback callback);
typedef void (^AsyncEmbedderCallbackHandler)(const FlutterKeyEvent* event,
                                             FlutterAsyncKeyCallback callback);
typedef BOOL (^TextInputCallback)(NSEvent*);

// When the Vietnamese IME converts messages into "pure text" messages, their
// key codes are set to "empty".
//
// The 0 also happens to be the key code for key A.
constexpr uint16_t kKeyCodeEmpty = 0x00;

// Constants used for `recordCallTypesTo:forTypes:`.
constexpr uint32_t kEmbedderCall = 0x1;
constexpr uint32_t kChannelCall = 0x2;
constexpr uint32_t kTextCall = 0x4;

// All key clues for a keyboard layout.
//
// The index is (keyCode * 2 + hasShift). The value is 0xMNNNN, where:
//
//  - M is whether the key is a dead key (0x1 for true, 0x0 for false).
//  - N is the character for this key. (It only supports UTF-16, but we don't
//    need full UTF-32 support for unit tests. Moreover, Carbon's UCKeyTranslate
//    only returns UniChar (UInt16) anyway.)
typedef const std::array<uint32_t, 256> MockLayoutData;

// The following layout data is generated using DEBUG_PRINT_LAYOUT.

MockLayoutData kUsLayout = {
    //         +0x0     Shift    +0x1     Shift    +0x2     Shift    +0x3     Shift
    /* 0x00 */ 0x00061, 0x00041, 0x00073, 0x00053, 0x00064, 0x00044, 0x00066, 0x00046,
    /* 0x04 */ 0x00068, 0x00048, 0x00067, 0x00047, 0x0007a, 0x0005a, 0x00078, 0x00058,
    /* 0x08 */ 0x00063, 0x00043, 0x00076, 0x00056, 0x000a7, 0x000b1, 0x00062, 0x00042,
    /* 0x0c */ 0x00071, 0x00051, 0x00077, 0x00057, 0x00065, 0x00045, 0x00072, 0x00052,
    /* 0x10 */ 0x00079, 0x00059, 0x00074, 0x00054, 0x00031, 0x00021, 0x00032, 0x00040,
    /* 0x14 */ 0x00033, 0x00023, 0x00034, 0x00024, 0x00036, 0x0005e, 0x00035, 0x00025,
    /* 0x18 */ 0x0003d, 0x0002b, 0x00039, 0x00028, 0x00037, 0x00026, 0x0002d, 0x0005f,
    /* 0x1c */ 0x00038, 0x0002a, 0x00030, 0x00029, 0x0005d, 0x0007d, 0x0006f, 0x0004f,
    /* 0x20 */ 0x00075, 0x00055, 0x0005b, 0x0007b, 0x00069, 0x00049, 0x00070, 0x00050,
    /* 0x24 */ 0x00000, 0x00000, 0x0006c, 0x0004c, 0x0006a, 0x0004a, 0x00027, 0x00022,
    /* 0x28 */ 0x0006b, 0x0004b, 0x0003b, 0x0003a, 0x0005c, 0x0007c, 0x0002c, 0x0003c,
    /* 0x2c */ 0x0002f, 0x0003f, 0x0006e, 0x0004e, 0x0006d, 0x0004d, 0x0002e, 0x0003e,
    /* 0x30 */ 0x00000, 0x00000, 0x00020, 0x00020, 0x00060, 0x0007e,
};

MockLayoutData kFrenchLayout = {
    //         +0x0     Shift    +0x1     Shift    +0x2     Shift    +0x3     Shift
    /* 0x00 */ 0x00071, 0x00051, 0x00073, 0x00053, 0x00064, 0x00044, 0x00066, 0x00046,
    /* 0x04 */ 0x00068, 0x00048, 0x00067, 0x00047, 0x00077, 0x00057, 0x00078, 0x00058,
    /* 0x08 */ 0x00063, 0x00043, 0x00076, 0x00056, 0x00040, 0x00023, 0x00062, 0x00042,
    /* 0x0c */ 0x00061, 0x00041, 0x0007a, 0x0005a, 0x00065, 0x00045, 0x00072, 0x00052,
    /* 0x10 */ 0x00079, 0x00059, 0x00074, 0x00054, 0x00026, 0x00031, 0x000e9, 0x00032,
    /* 0x14 */ 0x00022, 0x00033, 0x00027, 0x00034, 0x000a7, 0x00036, 0x00028, 0x00035,
    /* 0x18 */ 0x0002d, 0x0005f, 0x000e7, 0x00039, 0x000e8, 0x00037, 0x00029, 0x000b0,
    /* 0x1c */ 0x00021, 0x00038, 0x000e0, 0x00030, 0x00024, 0x0002a, 0x0006f, 0x0004f,
    /* 0x20 */ 0x00075, 0x00055, 0x1005e, 0x100a8, 0x00069, 0x00049, 0x00070, 0x00050,
    /* 0x24 */ 0x00000, 0x00000, 0x0006c, 0x0004c, 0x0006a, 0x0004a, 0x000f9, 0x00025,
    /* 0x28 */ 0x0006b, 0x0004b, 0x0006d, 0x0004d, 0x10060, 0x000a3, 0x0003b, 0x0002e,
    /* 0x2c */ 0x0003d, 0x0002b, 0x0006e, 0x0004e, 0x0002c, 0x0003f, 0x0003a, 0x0002f,
    /* 0x30 */ 0x00000, 0x00000, 0x00020, 0x00020, 0x0003c, 0x0003e,
};

MockLayoutData kRussianLayout = {
    //         +0x0     Shift    +0x1     Shift    +0x2     Shift    +0x3     Shift
    /* 0x00 */ 0x00444, 0x00424, 0x0044b, 0x0042b, 0x00432, 0x00412, 0x00430, 0x00410,
    /* 0x04 */ 0x00440, 0x00420, 0x0043f, 0x0041f, 0x0044f, 0x0042f, 0x00447, 0x00427,
    /* 0x08 */ 0x00441, 0x00421, 0x0043c, 0x0041c, 0x0003e, 0x0003c, 0x00438, 0x00418,
    /* 0x0c */ 0x00439, 0x00419, 0x00446, 0x00426, 0x00443, 0x00423, 0x0043a, 0x0041a,
    /* 0x10 */ 0x0043d, 0x0041d, 0x00435, 0x00415, 0x00031, 0x00021, 0x00032, 0x00022,
    /* 0x14 */ 0x00033, 0x02116, 0x00034, 0x00025, 0x00036, 0x0002c, 0x00035, 0x0003a,
    /* 0x18 */ 0x0003d, 0x0002b, 0x00039, 0x00028, 0x00037, 0x0002e, 0x0002d, 0x0005f,
    /* 0x1c */ 0x00038, 0x0003b, 0x00030, 0x00029, 0x0044a, 0x0042a, 0x00449, 0x00429,
    /* 0x20 */ 0x00433, 0x00413, 0x00445, 0x00425, 0x00448, 0x00428, 0x00437, 0x00417,
    /* 0x24 */ 0x00000, 0x00000, 0x00434, 0x00414, 0x0043e, 0x0041e, 0x0044d, 0x0042d,
    /* 0x28 */ 0x0043b, 0x0041b, 0x00436, 0x00416, 0x00451, 0x00401, 0x00431, 0x00411,
    /* 0x2c */ 0x0002f, 0x0003f, 0x00442, 0x00422, 0x0044c, 0x0042c, 0x0044e, 0x0042e,
    /* 0x30 */ 0x00000, 0x00000, 0x00020, 0x00020, 0x0005d, 0x0005b,
};

MockLayoutData kKhmerLayout = {
    //         +0x0     Shift    +0x1     Shift    +0x2     Shift    +0x3     Shift
    /* 0x00 */ 0x017b6, 0x017ab, 0x0179f, 0x017c3, 0x0178a, 0x0178c, 0x01790, 0x01792,
    /* 0x04 */ 0x017a0, 0x017c7, 0x01784, 0x017a2, 0x0178b, 0x0178d, 0x01781, 0x01783,
    /* 0x08 */ 0x01785, 0x01787, 0x0179c, 0x017c8, 0x00000, 0x00000, 0x01794, 0x01796,
    /* 0x0c */ 0x01786, 0x01788, 0x017b9, 0x017ba, 0x017c1, 0x017c2, 0x0179a, 0x017ac,
    /* 0x10 */ 0x01799, 0x017bd, 0x0178f, 0x01791, 0x017e1, 0x00021, 0x017e2, 0x017d7,
    /* 0x14 */ 0x017e3, 0x00022, 0x017e4, 0x017db, 0x017e6, 0x017cd, 0x017e5, 0x00025,
    /* 0x18 */ 0x017b2, 0x017ce, 0x017e9, 0x017b0, 0x017e7, 0x017d0, 0x017a5, 0x017cc,
    /* 0x1c */ 0x017e8, 0x017cf, 0x017e0, 0x017b3, 0x017aa, 0x017a7, 0x017c4, 0x017c5,
    /* 0x20 */ 0x017bb, 0x017bc, 0x017c0, 0x017bf, 0x017b7, 0x017b8, 0x01795, 0x01797,
    /* 0x24 */ 0x00000, 0x00000, 0x0179b, 0x017a1, 0x017d2, 0x01789, 0x017cb, 0x017c9,
    /* 0x28 */ 0x01780, 0x01782, 0x017be, 0x017d6, 0x017ad, 0x017ae, 0x017a6, 0x017b1,
    /* 0x2c */ 0x017ca, 0x017af, 0x01793, 0x0178e, 0x01798, 0x017c6, 0x017d4, 0x017d5,
    /* 0x30 */ 0x00000, 0x00000, 0x00020, 0x0200b, 0x000ab, 0x000bb,
};

NSEvent* keyDownEvent(unsigned short keyCode, NSString* chars = @"", NSString* charsUnmod = @"") {
  return [NSEvent keyEventWithType:NSEventTypeKeyDown
                          location:NSZeroPoint
                     modifierFlags:0x100
                         timestamp:0
                      windowNumber:0
                           context:nil
                        characters:chars
       charactersIgnoringModifiers:charsUnmod
                         isARepeat:NO
                           keyCode:keyCode];
}

NSEvent* keyUpEvent(unsigned short keyCode) {
  return [NSEvent keyEventWithType:NSEventTypeKeyUp
                          location:NSZeroPoint
                     modifierFlags:0x100
                         timestamp:0
                      windowNumber:0
                           context:nil
                        characters:@""
       charactersIgnoringModifiers:@""
                         isARepeat:NO
                           keyCode:keyCode];
}

id checkKeyDownEvent(unsigned short keyCode) {
  return [OCMArg checkWithBlock:^BOOL(id value) {
    if (![value isKindOfClass:[NSEvent class]]) {
      return NO;
    }
    NSEvent* event = value;
    return event.keyCode == keyCode;
  }];
}

// Clear a list of `FlutterKeyEvent` whose `character` is dynamically allocated.
void clearEvents(std::vector<FlutterKeyEvent>& events) {
  for (FlutterKeyEvent& event : events) {
    if (event.character != nullptr) {
      delete[] event.character;
    }
  }
  events.clear();
}

#define VERIFY_DOWN(OUT_LOGICAL, OUT_CHAR)                          \
  EXPECT_EQ(events[0].type, kFlutterKeyEventTypeDown);              \
  EXPECT_EQ(events[0].logical, static_cast<uint64_t>(OUT_LOGICAL)); \
  EXPECT_STREQ(events[0].character, (OUT_CHAR));                    \
  clearEvents(events);

}  // namespace

@interface KeyboardTester : NSObject
- (nonnull instancetype)init;

// Set embedder calls to respond immediately with the given response.
- (void)respondEmbedderCallsWith:(BOOL)response;

// Record embedder calls to the given storage.
//
// They are not responded to until the stored callbacks are manually called.
- (void)recordEmbedderCallsTo:(nonnull NSMutableArray<FlutterAsyncKeyCallback>*)storage;

- (void)recordEmbedderEventsTo:(nonnull std::vector<FlutterKeyEvent>*)storage
                     returning:(bool)handled;

// Set channel calls to respond immediately with the given response.
- (void)respondChannelCallsWith:(BOOL)response;

// Record channel calls to the given storage.
//
// They are not responded to until the stored callbacks are manually called.
- (void)recordChannelCallsTo:(nonnull NSMutableArray<FlutterAsyncKeyCallback>*)storage;

// Set text calls to respond with the given response.
- (void)respondTextInputWith:(BOOL)response;

// At the start of any kind of call, record the call type to the given storage.
//
// Only calls that are included in `typeMask` will be added. Options are
// kEmbedderCall, kChannelCall, and kTextCall.
//
// This method does not conflict with other call settings, and the recording
// takes place before the callbacks are (or are not) invoked.
- (void)recordCallTypesTo:(nonnull NSMutableArray<NSNumber*>*)typeStorage
                 forTypes:(uint32_t)typeMask;

@property(readonly, nonatomic, strong) FlutterKeyboardManager* manager;
@property(nonatomic, nullable, strong) NSResponder* nextResponder;

#pragma mark - Private

- (void)handleEmbedderEvent:(const FlutterKeyEvent&)event
                   callback:(nullable FlutterKeyEventCallback)callback
                   userData:(nullable void*)userData;

- (void)handleChannelMessage:(NSString*)channel
                     message:(NSData* _Nullable)message
                 binaryReply:(FlutterBinaryReply _Nullable)callback;

- (BOOL)handleTextInputKeyEvent:(NSEvent*)event;
@end

@implementation KeyboardTester {
  AsyncEmbedderCallbackHandler _embedderHandler;
  AsyncKeyCallbackHandler _channelHandler;
  TextInputCallback _textCallback;

  NSMutableArray<NSNumber*>* _typeStorage;
  uint32_t _typeStorageMask;

  flutter::KeyboardLayoutNotifier _keyboardLayoutNotifier;
  const MockLayoutData* _currentLayout;
}

- (nonnull instancetype)init {
  self = [super init];
  if (self == nil) {
    return nil;
  }

  _nextResponder = OCMClassMock([NSResponder class]);
  [self respondChannelCallsWith:FALSE];
  [self respondEmbedderCallsWith:FALSE];
  [self respondTextInputWith:FALSE];

  _currentLayout = &kUsLayout;

  id messengerMock = OCMStrictProtocolMock(@protocol(FlutterBinaryMessenger));
  OCMStub([messengerMock sendOnChannel:@"flutter/keyevent"
                               message:[OCMArg any]
                           binaryReply:[OCMArg any]])
      .andCall(self, @selector(handleChannelMessage:message:binaryReply:));

  id viewDelegateMock = OCMStrictProtocolMock(@protocol(FlutterKeyboardViewDelegate));
  OCMStub([viewDelegateMock nextResponder]).andReturn(_nextResponder);
  OCMStub([viewDelegateMock onTextInputKeyEvent:[OCMArg any]])
      .andCall(self, @selector(handleTextInputKeyEvent:));
  OCMStub([viewDelegateMock getBinaryMessenger]).andReturn(messengerMock);
  OCMStub([viewDelegateMock sendKeyEvent:FlutterKeyEvent {} callback:nil userData:nil])
      .ignoringNonObjectArgs()
      .andCall(self, @selector(handleEmbedderEvent:callback:userData:));
  OCMStub([viewDelegateMock subscribeToKeyboardLayoutChange:[OCMArg any]])
      .andCall(self, @selector(onSetKeyboardLayoutNotifier:));
  OCMStub([viewDelegateMock lookUpLayoutForKeyCode:0 shift:false])
      .ignoringNonObjectArgs()
      .andCall(self, @selector(lookUpLayoutForKeyCode:shift:));

  _manager = [[FlutterKeyboardManager alloc] initWithViewDelegate:viewDelegateMock];
  return self;
}

- (void)respondEmbedderCallsWith:(BOOL)response {
  _embedderHandler = ^(const FlutterKeyEvent* event, FlutterAsyncKeyCallback callback) {
    callback(response);
  };
}

- (void)recordEmbedderCallsTo:(nonnull NSMutableArray<FlutterAsyncKeyCallback>*)storage {
  _embedderHandler = ^(const FlutterKeyEvent* event, FlutterAsyncKeyCallback callback) {
    [storage addObject:callback];
  };
}

- (void)recordEmbedderEventsTo:(nonnull std::vector<FlutterKeyEvent>*)storage
                     returning:(bool)handled {
  _embedderHandler = ^(const FlutterKeyEvent* event, FlutterAsyncKeyCallback callback) {
    FlutterKeyEvent newEvent = *event;
    if (event->character != nullptr) {
      size_t charLen = strlen(event->character);
      char* newCharacter = new char[charLen + 1];
      strlcpy(newCharacter, event->character, charLen + 1);
      newEvent.character = newCharacter;
    }
    storage->push_back(newEvent);
    callback(handled);
  };
}

- (void)respondChannelCallsWith:(BOOL)response {
  _channelHandler = ^(FlutterAsyncKeyCallback callback) {
    callback(response);
  };
}

- (void)recordChannelCallsTo:(nonnull NSMutableArray<FlutterAsyncKeyCallback>*)storage {
  _channelHandler = ^(FlutterAsyncKeyCallback callback) {
    [storage addObject:callback];
  };
}

- (void)respondTextInputWith:(BOOL)response {
  _textCallback = ^(NSEvent* event) {
    return response;
  };
}

- (void)recordCallTypesTo:(nonnull NSMutableArray<NSNumber*>*)typeStorage
                 forTypes:(uint32_t)typeMask {
  _typeStorage = typeStorage;
  _typeStorageMask = typeMask;
}

- (void)setLayout:(const MockLayoutData&)layout {
  _currentLayout = &layout;
  if (_keyboardLayoutNotifier != nil) {
    _keyboardLayoutNotifier();
  }
}

#pragma mark - Private

- (void)handleEmbedderEvent:(const FlutterKeyEvent&)event
                   callback:(nullable FlutterKeyEventCallback)callback
                   userData:(nullable void*)userData {
  if (_typeStorage != nil && (_typeStorageMask & kEmbedderCall) != 0) {
    [_typeStorage addObject:@(kEmbedderCall)];
  }
  if (callback != nullptr) {
    _embedderHandler(&event, ^(BOOL handled) {
      callback(handled, userData);
    });
  }
}

- (void)handleChannelMessage:(NSString*)channel
                     message:(NSData* _Nullable)message
                 binaryReply:(FlutterBinaryReply _Nullable)callback {
  if (_typeStorage != nil && (_typeStorageMask & kChannelCall) != 0) {
    [_typeStorage addObject:@(kChannelCall)];
  }
  _channelHandler(^(BOOL handled) {
    NSDictionary* result = @{
      @"handled" : @(handled),
    };
    NSData* encodedKeyEvent = [[FlutterJSONMessageCodec sharedInstance] encode:result];
    callback(encodedKeyEvent);
  });
}

- (BOOL)handleTextInputKeyEvent:(NSEvent*)event {
  if (_typeStorage != nil && (_typeStorageMask & kTextCall) != 0) {
    [_typeStorage addObject:@(kTextCall)];
  }
  return _textCallback(event);
}

- (void)onSetKeyboardLayoutNotifier:(nullable flutter::KeyboardLayoutNotifier)callback {
  _keyboardLayoutNotifier = callback;
}

- (LayoutClue)lookUpLayoutForKeyCode:(uint16_t)keyCode shift:(BOOL)shift {
  uint32_t cluePair = (*_currentLayout)[(keyCode * 2) + (shift ? 1 : 0)];
  const uint32_t kCharMask = 0xffff;
  const uint32_t kDeadKeyMask = 0x10000;
  return LayoutClue{cluePair & kCharMask, (cluePair & kDeadKeyMask) != 0};
}

@end

@interface FlutterKeyboardManagerUnittestsObjC : NSObject
- (bool)singlePrimaryResponder;
- (bool)doublePrimaryResponder;
- (bool)textInputPlugin;
- (bool)emptyNextResponder;
- (bool)racingConditionBetweenKeyAndText;
- (bool)correctLogicalKeyForLayouts;
@end

namespace flutter::testing {
TEST(FlutterKeyboardManagerUnittests, SinglePrimaryResponder) {
  ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] singlePrimaryResponder]);
}

TEST(FlutterKeyboardManagerUnittests, DoublePrimaryResponder) {
  ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] doublePrimaryResponder]);
}

TEST(FlutterKeyboardManagerUnittests, SingleFinalResponder) {
  ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] textInputPlugin]);
}

TEST(FlutterKeyboardManagerUnittests, EmptyNextResponder) {
  ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] emptyNextResponder]);
}

TEST(FlutterKeyboardManagerUnittests, RacingConditionBetweenKeyAndText) {
  ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] racingConditionBetweenKeyAndText]);
}

TEST(FlutterKeyboardManagerUnittests, CorrectLogicalKeyForLayouts) {
  ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] correctLogicalKeyForLayouts]);
}

}  // namespace flutter::testing

@implementation FlutterKeyboardManagerUnittestsObjC

- (bool)singlePrimaryResponder {
  KeyboardTester* tester = [[KeyboardTester alloc] init];
  NSMutableArray<FlutterAsyncKeyCallback>* embedderCallbacks =
      [NSMutableArray<FlutterAsyncKeyCallback> array];
  [tester recordEmbedderCallsTo:embedderCallbacks];

  // Case: The responder reports FALSE
  [tester.manager handleEvent:keyDownEvent(0x50)];
  EXPECT_EQ([embedderCallbacks count], 1u);
  embedderCallbacks[0](FALSE);
  OCMVerify([tester.nextResponder keyDown:checkKeyDownEvent(0x50)]);
  [embedderCallbacks removeAllObjects];

  // Case: The responder reports TRUE
  [tester.manager handleEvent:keyUpEvent(0x50)];
  EXPECT_EQ([embedderCallbacks count], 1u);
  embedderCallbacks[0](TRUE);
  // [owner.nextResponder keyUp:] should not be called, otherwise an error will be thrown.

  return true;
}

- (bool)doublePrimaryResponder {
  KeyboardTester* tester = [[KeyboardTester alloc] init];

  // Send a down event first so we can send an up event later.
  [tester respondEmbedderCallsWith:false];
  [tester respondChannelCallsWith:false];
  [tester.manager handleEvent:keyDownEvent(0x50)];

  NSMutableArray<FlutterAsyncKeyCallback>* embedderCallbacks =
      [NSMutableArray<FlutterAsyncKeyCallback> array];
  NSMutableArray<FlutterAsyncKeyCallback>* channelCallbacks =
      [NSMutableArray<FlutterAsyncKeyCallback> array];
  [tester recordEmbedderCallsTo:embedderCallbacks];
  [tester recordChannelCallsTo:channelCallbacks];

  // Case: Both responders report TRUE.
  [tester.manager handleEvent:keyUpEvent(0x50)];
  EXPECT_EQ([embedderCallbacks count], 1u);
  EXPECT_EQ([channelCallbacks count], 1u);
  embedderCallbacks[0](TRUE);
  channelCallbacks[0](TRUE);
  EXPECT_EQ([embedderCallbacks count], 1u);
  EXPECT_EQ([channelCallbacks count], 1u);
  // [tester.nextResponder keyUp:] should not be called, otherwise an error will be thrown.
  [embedderCallbacks removeAllObjects];
  [channelCallbacks removeAllObjects];

  // Case: One responder reports TRUE.
  [tester respondEmbedderCallsWith:false];
  [tester respondChannelCallsWith:false];
  [tester.manager handleEvent:keyDownEvent(0x50)];

  [tester recordEmbedderCallsTo:embedderCallbacks];
  [tester recordChannelCallsTo:channelCallbacks];
  [tester.manager handleEvent:keyUpEvent(0x50)];
  EXPECT_EQ([embedderCallbacks count], 1u);
  EXPECT_EQ([channelCallbacks count], 1u);
  embedderCallbacks[0](FALSE);
  channelCallbacks[0](TRUE);
  EXPECT_EQ([embedderCallbacks count], 1u);
  EXPECT_EQ([channelCallbacks count], 1u);
  // [tester.nextResponder keyUp:] should not be called, otherwise an error will be thrown.
  [embedderCallbacks removeAllObjects];
  [channelCallbacks removeAllObjects];

  // Case: Both responders report FALSE.
  [tester.manager handleEvent:keyDownEvent(0x53)];
  EXPECT_EQ([embedderCallbacks count], 1u);
  EXPECT_EQ([channelCallbacks count], 1u);
  embedderCallbacks[0](FALSE);
  channelCallbacks[0](FALSE);
  EXPECT_EQ([embedderCallbacks count], 1u);
  EXPECT_EQ([channelCallbacks count], 1u);
  OCMVerify([tester.nextResponder keyDown:checkKeyDownEvent(0x53)]);
  [embedderCallbacks removeAllObjects];
  [channelCallbacks removeAllObjects];

  return true;
}

- (bool)textInputPlugin {
  KeyboardTester* tester = [[KeyboardTester alloc] init];

  // Send a down event first so we can send an up event later.
  [tester respondEmbedderCallsWith:false];
  [tester respondChannelCallsWith:false];
  [tester.manager handleEvent:keyDownEvent(0x50)];

  NSMutableArray<FlutterAsyncKeyCallback>* callbacks =
      [NSMutableArray<FlutterAsyncKeyCallback> array];
  [tester recordEmbedderCallsTo:callbacks];

  // Case: Primary responder responds TRUE. The event shouldn't be handled by
  // the secondary responder.
  [tester respondTextInputWith:FALSE];
  [tester.manager handleEvent:keyUpEvent(0x50)];
  EXPECT_EQ([callbacks count], 1u);
  callbacks[0](TRUE);
  // [owner.nextResponder keyUp:] should not be called, otherwise an error will be thrown.
  [callbacks removeAllObjects];

  // Send a down event first so we can send an up event later.
  [tester respondEmbedderCallsWith:false];
  [tester.manager handleEvent:keyDownEvent(0x50)];

  // Case: Primary responder responds FALSE. The secondary responder returns
  // TRUE.
  [tester recordEmbedderCallsTo:callbacks];
  [tester respondTextInputWith:TRUE];
  [tester.manager handleEvent:keyUpEvent(0x50)];
  EXPECT_EQ([callbacks count], 1u);
  callbacks[0](FALSE);
  // [owner.nextResponder keyUp:] should not be called, otherwise an error will be thrown.
  [callbacks removeAllObjects];

  // Case: Primary responder responds FALSE. The secondary responder returns FALSE.
  [tester respondTextInputWith:FALSE];
  [tester.manager handleEvent:keyDownEvent(0x50)];
  EXPECT_EQ([callbacks count], 1u);
  callbacks[0](FALSE);
  OCMVerify([tester.nextResponder keyDown:checkKeyDownEvent(0x50)]);
  [callbacks removeAllObjects];

  return true;
}

- (bool)emptyNextResponder {
  KeyboardTester* tester = [[KeyboardTester alloc] init];
  tester.nextResponder = nil;

  [tester respondEmbedderCallsWith:false];
  [tester respondChannelCallsWith:false];
  [tester respondTextInputWith:false];
  [tester.manager handleEvent:keyDownEvent(0x50)];

  // Passes if no error is thrown.
  return true;
}

// Regression test for https://github.com/flutter/flutter/issues/82673.
- (bool)racingConditionBetweenKeyAndText {
  KeyboardTester* tester = [[KeyboardTester alloc] init];

  // Use Vietnamese IME (GoTiengViet, Telex mode) to type "uco".

  // The events received by the framework. The engine might receive
  // a channel message "setEditingState" from the framework.
  NSMutableArray<FlutterAsyncKeyCallback>* keyCallbacks =
      [NSMutableArray<FlutterAsyncKeyCallback> array];
  [tester recordEmbedderCallsTo:keyCallbacks];

  NSMutableArray<NSNumber*>* allCalls = [NSMutableArray<NSNumber*> array];
  [tester recordCallTypesTo:allCalls forTypes:(kEmbedderCall | kTextCall)];

  // Tap key U, which is converted by IME into a pure text message "ư".

  [tester.manager handleEvent:keyDownEvent(kKeyCodeEmpty, @"ư", @"ư")];
  EXPECT_EQ([keyCallbacks count], 1u);
  EXPECT_EQ([allCalls count], 1u);
  EXPECT_EQ(allCalls[0], @(kEmbedderCall));
  keyCallbacks[0](false);
  EXPECT_EQ([keyCallbacks count], 1u);
  EXPECT_EQ([allCalls count], 2u);
  EXPECT_EQ(allCalls[1], @(kTextCall));
  [keyCallbacks removeAllObjects];
  [allCalls removeAllObjects];

  [tester.manager handleEvent:keyUpEvent(kKeyCodeEmpty)];
  EXPECT_EQ([keyCallbacks count], 1u);
  keyCallbacks[0](false);
  EXPECT_EQ([keyCallbacks count], 1u);
  EXPECT_EQ([allCalls count], 2u);
  [keyCallbacks removeAllObjects];
  [allCalls removeAllObjects];

  // Tap key O, which is converted to normal KeyO events, but the responses are
  // slow.

  [tester.manager handleEvent:keyDownEvent(kVK_ANSI_O, @"o", @"o")];
  [tester.manager handleEvent:keyUpEvent(kVK_ANSI_O)];
  EXPECT_EQ([keyCallbacks count], 1u);
  EXPECT_EQ([allCalls count], 1u);
  EXPECT_EQ(allCalls[0], @(kEmbedderCall));

  // Tap key C, which results in two Backspace messages first - and here they
  // arrive before the key O messages are responded.

  [tester.manager handleEvent:keyDownEvent(kVK_Delete)];
  [tester.manager handleEvent:keyUpEvent(kVK_Delete)];
  EXPECT_EQ([keyCallbacks count], 1u);
  EXPECT_EQ([allCalls count], 1u);

  // The key O down is responded, which releases a text call (for KeyO down) and
  // an embedder call (for KeyO up) immediately.
  keyCallbacks[0](false);
  EXPECT_EQ([keyCallbacks count], 2u);
  EXPECT_EQ([allCalls count], 3u);
  EXPECT_EQ(allCalls[1], @(kTextCall));  // The order is important!
  EXPECT_EQ(allCalls[2], @(kEmbedderCall));

  // The key O up is responded, which releases a text call (for KeyO up) and
  // an embedder call (for Backspace down) immediately.
  keyCallbacks[1](false);
  EXPECT_EQ([keyCallbacks count], 3u);
  EXPECT_EQ([allCalls count], 5u);
  EXPECT_EQ(allCalls[3], @(kTextCall));  // The order is important!
  EXPECT_EQ(allCalls[4], @(kEmbedderCall));

  // Finish up callbacks.
  keyCallbacks[2](false);
  keyCallbacks[3](false);

  return true;
}

- (bool)correctLogicalKeyForLayouts {
  KeyboardTester* tester = [[KeyboardTester alloc] init];
  tester.nextResponder = nil;

  std::vector<FlutterKeyEvent> events;
  [tester recordEmbedderEventsTo:&events returning:true];
  [tester respondChannelCallsWith:false];
  [tester respondTextInputWith:false];

  auto sendTap = [&](uint16_t keyCode, NSString* chars, NSString* charsUnmod) {
    [tester.manager handleEvent:keyDownEvent(keyCode, chars, charsUnmod)];
    [tester.manager handleEvent:keyUpEvent(keyCode)];
  };

  /* US keyboard layout */

  sendTap(kVK_ANSI_A, @"a", @"a");  // KeyA
  VERIFY_DOWN(kLogicalKeyA, "a");

  sendTap(kVK_ANSI_A, @"A", @"A");  // Shift-KeyA
  VERIFY_DOWN(kLogicalKeyA, "A");

  sendTap(kVK_ANSI_A, @"å", @"a");  // Option-KeyA
  VERIFY_DOWN(kLogicalKeyA, "å");

  sendTap(kVK_ANSI_T, @"t", @"t");  // KeyT
  VERIFY_DOWN(kLogicalKeyT, "t");

  sendTap(kVK_ANSI_1, @"1", @"1");  // Digit1
  VERIFY_DOWN(kLogicalDigit1, "1");

  sendTap(kVK_ANSI_1, @"!", @"!");  // Shift-Digit1
  VERIFY_DOWN(kLogicalDigit1, "!");

  sendTap(kVK_ANSI_Minus, @"-", @"-");  // Minus
  VERIFY_DOWN('-', "-");

  sendTap(kVK_ANSI_Minus, @"=", @"=");  // Shift-Minus
  VERIFY_DOWN('=', "=");

  /* French keyboard layout */
  [tester setLayout:kFrenchLayout];

  sendTap(kVK_ANSI_A, @"q", @"q");  // KeyA
  VERIFY_DOWN(kLogicalKeyQ, "q");

  sendTap(kVK_ANSI_A, @"Q", @"Q");  // Shift-KeyA
  VERIFY_DOWN(kLogicalKeyQ, "Q");

  sendTap(kVK_ANSI_Semicolon, @"m", @"m");  // ; but prints M
  VERIFY_DOWN(kLogicalKeyM, "m");

  sendTap(kVK_ANSI_M, @",", @",");  // M but prints ,
  VERIFY_DOWN(',', ",");

  sendTap(kVK_ANSI_1, @"&", @"&");  // Digit1
  VERIFY_DOWN(kLogicalDigit1, "&");

  sendTap(kVK_ANSI_1, @"1", @"1");  // Shift-Digit1
  VERIFY_DOWN(kLogicalDigit1, "1");

  sendTap(kVK_ANSI_Minus, @")", @")");  // Minus
  VERIFY_DOWN(')', ")");

  sendTap(kVK_ANSI_Minus, @"°", @"°");  // Shift-Minus
  VERIFY_DOWN(L'°', "°");

  /* Russian keyboard layout */
  [tester setLayout:kRussianLayout];

  sendTap(kVK_ANSI_A, @"ф", @"ф");  // KeyA
  VERIFY_DOWN(kLogicalKeyA, "ф");

  sendTap(kVK_ANSI_1, @"1", @"1");  // Digit1
  VERIFY_DOWN(kLogicalDigit1, "1");

  sendTap(kVK_ANSI_LeftBracket, @"х", @"х");
  VERIFY_DOWN(kLogicalBracketLeft, "х");

  /* Khmer keyboard layout */
  // Regression test for https://github.com/flutter/flutter/issues/108729
  [tester setLayout:kKhmerLayout];

  sendTap(kVK_ANSI_2, @"២", @"២");  // Digit2
  VERIFY_DOWN(kLogicalDigit2, "២");

  return TRUE;
}

@end
