// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h"
#import "flutter/shell/platform/darwin/ios/flutter_task_queue_dispatch.h"

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

FLUTTER_ASSERT_ARC

@interface MockBinaryMessenger : NSObject <FlutterBinaryMessenger>
@property(nonatomic, copy) NSString* channel;
@property(nonatomic, strong) NSData* message;
@property(nonatomic, strong) NSMutableDictionary<NSString*, FlutterBinaryMessageHandler>* handlers;
@end
@implementation MockBinaryMessenger
- (instancetype)init {
  self = [super init];
  if (self) {
    _handlers = [[NSMutableDictionary<NSString*, FlutterBinaryMessageHandler> alloc] init];
  }
  return self;
}

- (void)sendOnChannel:(NSString*)channel message:(NSData* _Nullable)message {
  [self sendOnChannel:channel message:message binaryReply:nil];
}

- (void)sendOnChannel:(NSString*)channel
              message:(NSData* _Nullable)message
          binaryReply:(FlutterBinaryReply _Nullable)callback {
  self.channel = channel;
  self.message = message;
}

- (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel
                                          binaryMessageHandler:
                                              (FlutterBinaryMessageHandler _Nullable)handler {
  [self.handlers setObject:handler forKey:channel];
  return 0;
}

- (void)cleanUpConnection:(FlutterBinaryMessengerConnection)connection {
}

@end

@interface FlutterChannelsTest : XCTestCase
@end

@implementation FlutterChannelsTest

- (void)testMethodInvoke {
  NSString* channelName = @"foo";
  id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  FlutterMethodChannel* channel = [[FlutterMethodChannel alloc] initWithName:channelName
                                                             binaryMessenger:binaryMessenger
                                                                       codec:codec];
  XCTAssertNotNil(channel);
  NSData* encodedMethodCall = [@"hey" dataUsingEncoding:NSUTF8StringEncoding];
  OCMStub([codec encodeMethodCall:[OCMArg any]]).andReturn(encodedMethodCall);
  [channel invokeMethod:@"foo" arguments:@[ @(1) ]];
  OCMVerify([binaryMessenger sendOnChannel:channelName message:encodedMethodCall]);
}

- (void)testMethodInvokeWithReply {
  NSString* channelName = @"foo";
  id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  FlutterMethodChannel* channel = [[FlutterMethodChannel alloc] initWithName:channelName
                                                             binaryMessenger:binaryMessenger
                                                                       codec:codec];
  XCTAssertNotNil(channel);
  NSData* encodedMethodCall = [@"hey" dataUsingEncoding:NSUTF8StringEncoding];
  OCMStub([codec encodeMethodCall:[OCMArg any]]).andReturn(encodedMethodCall);
  XCTestExpectation* didCallReply = [self expectationWithDescription:@"didCallReply"];
  OCMExpect([binaryMessenger sendOnChannel:channelName
                                   message:encodedMethodCall
                               binaryReply:[OCMArg checkWithBlock:^BOOL(id obj) {
                                 FlutterBinaryReply reply = obj;
                                 reply(nil);
                                 return YES;
                               }]]);
  [channel invokeMethod:@"foo"
              arguments:@[ @1 ]
                 result:^(id _Nullable result) {
                   [didCallReply fulfill];
                   XCTAssertEqual(FlutterMethodNotImplemented, result);
                 }];
  OCMVerifyAll(binaryMessenger);
  [self waitForExpectationsWithTimeout:1.0 handler:nil];
}

- (void)testMethodMessageHandler {
  NSString* channelName = @"foo";
  id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  FlutterMethodChannel* channel = [[FlutterMethodChannel alloc] initWithName:channelName
                                                             binaryMessenger:binaryMessenger
                                                                       codec:codec];
  XCTAssertNotNil(channel);

  NSData* encodedMethodCall = [@"hey" dataUsingEncoding:NSUTF8StringEncoding];
  OCMStub([codec encodeMethodCall:[OCMArg any]]).andReturn(encodedMethodCall);
  FlutterMethodCallHandler handler =
      ^(FlutterMethodCall* _Nonnull call, FlutterResult _Nonnull result) {
      };
  [channel setMethodCallHandler:handler];
  OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName
                                   binaryMessageHandler:[OCMArg isNotNil]]);
}

