// 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 camera;
@import camera.Test;
@import XCTest;
@import Flutter;

#import <OCMock/OCMock.h>

@interface CameraOrientationTests : XCTestCase
@end

@implementation CameraOrientationTests

- (void)testOrientationNotifications {
  id mockMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  CameraPlugin *cameraPlugin = [[CameraPlugin alloc] initWithRegistry:nil messenger:mockMessenger];

  [mockMessenger setExpectationOrderMatters:YES];

  [self rotate:UIDeviceOrientationPortraitUpsideDown
      expectedChannelOrientation:@"portraitDown"
                    cameraPlugin:cameraPlugin
                       messenger:mockMessenger];
  [self rotate:UIDeviceOrientationPortrait
      expectedChannelOrientation:@"portraitUp"
                    cameraPlugin:cameraPlugin
                       messenger:mockMessenger];
  [self rotate:UIDeviceOrientationLandscapeRight
      expectedChannelOrientation:@"landscapeLeft"
                    cameraPlugin:cameraPlugin
                       messenger:mockMessenger];
  [self rotate:UIDeviceOrientationLandscapeLeft
      expectedChannelOrientation:@"landscapeRight"
                    cameraPlugin:cameraPlugin
                       messenger:mockMessenger];

  OCMReject([mockMessenger sendOnChannel:[OCMArg any] message:[OCMArg any]]);

  // No notification when flat.
  [cameraPlugin
      orientationChanged:[self createMockNotificationForOrientation:UIDeviceOrientationFaceUp]];
  // No notification when facedown.
  [cameraPlugin
      orientationChanged:[self createMockNotificationForOrientation:UIDeviceOrientationFaceDown]];

  OCMVerifyAll(mockMessenger);
}

- (void)rotate:(UIDeviceOrientation)deviceOrientation
    expectedChannelOrientation:(NSString *)channelOrientation
                  cameraPlugin:(CameraPlugin *)cameraPlugin
                     messenger:(NSObject<FlutterBinaryMessenger> *)messenger {
  XCTestExpectation *orientationExpectation = [self expectationWithDescription:channelOrientation];

  OCMExpect([messenger
      sendOnChannel:[OCMArg any]
            message:[OCMArg checkWithBlock:^BOOL(NSData *data) {
              NSObject<FlutterMethodCodec> *codec = [FlutterStandardMethodCodec sharedInstance];
              FlutterMethodCall *methodCall = [codec decodeMethodCall:data];
              [orientationExpectation fulfill];
              return
                  [methodCall.method isEqualToString:@"orientation_changed"] &&
                  [methodCall.arguments isEqualToDictionary:@{@"orientation" : channelOrientation}];
            }]]);

  [cameraPlugin orientationChanged:[self createMockNotificationForOrientation:deviceOrientation]];
  [self waitForExpectationsWithTimeout:30.0 handler:nil];
}

- (NSNotification *)createMockNotificationForOrientation:(UIDeviceOrientation)deviceOrientation {
  UIDevice *mockDevice = OCMClassMock([UIDevice class]);
  OCMStub([mockDevice orientation]).andReturn(deviceOrientation);

  return [NSNotification notificationWithName:@"orientation_test" object:mockDevice];
}

@end
