// 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 <Foundation/Foundation.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/Source/FlutterChannelKeyResponder.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFakeKeyEvents.h"

FLUTTER_ASSERT_ARC;

#define XCTAssertStrEqual(value, expected)        \
  XCTAssertTrue([value isEqualToString:expected], \
                @"String \"%@\" not equal to the expected value of \"%@\"", value, expected)

namespace {
API_AVAILABLE(ios(13.4))
constexpr UIKeyboardHIDUsage keyACode = (UIKeyboardHIDUsage)0x4;  // KeyA iOS scan code.
}  // namespace

API_AVAILABLE(ios(13.4))
@interface FlutterChannelKeyResponderTest : XCTestCase
@property(copy, nonatomic) FlutterUIPressProxy* testKeyDownEvent API_AVAILABLE(ios(13.4));
@property(copy, nonatomic) FlutterUIPressProxy* testKeyUpEvent API_AVAILABLE(ios(13.4));
@end

@implementation FlutterChannelKeyResponderTest

- (void)setUp API_AVAILABLE(ios(13.4)) {
  _testKeyDownEvent = keyDownEvent(keyACode, 0x0, 0.0f, "a", "a");
  _testKeyUpEvent = keyUpEvent(keyACode, 0x0, 0.0f);
}

- (void)tearDown API_AVAILABLE(ios(13.4)) {
  _testKeyDownEvent = nil;
  _testKeyUpEvent = nil;
}

- (void)testBasicKeyEvent API_AVAILABLE(ios(13.4)) {
  __block NSMutableArray<id>* messages = [[NSMutableArray<id> alloc] init];
  __block BOOL next_response = TRUE;
  __block NSMutableArray<NSNumber*>* responses = [[NSMutableArray<NSNumber*> alloc] init];

  id mockKeyEventChannel = OCMStrictClassMock([FlutterBasicMessageChannel class]);
  OCMStub([mockKeyEventChannel sendMessage:[OCMArg any] reply:[OCMArg any]])
      .andDo((^(NSInvocation* invocation) {
        [invocation retainArguments];
        NSDictionary* message;
        [invocation getArgument:&message atIndex:2];
        [messages addObject:message];

        FlutterReply callback;
        [invocation getArgument:&callback atIndex:3];
        NSDictionary* keyMessage = @{
          @"handled" : @(next_response),
        };
        callback(keyMessage);
      }));

  // Key down
  FlutterChannelKeyResponder* responder =
      [[FlutterChannelKeyResponder alloc] initWithChannel:mockKeyEventChannel];
  [responder handlePress:_testKeyDownEvent
                callback:^(BOOL handled) {
                  [responses addObject:@(handled)];
                }];

  XCTAssertEqual([messages count], 1u);
  XCTAssertEqual([messages lastObject][@"keymap"], @"ios");
  XCTAssertEqual([messages lastObject][@"type"], @"keydown");
  XCTAssertEqual([[messages lastObject][@"keyCode"] intValue], keyACode);
  XCTAssertEqual([[messages lastObject][@"modifiers"] intValue], 0x0);
  XCTAssertStrEqual([messages lastObject][@"characters"], @"a");
  XCTAssertStrEqual([messages lastObject][@"charactersIgnoringModifiers"], @"a");

  XCTAssertEqual([responses count], 1u);
  XCTAssertEqual([[responses lastObject] boolValue], TRUE);

  [messages removeAllObjects];
  [responses removeAllObjects];

  // Key up
  next_response = FALSE;
  [responder handlePress:_testKeyUpEvent
                callback:^(BOOL handled) {
                  [responses addObject:@(handled)];
                }];

  XCTAssertEqual([messages count], 1u);
  XCTAssertEqual([messages lastObject][@"keymap"], @"ios");
  XCTAssertEqual([messages lastObject][@"type"], @"keyup");
  XCTAssertEqual([[messages lastObject][@"keyCode"] intValue], keyACode);
  XCTAssertEqual([[messages lastObject][@"modifiers"] intValue], 0x0);

  XCTAssertEqual([responses count], 1u);
  XCTAssertEqual([[responses lastObject] boolValue], FALSE);

  [messages removeAllObjects];
  [responses removeAllObjects];
}

- (void)testEmptyResponseIsTakenAsHandled API_AVAILABLE(ios(13.4)) {
  __block NSMutableArray<id>* messages = [[NSMutableArray<id> alloc] init];
  __block NSMutableArray<NSNumber*>* responses = [[NSMutableArray<NSNumber*> alloc] init];

  id mockKeyEventChannel = OCMStrictClassMock([FlutterBasicMessageChannel class]);
  OCMStub([mockKeyEventChannel sendMessage:[OCMArg any] reply:[OCMArg any]])
      .andDo((^(NSInvocation* invocation) {
        [invocation retainArguments];
        NSDictionary* message;
        [invocation getArgument:&message atIndex:2];
        [messages addObject:message];

        FlutterReply callback;
        [invocation getArgument:&callback atIndex:3];
        callback(nullptr);
      }));

  FlutterChannelKeyResponder* responder =
      [[FlutterChannelKeyResponder alloc] initWithChannel:mockKeyEventChannel];
  [responder handlePress:_testKeyDownEvent
                callback:^(BOOL handled) {
                  [responses addObject:@(handled)];
                }];

  XCTAssertEqual([messages count], 1u);
  XCTAssertEqual([messages lastObject][@"keymap"], @"ios");
  XCTAssertEqual([messages lastObject][@"type"], @"keydown");
  XCTAssertEqual([[messages lastObject][@"keyCode"] intValue], keyACode);
  XCTAssertEqual([[messages lastObject][@"modifiers"] intValue], 0x0);
  XCTAssertStrEqual([messages lastObject][@"characters"], @"a");
  XCTAssertStrEqual([messages lastObject][@"charactersIgnoringModifiers"], @"a");

  XCTAssertEqual([responses count], 1u);
  XCTAssertEqual([[responses lastObject] boolValue], TRUE);
}

@end