- (void)testCallMethodHandler {
  NSString* channelName = @"foo";
  MockBinaryMessenger* binaryMessenger = [[MockBinaryMessenger alloc] init];
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  FlutterMethodChannel* channel = [[FlutterMethodChannel alloc] initWithName:channelName
                                                             binaryMessenger:binaryMessenger
                                                                       codec:codec];
  XCTAssertNotNil(channel);

  NSData* encodedMethodCall = [@"encoded" dataUsingEncoding:NSUTF8StringEncoding];
  NSData* replyData = [@"reply" dataUsingEncoding:NSUTF8StringEncoding];
  NSData* replyEnvelopeData = [@"reply-envelope" dataUsingEncoding:NSUTF8StringEncoding];
  FlutterMethodCall* methodCall = [[FlutterMethodCall alloc] init];
  OCMStub([codec decodeMethodCall:encodedMethodCall]).andReturn(methodCall);
  OCMStub([codec encodeSuccessEnvelope:replyData]).andReturn(replyEnvelopeData);
  XCTestExpectation* didCallHandler = [self expectationWithDescription:@"didCallHandler"];
  XCTestExpectation* didCallReply = [self expectationWithDescription:@"didCallReply"];
  FlutterMethodCallHandler handler =
      ^(FlutterMethodCall* _Nonnull call, FlutterResult _Nonnull result) {
        XCTAssertEqual(methodCall, call);
        [didCallHandler fulfill];
        result(replyData);
      };
  [channel setMethodCallHandler:handler];
  binaryMessenger.handlers[channelName](encodedMethodCall, ^(NSData* reply) {
    [didCallReply fulfill];
    XCTAssertEqual(replyEnvelopeData, reply);
  });
  [self waitForExpectationsWithTimeout:1.0 handler:nil];
}

- (void)testResize {
  NSString* channelName = @"flutter/test";
  id binaryMessenger = OCMStrictProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  FlutterBasicMessageChannel* channel =
      [[FlutterBasicMessageChannel alloc] initWithName:channelName
                                       binaryMessenger:binaryMessenger
                                                 codec:codec];
  XCTAssertNotNil(channel);

  // The expected content was created from the following Dart code:
  //   MethodCall call = MethodCall('resize', ['flutter/test',3]);
  //   StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
  const unsigned char bytes[] = {7,   6,   114, 101, 115, 105, 122, 101, 12,  2,
                                 7,   12,  102, 108, 117, 116, 116, 101, 114, 47,
                                 116, 101, 115, 116, 3,   3,   0,   0,   0};
  NSData* expectedMessage = [NSData dataWithBytes:bytes length:sizeof(bytes)];

  OCMExpect([binaryMessenger sendOnChannel:@"dev.flutter/channel-buffers" message:expectedMessage]);
  [channel resizeChannelBuffer:3];
  OCMVerifyAll(binaryMessenger);
  [binaryMessenger stopMocking];
}

- (bool)testSetWarnsOnOverflow {
  NSString* channelName = @"flutter/test";
  id binaryMessenger = OCMStrictProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  FlutterBasicMessageChannel* channel =
      [[FlutterBasicMessageChannel alloc] initWithName:channelName
                                       binaryMessenger:binaryMessenger
                                                 codec:codec];
  XCTAssertNotNil(channel);

  // The expected content was created from the following Dart code:
  //   MethodCall call = MethodCall('overflow',['flutter/test', true]);
  //   StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
  const unsigned char bytes[] = {7,   8,   111, 118, 101, 114, 102, 108, 111, 119, 12,  2,   7, 12,
                                 102, 108, 117, 116, 116, 101, 114, 47,  116, 101, 115, 116, 1};
  NSData* expectedMessage = [NSData dataWithBytes:bytes length:sizeof(bytes)];

  OCMExpect([binaryMessenger sendOnChannel:@"dev.flutter/channel-buffers" message:expectedMessage]);
  [channel setWarnsOnOverflow:NO];
  OCMVerifyAll(binaryMessenger);
  [binaryMessenger stopMocking];
}

