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

#if !__has_feature(objc_arc)
#error ARC must be enabled!
#endif

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

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

@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 = @"foo";
  id binaryMessenger = OCMStrictProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  FlutterBasicMessageChannel* channel =
      [[FlutterBasicMessageChannel alloc] initWithName:channelName
                                       binaryMessenger:binaryMessenger
                                                 codec:codec];
  XCTAssertNotNil(channel);

  NSString* expectedMessageString =
      [NSString stringWithFormat:@"resize\r%@\r%@", channelName, @100];
  NSData* expectedMessage = [expectedMessageString dataUsingEncoding:NSUTF8StringEncoding];
  OCMExpect([binaryMessenger sendOnChannel:@"dev.flutter/channel-buffers" message:expectedMessage]);
  [channel resizeChannelBuffer:100];
  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 = OCMClassMock([NSObject class]);
  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)testMethodChannelTaskQueue {
  NSString* channelName = @"foo";
  FlutterBinaryMessengerConnection connection = 123;
  id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
  id taskQueue = OCMClassMock([NSObject class]);
  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 = OCMClassMock([NSObject class]);
  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
