// 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 <OCMock/OCMock.h>
#import <XCTest/XCTest.h>
#import "FIAPaymentQueueHandler.h"
#import "Stubs.h"

@import in_app_purchase_ios;

@interface InAppPurchasePluginTest : XCTestCase

@property(strong, nonatomic) FIAPReceiptManagerStub* receiptManagerStub;
@property(strong, nonatomic) InAppPurchasePlugin* plugin;

@end

@implementation InAppPurchasePluginTest

- (void)setUp {
  self.receiptManagerStub = [FIAPReceiptManagerStub new];
  self.plugin = [[InAppPurchasePluginStub alloc] initWithReceiptManager:self.receiptManagerStub];
}

- (void)tearDown {
}

- (void)testInvalidMethodCall {
  XCTestExpectation* expectation =
      [self expectationWithDescription:@"expect result to be not implemented"];
  FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"invalid" arguments:NULL];
  __block id result;
  [self.plugin handleMethodCall:call
                         result:^(id r) {
                           [expectation fulfill];
                           result = r;
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssertEqual(result, FlutterMethodNotImplemented);
}

- (void)testCanMakePayments {
  XCTestExpectation* expectation = [self expectationWithDescription:@"expect result to be YES"];
  FlutterMethodCall* call =
      [FlutterMethodCall methodCallWithMethodName:@"-[SKPaymentQueue canMakePayments:]"
                                        arguments:NULL];
  __block id result;
  [self.plugin handleMethodCall:call
                         result:^(id r) {
                           [expectation fulfill];
                           result = r;
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssertEqual(result, @YES);
}

- (void)testGetProductResponse {
  XCTestExpectation* expectation =
      [self expectationWithDescription:@"expect response contains 1 item"];
  FlutterMethodCall* call = [FlutterMethodCall
      methodCallWithMethodName:@"-[InAppPurchasePlugin startProductRequest:result:]"
                     arguments:@[ @"123" ]];
  __block id result;
  [self.plugin handleMethodCall:call
                         result:^(id r) {
                           [expectation fulfill];
                           result = r;
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssert([result isKindOfClass:[NSDictionary class]]);
  NSArray* resultArray = [result objectForKey:@"products"];
  XCTAssertEqual(resultArray.count, 1);
  XCTAssertTrue([resultArray.firstObject[@"productIdentifier"] isEqualToString:@"123"]);
}

- (void)testAddPaymentFailure {
  XCTestExpectation* expectation =
      [self expectationWithDescription:@"result should return failed state"];
  FlutterMethodCall* call =
      [FlutterMethodCall methodCallWithMethodName:@"-[InAppPurchasePlugin addPayment:result:]"
                                        arguments:@{
                                          @"productIdentifier" : @"123",
                                          @"quantity" : @(1),
                                          @"simulatesAskToBuyInSandbox" : @YES,
                                        }];
  SKPaymentQueueStub* queue = [SKPaymentQueueStub new];
  queue.testState = SKPaymentTransactionStateFailed;
  __block SKPaymentTransaction* transactionForUpdateBlock;
  self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue
      transactionsUpdated:^(NSArray<SKPaymentTransaction*>* _Nonnull transactions) {
        SKPaymentTransaction* transaction = transactions[0];
        if (transaction.transactionState == SKPaymentTransactionStateFailed) {
          transactionForUpdateBlock = transaction;
          [expectation fulfill];
        }
      }
      transactionRemoved:nil
      restoreTransactionFailed:nil
      restoreCompletedTransactionsFinished:nil
      shouldAddStorePayment:^BOOL(SKPayment* _Nonnull payment, SKProduct* _Nonnull product) {
        return YES;
      }
      updatedDownloads:nil];
  [queue addTransactionObserver:self.plugin.paymentQueueHandler];

  [self.plugin handleMethodCall:call
                         result:^(id r){
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssertEqual(transactionForUpdateBlock.transactionState, SKPaymentTransactionStateFailed);
}

- (void)testAddPaymentSuccessWithoutPaymentDiscount {
  XCTestExpectation* expectation =
      [self expectationWithDescription:@"result should return success state"];
  FlutterMethodCall* call =
      [FlutterMethodCall methodCallWithMethodName:@"-[InAppPurchasePlugin addPayment:result:]"
                                        arguments:@{
                                          @"productIdentifier" : @"123",
                                          @"quantity" : @(1),
                                          @"simulatesAskToBuyInSandbox" : @YES,
                                        }];
  SKPaymentQueueStub* queue = [SKPaymentQueueStub new];
  queue.testState = SKPaymentTransactionStatePurchased;
  __block SKPaymentTransaction* transactionForUpdateBlock;
  self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue
      transactionsUpdated:^(NSArray<SKPaymentTransaction*>* _Nonnull transactions) {
        SKPaymentTransaction* transaction = transactions[0];
        if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
          transactionForUpdateBlock = transaction;
          if (@available(iOS 12.2, *)) {
            XCTAssertNil(transaction.payment.paymentDiscount);
          }
          [expectation fulfill];
        }
      }
      transactionRemoved:nil
      restoreTransactionFailed:nil
      restoreCompletedTransactionsFinished:nil
      shouldAddStorePayment:^BOOL(SKPayment* _Nonnull payment, SKProduct* _Nonnull product) {
        return YES;
      }
      updatedDownloads:nil];
  [queue addTransactionObserver:self.plugin.paymentQueueHandler];
  [self.plugin handleMethodCall:call
                         result:^(id r){
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssertEqual(transactionForUpdateBlock.transactionState, SKPaymentTransactionStatePurchased);
}

- (void)testAddPaymentSuccessWithPaymentDiscount {
  XCTestExpectation* expectation =
      [self expectationWithDescription:@"result should return success state"];
  FlutterMethodCall* call =
      [FlutterMethodCall methodCallWithMethodName:@"-[InAppPurchasePlugin addPayment:result:]"
                                        arguments:@{
                                          @"productIdentifier" : @"123",
                                          @"quantity" : @(1),
                                          @"simulatesAskToBuyInSandbox" : @YES,
                                          @"paymentDiscount" : @{
                                            @"identifier" : @"test_identifier",
                                            @"keyIdentifier" : @"test_key_identifier",
                                            @"nonce" : @"4a11a9cc-3bc3-11ec-8d3d-0242ac130003",
                                            @"signature" : @"test_signature",
                                            @"timestamp" : @(1635847102),
                                          }
                                        }];
  SKPaymentQueueStub* queue = [SKPaymentQueueStub new];
  queue.testState = SKPaymentTransactionStatePurchased;
  __block SKPaymentTransaction* transactionForUpdateBlock;
  self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue
      transactionsUpdated:^(NSArray<SKPaymentTransaction*>* _Nonnull transactions) {
        SKPaymentTransaction* transaction = transactions[0];
        if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
          transactionForUpdateBlock = transaction;
          if (@available(iOS 12.2, *)) {
            SKPaymentDiscount* paymentDiscount = transaction.payment.paymentDiscount;
            XCTAssertEqual(paymentDiscount.identifier, @"test_identifier");
            XCTAssertEqual(paymentDiscount.keyIdentifier, @"test_key_identifier");
            XCTAssertEqualObjects(
                paymentDiscount.nonce,
                [[NSUUID alloc] initWithUUIDString:@"4a11a9cc-3bc3-11ec-8d3d-0242ac130003"]);
            XCTAssertEqual(paymentDiscount.signature, @"test_signature");
            XCTAssertEqual(paymentDiscount.timestamp, @(1635847102));
          }
          [expectation fulfill];
        }
      }
      transactionRemoved:nil
      restoreTransactionFailed:nil
      restoreCompletedTransactionsFinished:nil
      shouldAddStorePayment:^BOOL(SKPayment* _Nonnull payment, SKProduct* _Nonnull product) {
        return YES;
      }
      updatedDownloads:nil];
  [queue addTransactionObserver:self.plugin.paymentQueueHandler];
  [self.plugin handleMethodCall:call
                         result:^(id r){
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssertEqual(transactionForUpdateBlock.transactionState, SKPaymentTransactionStatePurchased);
}

- (void)testAddPaymentFailureWithInvalidPaymentDiscount {
  XCTestExpectation* expectation =
      [self expectationWithDescription:@"result should return success state"];
  FlutterMethodCall* call =
      [FlutterMethodCall methodCallWithMethodName:@"-[InAppPurchasePlugin addPayment:result:]"
                                        arguments:@{
                                          @"productIdentifier" : @"123",
                                          @"quantity" : @(1),
                                          @"simulatesAskToBuyInSandbox" : @YES,
                                          @"paymentDiscount" : @{
                                            @"keyIdentifier" : @"test_key_identifier",
                                            @"nonce" : @"4a11a9cc-3bc3-11ec-8d3d-0242ac130003",
                                            @"signature" : @"test_signature",
                                            @"timestamp" : @(1635847102),
                                          }
                                        }];

  [self.plugin
      handleMethodCall:call
                result:^(id r) {
                  XCTAssertTrue([r isKindOfClass:FlutterError.class]);
                  FlutterError* result = r;
                  XCTAssertEqualObjects(result.code, @"storekit_invalid_payment_discount_object");
                  XCTAssertEqualObjects(result.message,
                                        @"You have requested a payment and specified a payment "
                                        @"discount with invalid properties. When specifying a "
                                        @"payment discount the 'identifier' field is mandatory.");
                  XCTAssertEqualObjects(result.details, call.arguments);
                  [expectation fulfill];
                }];

  [self waitForExpectations:@[ expectation ] timeout:5];
}

- (void)testAddPaymentWithNullSandboxArgument {
  XCTestExpectation* expectation =
      [self expectationWithDescription:@"result should return success state"];
  XCTestExpectation* simulatesAskToBuyInSandboxExpectation =
      [self expectationWithDescription:@"payment isn't simulatesAskToBuyInSandbox"];
  FlutterMethodCall* call =
      [FlutterMethodCall methodCallWithMethodName:@"-[InAppPurchasePlugin addPayment:result:]"
                                        arguments:@{
                                          @"productIdentifier" : @"123",
                                          @"quantity" : @(1),
                                          @"simulatesAskToBuyInSandbox" : [NSNull null],
                                        }];
  SKPaymentQueueStub* queue = [SKPaymentQueueStub new];
  queue.testState = SKPaymentTransactionStatePurchased;
  __block SKPaymentTransaction* transactionForUpdateBlock;
  self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue
      transactionsUpdated:^(NSArray<SKPaymentTransaction*>* _Nonnull transactions) {
        SKPaymentTransaction* transaction = transactions[0];
        if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
          transactionForUpdateBlock = transaction;
          [expectation fulfill];
        }
        if (!transaction.payment.simulatesAskToBuyInSandbox) {
          [simulatesAskToBuyInSandboxExpectation fulfill];
        }
      }
      transactionRemoved:nil
      restoreTransactionFailed:nil
      restoreCompletedTransactionsFinished:nil
      shouldAddStorePayment:^BOOL(SKPayment* _Nonnull payment, SKProduct* _Nonnull product) {
        return YES;
      }
      updatedDownloads:nil];
  [queue addTransactionObserver:self.plugin.paymentQueueHandler];
  [self.plugin handleMethodCall:call
                         result:^(id r){
                         }];
  [self waitForExpectations:@[ expectation, simulatesAskToBuyInSandboxExpectation ] timeout:5];
  XCTAssertEqual(transactionForUpdateBlock.transactionState, SKPaymentTransactionStatePurchased);
}

- (void)testRestoreTransactions {
  XCTestExpectation* expectation =
      [self expectationWithDescription:@"result successfully restore transactions"];
  FlutterMethodCall* call = [FlutterMethodCall
      methodCallWithMethodName:@"-[InAppPurchasePlugin restoreTransactions:result:]"
                     arguments:nil];
  SKPaymentQueueStub* queue = [SKPaymentQueueStub new];
  queue.testState = SKPaymentTransactionStatePurchased;
  __block BOOL callbackInvoked = NO;
  self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:queue
      transactionsUpdated:^(NSArray<SKPaymentTransaction*>* _Nonnull transactions) {
      }
      transactionRemoved:nil
      restoreTransactionFailed:nil
      restoreCompletedTransactionsFinished:^() {
        callbackInvoked = YES;
        [expectation fulfill];
      }
      shouldAddStorePayment:nil
      updatedDownloads:nil];
  [queue addTransactionObserver:self.plugin.paymentQueueHandler];
  [self.plugin handleMethodCall:call
                         result:^(id r){
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssertTrue(callbackInvoked);
}

- (void)testRetrieveReceiptDataSuccess {
  XCTestExpectation* expectation = [self expectationWithDescription:@"receipt data retrieved"];
  FlutterMethodCall* call = [FlutterMethodCall
      methodCallWithMethodName:@"-[InAppPurchasePlugin retrieveReceiptData:result:]"
                     arguments:nil];
  __block NSDictionary* result;
  [self.plugin handleMethodCall:call
                         result:^(id r) {
                           result = r;
                           [expectation fulfill];
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssertNotNil(result);
  XCTAssert([result isKindOfClass:[NSString class]]);
}

- (void)testRetrieveReceiptDataError {
  XCTestExpectation* expectation = [self expectationWithDescription:@"receipt data retrieved"];
  FlutterMethodCall* call = [FlutterMethodCall
      methodCallWithMethodName:@"-[InAppPurchasePlugin retrieveReceiptData:result:]"
                     arguments:nil];
  __block NSDictionary* result;
  self.receiptManagerStub.returnError = YES;
  [self.plugin handleMethodCall:call
                         result:^(id r) {
                           result = r;
                           [expectation fulfill];
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssertNotNil(result);
  XCTAssert([result isKindOfClass:[FlutterError class]]);
  NSDictionary* details = ((FlutterError*)result).details;
  XCTAssertNotNil(details[@"error"]);
  NSNumber* errorCode = (NSNumber*)details[@"error"][@"code"];
  XCTAssertEqual(errorCode, [NSNumber numberWithInteger:99]);
}

- (void)testRefreshReceiptRequest {
  XCTestExpectation* expectation = [self expectationWithDescription:@"expect success"];
  FlutterMethodCall* call =
      [FlutterMethodCall methodCallWithMethodName:@"-[InAppPurchasePlugin refreshReceipt:result:]"
                                        arguments:nil];
  __block BOOL result = NO;
  [self.plugin handleMethodCall:call
                         result:^(id r) {
                           result = YES;
                           [expectation fulfill];
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssertTrue(result);
}

- (void)testPresentCodeRedemptionSheet {
  XCTestExpectation* expectation =
      [self expectationWithDescription:@"expect successfully present Code Redemption Sheet"];
  FlutterMethodCall* call = [FlutterMethodCall
      methodCallWithMethodName:@"-[InAppPurchasePlugin presentCodeRedemptionSheet:result:]"
                     arguments:nil];
  __block BOOL callbackInvoked = NO;
  [self.plugin handleMethodCall:call
                         result:^(id r) {
                           callbackInvoked = YES;
                           [expectation fulfill];
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssertTrue(callbackInvoked);
}

- (void)testGetPendingTransactions {
  XCTestExpectation* expectation = [self expectationWithDescription:@"expect success"];
  FlutterMethodCall* call =
      [FlutterMethodCall methodCallWithMethodName:@"-[SKPaymentQueue transactions]" arguments:nil];
  SKPaymentQueue* mockQueue = OCMClassMock(SKPaymentQueue.class);
  NSDictionary* transactionMap = @{
    @"transactionIdentifier" : [NSNull null],
    @"transactionState" : @(SKPaymentTransactionStatePurchasing),
    @"payment" : [NSNull null],
    @"error" : [FIAObjectTranslator getMapFromNSError:[NSError errorWithDomain:@"test_stub"
                                                                          code:123
                                                                      userInfo:@{}]],
    @"transactionTimeStamp" : @([NSDate date].timeIntervalSince1970),
    @"originalTransaction" : [NSNull null],
  };
  OCMStub(mockQueue.transactions).andReturn(@[ [[SKPaymentTransactionStub alloc]
      initWithMap:transactionMap] ]);

  __block NSArray* resultArray;
  self.plugin.paymentQueueHandler = [[FIAPaymentQueueHandler alloc] initWithQueue:mockQueue
                                                              transactionsUpdated:nil
                                                               transactionRemoved:nil
                                                         restoreTransactionFailed:nil
                                             restoreCompletedTransactionsFinished:nil
                                                            shouldAddStorePayment:nil
                                                                 updatedDownloads:nil];
  [self.plugin handleMethodCall:call
                         result:^(id r) {
                           resultArray = r;
                           [expectation fulfill];
                         }];
  [self waitForExpectations:@[ expectation ] timeout:5];
  XCTAssertEqualObjects(resultArray, @[ transactionMap ]);
}

- (void)testStartAndStopObservingPaymentQueue {
  FlutterMethodCall* startCall = [FlutterMethodCall
      methodCallWithMethodName:@"-[SKPaymentQueue startObservingTransactionQueue]"
                     arguments:nil];
  FlutterMethodCall* stopCall =
      [FlutterMethodCall methodCallWithMethodName:@"-[SKPaymentQueue stopObservingTransactionQueue]"
                                        arguments:nil];

  SKPaymentQueueStub* queue = [SKPaymentQueueStub new];

  self.plugin.paymentQueueHandler =
      [[FIAPaymentQueueHandler alloc] initWithQueue:queue
                                transactionsUpdated:nil
                                 transactionRemoved:nil
                           restoreTransactionFailed:nil
               restoreCompletedTransactionsFinished:nil
                              shouldAddStorePayment:^BOOL(SKPayment* _Nonnull payment,
                                                          SKProduct* _Nonnull product) {
                                return YES;
                              }
                                   updatedDownloads:nil];

  // Check that there is no observer to start with.
  XCTAssertNil(queue.observer);

  // Start observing
  [self.plugin handleMethodCall:startCall
                         result:^(id r){
                         }];

  // Observer should be set
  XCTAssertNotNil(queue.observer);

  // Stop observing
  [self.plugin handleMethodCall:stopCall
                         result:^(id r){
                         }];

  // No observer should be set
  XCTAssertNil(queue.observer);
}

- (void)testRegisterPaymentQueueDelegate {
  if (@available(iOS 13, *)) {
    FlutterMethodCall* call =
        [FlutterMethodCall methodCallWithMethodName:@"-[SKPaymentQueue registerDelegate]"
                                          arguments:nil];

    self.plugin.paymentQueueHandler =
        [[FIAPaymentQueueHandler alloc] initWithQueue:[SKPaymentQueueStub new]
                                  transactionsUpdated:nil
                                   transactionRemoved:nil
                             restoreTransactionFailed:nil
                 restoreCompletedTransactionsFinished:nil
                                shouldAddStorePayment:nil
                                     updatedDownloads:nil];

    // Verify the delegate is nil before we register one.
    XCTAssertNil(self.plugin.paymentQueueHandler.delegate);

    [self.plugin handleMethodCall:call
                           result:^(id r){
                           }];

    // Verify the delegate is not nil after we registered one.
    XCTAssertNotNil(self.plugin.paymentQueueHandler.delegate);
  }
}

- (void)testRemovePaymentQueueDelegate {
  if (@available(iOS 13, *)) {
    FlutterMethodCall* call =
        [FlutterMethodCall methodCallWithMethodName:@"-[SKPaymentQueue removeDelegate]"
                                          arguments:nil];

    self.plugin.paymentQueueHandler =
        [[FIAPaymentQueueHandler alloc] initWithQueue:[SKPaymentQueueStub new]
                                  transactionsUpdated:nil
                                   transactionRemoved:nil
                             restoreTransactionFailed:nil
                 restoreCompletedTransactionsFinished:nil
                                shouldAddStorePayment:nil
                                     updatedDownloads:nil];
    self.plugin.paymentQueueHandler.delegate = OCMProtocolMock(@protocol(SKPaymentQueueDelegate));

    // Verify the delegate is not nil before removing it.
    XCTAssertNotNil(self.plugin.paymentQueueHandler.delegate);

    [self.plugin handleMethodCall:call
                           result:^(id r){
                           }];

    // Verify the delegate is nill after removing it.
    XCTAssertNil(self.plugin.paymentQueueHandler.delegate);
  }
}

- (void)testShowPriceConsentIfNeeded {
  FlutterMethodCall* call =
      [FlutterMethodCall methodCallWithMethodName:@"-[SKPaymentQueue showPriceConsentIfNeeded]"
                                        arguments:nil];

  FIAPaymentQueueHandler* mockQueueHandler = OCMClassMock(FIAPaymentQueueHandler.class);
  self.plugin.paymentQueueHandler = mockQueueHandler;

  [self.plugin handleMethodCall:call
                         result:^(id r){
                         }];

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpartial-availability"
  if (@available(iOS 13.4, *)) {
    OCMVerify(times(1), [mockQueueHandler showPriceConsentIfNeeded]);
  } else {
    OCMVerify(never(), [mockQueueHandler showPriceConsentIfNeeded]);
  }
#pragma clang diagnostic pop
}

@end