- (void)testBasicMessageChannelCleanup {
  NSString* channelName = @"foo";
  FlutterBinaryMessengerConnection connection = 123;
  id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  FlutterBasicMessageChannel* channel =
      [[FlutterBasicMessageChannel alloc] initWithName:channelName
                                       binaryMessenger:binaryMessenger
                                                 codec:codec];
  FlutterMessageHandler handler = ^(id _Nullable message, FlutterReply callback) {
  };
  OCMStub([binaryMessenger setMessageHandlerOnChannel:channelName
                                 binaryMessageHandler:[OCMArg any]])
      .andReturn(connection);
  [channel setMessageHandler:handler];
  OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName
                                   binaryMessageHandler:[OCMArg isNotNil]]);
  [channel setMessageHandler:nil];
  OCMVerify([binaryMessenger cleanUpConnection:connection]);
}

- (void)testMethodChannelCleanup {
  NSString* channelName = @"foo";
  FlutterBinaryMessengerConnection connection = 123;
  id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  FlutterMethodChannel* channel = [[FlutterMethodChannel alloc] initWithName:channelName
                                                             binaryMessenger:binaryMessenger
                                                                       codec:codec];
  XCTAssertNotNil(channel);

  OCMStub([binaryMessenger setMessageHandlerOnChannel:channelName
                                 binaryMessageHandler:[OCMArg any]])
      .andReturn(connection);

  FlutterMethodCallHandler handler =
      ^(FlutterMethodCall* _Nonnull call, FlutterResult _Nonnull result) {
      };
  [channel setMethodCallHandler:handler];
  OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName
                                   binaryMessageHandler:[OCMArg isNotNil]]);
  [channel setMethodCallHandler:nil];
  OCMVerify([binaryMessenger cleanUpConnection:connection]);
}

- (void)testBasicMessageChannelTaskQueue {
  NSString* channelName = @"foo";
  FlutterBinaryMessengerConnection connection = 123;
  id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  id taskQueue = OCMProtocolMock(@protocol(FlutterTaskQueueDispatch));
  FlutterBasicMessageChannel* channel =
      [[FlutterBasicMessageChannel alloc] initWithName:channelName
                                       binaryMessenger:binaryMessenger
                                                 codec:codec
                                             taskQueue:taskQueue];
  FlutterMessageHandler handler = ^(id _Nullable message, FlutterReply callback) {
  };
  OCMStub([binaryMessenger setMessageHandlerOnChannel:channelName
                                 binaryMessageHandler:[OCMArg any]
                                            taskQueue:taskQueue])
      .andReturn(connection);
  [channel setMessageHandler:handler];
  OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName
                                   binaryMessageHandler:[OCMArg isNotNil]
                                              taskQueue:taskQueue]);
  [channel setMessageHandler:nil];
  OCMVerify([binaryMessenger cleanUpConnection:connection]);
}

- (void)testBasicMessageChannelInvokeHandlerAfterChannelReleased {
  NSString* channelName = @"foo";
  __block NSString* handlerMessage;
  __block FlutterBinaryMessageHandler messageHandler;
  @autoreleasepool {
    FlutterBinaryMessengerConnection connection = 123;
    id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
    id codec = OCMProtocolMock(@protocol(FlutterMessageCodec));
    id taskQueue = OCMProtocolMock(@protocol(FlutterTaskQueueDispatch));
    FlutterBasicMessageChannel* channel =
        [[FlutterBasicMessageChannel alloc] initWithName:channelName
                                         binaryMessenger:binaryMessenger
                                                   codec:codec
                                               taskQueue:taskQueue];

    FlutterMessageHandler handler = ^(id _Nullable message, FlutterReply callback) {
      handlerMessage = message;
    };
    OCMStub([binaryMessenger
                setMessageHandlerOnChannel:channelName
                      binaryMessageHandler:[OCMArg checkWithBlock:^BOOL(
                                                       FlutterBinaryMessageHandler handler) {
                        messageHandler = handler;
                        return YES;
                      }]
                                 taskQueue:taskQueue])
        .andReturn(connection);
    OCMStub([codec decode:[OCMArg any]]).andReturn(@"decoded message");
    [channel setMessageHandler:handler];
  }
  // Channel is released, messageHandler should still retain the codec. The codec
  // internally makes a `decode` call and updates the `handlerMessage` to "decoded message".
  messageHandler([NSData data], ^(NSData* data){
                 });
  XCTAssertEqualObjects(handlerMessage, @"decoded message");
}

