// 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 AVFoundation;
@import XCTest;
#import <OCMock/OCMock.h>
#import "CameraTestUtils.h"

@interface CameraPermissionTests : XCTestCase

@end

@implementation CameraPermissionTests

- (void)testRequestCameraPermission_completeWithoutErrorIfPrevoiuslyAuthorized {
  XCTestExpectation *expectation =
      [self expectationWithDescription:
                @"Must copmlete without error if camera access was previously authorized."];

  id mockDevice = OCMClassMock([AVCaptureDevice class]);
  OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeVideo])
      .andReturn(AVAuthorizationStatusAuthorized);

  FLTRequestCameraPermissionWithCompletionHandler(^(FlutterError *error) {
    if (error == nil) {
      [expectation fulfill];
    }
  });
  [self waitForExpectationsWithTimeout:1 handler:nil];
}
- (void)testRequestCameraPermission_completeWithErrorIfPreviouslyDenied {
  XCTestExpectation *expectation =
      [self expectationWithDescription:
                @"Must complete with error if camera access was previously denied."];
  FlutterError *expectedError =
      [FlutterError errorWithCode:@"CameraAccessDeniedWithoutPrompt"
                          message:@"User has previously denied the camera access request. Go to "
                                  @"Settings to enable camera access."
                          details:nil];

  id mockDevice = OCMClassMock([AVCaptureDevice class]);
  OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeVideo])
      .andReturn(AVAuthorizationStatusDenied);
  FLTRequestCameraPermissionWithCompletionHandler(^(FlutterError *error) {
    if ([error isEqual:expectedError]) {
      [expectation fulfill];
    }
  });
  [self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)testRequestCameraPermission_completeWithErrorIfRestricted {
  XCTestExpectation *expectation =
      [self expectationWithDescription:@"Must complete with error if camera access is restricted."];
  FlutterError *expectedError = [FlutterError errorWithCode:@"CameraAccessRestricted"
                                                    message:@"Camera access is restricted. "
                                                    details:nil];

  id mockDevice = OCMClassMock([AVCaptureDevice class]);
  OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeVideo])
      .andReturn(AVAuthorizationStatusRestricted);

  FLTRequestCameraPermissionWithCompletionHandler(^(FlutterError *error) {
    if ([error isEqual:expectedError]) {
      [expectation fulfill];
    }
  });
  [self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)testRequestCameraPermission_completeWithoutErrorIfUserGrantAccess {
  XCTestExpectation *grantedExpectation = [self
      expectationWithDescription:@"Must complete without error if user choose to grant access"];

  id mockDevice = OCMClassMock([AVCaptureDevice class]);
  OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeVideo])
      .andReturn(AVAuthorizationStatusNotDetermined);
  // Mimic user choosing "allow" in permission dialog.
  OCMStub([mockDevice requestAccessForMediaType:AVMediaTypeVideo
                              completionHandler:[OCMArg checkWithBlock:^BOOL(void (^block)(BOOL)) {
                                block(YES);
                                return YES;
                              }]]);

  FLTRequestCameraPermissionWithCompletionHandler(^(FlutterError *error) {
    if (error == nil) {
      [grantedExpectation fulfill];
    }
  });
  [self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)testRequestCameraPermission_completeWithErrorIfUserDenyAccess {
  XCTestExpectation *expectation =
      [self expectationWithDescription:@"Must complete with error if user choose to deny access"];
  FlutterError *expectedError =
      [FlutterError errorWithCode:@"CameraAccessDenied"
                          message:@"User denied the camera access request."
                          details:nil];

  id mockDevice = OCMClassMock([AVCaptureDevice class]);
  OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeVideo])
      .andReturn(AVAuthorizationStatusNotDetermined);

  // Mimic user choosing "deny" in permission dialog.
  OCMStub([mockDevice requestAccessForMediaType:AVMediaTypeVideo
                              completionHandler:[OCMArg checkWithBlock:^BOOL(void (^block)(BOOL)) {
                                block(NO);
                                return YES;
                              }]]);
  FLTRequestCameraPermissionWithCompletionHandler(^(FlutterError *error) {
    if ([error isEqual:expectedError]) {
      [expectation fulfill];
    }
  });

  [self waitForExpectationsWithTimeout:1 handler:nil];
}

@end