- (void)testMethodChannelInvokeHandlerAfterChannelReleased {
  NSString* channelName = @"foo";
  FlutterBinaryMessengerConnection connection = 123;
  __block FlutterMethodCall* decodedMethodCall;
  __block FlutterBinaryMessageHandler messageHandler;
  @autoreleasepool {
    id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
    id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
    id taskQueue = OCMProtocolMock(@protocol(FlutterTaskQueueDispatch));
    FlutterMethodChannel* channel = [[FlutterMethodChannel alloc] initWithName:channelName
                                                               binaryMessenger:binaryMessenger
                                                                         codec:codec
                                                                     taskQueue:taskQueue];
    FlutterMethodCallHandler handler = ^(FlutterMethodCall* call, FlutterResult result) {
      decodedMethodCall = call;
    };
    OCMStub([binaryMessenger
                setMessageHandlerOnChannel:channelName
                      binaryMessageHandler:[OCMArg checkWithBlock:^BOOL(
                                                       FlutterBinaryMessageHandler handler) {
                        messageHandler = handler;
                        return YES;
                      }]
                                 taskQueue:taskQueue])
        .andReturn(connection);
    OCMStub([codec decodeMethodCall:[OCMArg any]])
        .andReturn([FlutterMethodCall methodCallWithMethodName:@"decoded method call"
                                                     arguments:nil]);
    [channel setMethodCallHandler:handler];
  }
  messageHandler([NSData data], ^(NSData* data){
                 });
  XCTAssertEqualObjects(decodedMethodCall.method, @"decoded method call");
}

- (void)testMethodChannelTaskQueue {
  NSString* channelName = @"foo";
  FlutterBinaryMessengerConnection connection = 123;
  id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  id taskQueue = OCMProtocolMock(@protocol(FlutterTaskQueueDispatch));
  FlutterMethodChannel* channel = [[FlutterMethodChannel alloc] initWithName:channelName
                                                             binaryMessenger:binaryMessenger
                                                                       codec:codec
                                                                   taskQueue:taskQueue];
  XCTAssertNotNil(channel);
  FlutterMethodCallHandler handler = ^(FlutterMethodCall* call, FlutterResult result) {
  };
  OCMStub([binaryMessenger setMessageHandlerOnChannel:channelName
                                 binaryMessageHandler:[OCMArg any]
                                            taskQueue:taskQueue])
      .andReturn(connection);
  [channel setMethodCallHandler:handler];
  OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName
                                   binaryMessageHandler:[OCMArg isNotNil]
                                              taskQueue:taskQueue]);
  [channel setMethodCallHandler:nil];
  OCMVerify([binaryMessenger cleanUpConnection:connection]);
}

- (void)testEventChannelTaskQueue {
  NSString* channelName = @"foo";
  FlutterBinaryMessengerConnection connection = 123;
  id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  id taskQueue = OCMProtocolMock(@protocol(FlutterTaskQueueDispatch));
  id handler = OCMProtocolMock(@protocol(FlutterStreamHandler));
  FlutterEventChannel* channel = [[FlutterEventChannel alloc] initWithName:channelName
                                                           binaryMessenger:binaryMessenger
                                                                     codec:codec
                                                                 taskQueue:taskQueue];
  XCTAssertNotNil(channel);
  OCMStub([binaryMessenger setMessageHandlerOnChannel:channelName
                                 binaryMessageHandler:[OCMArg any]
                                            taskQueue:taskQueue])
      .andReturn(connection);
  [channel setStreamHandler:handler];
  OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName
                                   binaryMessageHandler:[OCMArg isNotNil]
                                              taskQueue:taskQueue]);
  [channel setStreamHandler:nil];
  OCMVerify([binaryMessenger cleanUpConnection:connection]);
}

@end
