// 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 'package:in_app_purchase_android/billing_client_wrappers.dart';
import 'package:in_app_purchase_android/in_app_purchase_android.dart';
import 'package:in_app_purchase_android/src/billing_client_wrappers/enum_converters.dart';
import 'package:test/test.dart';

final PurchaseWrapper dummyPurchase = PurchaseWrapper(
  orderId: 'orderId',
  packageName: 'packageName',
  purchaseTime: 0,
  signature: 'signature',
  sku: 'sku',
  purchaseToken: 'purchaseToken',
  isAutoRenewing: false,
  originalJson: '',
  developerPayload: 'dummy payload',
  isAcknowledged: true,
  purchaseState: PurchaseStateWrapper.purchased,
  obfuscatedAccountId: 'Account101',
  obfuscatedProfileId: 'Profile103',
);

final PurchaseWrapper dummyUnacknowledgedPurchase = PurchaseWrapper(
  orderId: 'orderId',
  packageName: 'packageName',
  purchaseTime: 0,
  signature: 'signature',
  sku: 'sku',
  purchaseToken: 'purchaseToken',
  isAutoRenewing: false,
  originalJson: '',
  developerPayload: 'dummy payload',
  isAcknowledged: false,
  purchaseState: PurchaseStateWrapper.purchased,
);

final PurchaseHistoryRecordWrapper dummyPurchaseHistoryRecord =
    PurchaseHistoryRecordWrapper(
  purchaseTime: 0,
  signature: 'signature',
  sku: 'sku',
  purchaseToken: 'purchaseToken',
  originalJson: '',
  developerPayload: 'dummy payload',
);

final PurchaseWrapper dummyOldPurchase = PurchaseWrapper(
  orderId: 'oldOrderId',
  packageName: 'oldPackageName',
  purchaseTime: 0,
  signature: 'oldSignature',
  sku: 'oldSku',
  purchaseToken: 'oldPurchaseToken',
  isAutoRenewing: false,
  originalJson: '',
  developerPayload: 'old dummy payload',
  isAcknowledged: true,
  purchaseState: PurchaseStateWrapper.purchased,
);

void main() {
  group('PurchaseWrapper', () {
    test('converts from map', () {
      final PurchaseWrapper expected = dummyPurchase;
      final PurchaseWrapper parsed =
          PurchaseWrapper.fromJson(buildPurchaseMap(expected));

      expect(parsed, equals(expected));
    });

    test('toPurchaseDetails() should return correct PurchaseDetail object', () {
      final GooglePlayPurchaseDetails details =
          GooglePlayPurchaseDetails.fromPurchase(dummyPurchase);
      expect(details.purchaseID, dummyPurchase.orderId);
      expect(details.productID, dummyPurchase.sku);
      expect(details.transactionDate, dummyPurchase.purchaseTime.toString());
      expect(details.verificationData, isNotNull);
      expect(details.verificationData.source, kIAPSource);
      expect(details.verificationData.localVerificationData,
          dummyPurchase.originalJson);
      expect(details.verificationData.serverVerificationData,
          dummyPurchase.purchaseToken);
      expect(details.billingClientPurchase, dummyPurchase);
      expect(details.pendingCompletePurchase, true);
    });
  });

  group('PurchaseHistoryRecordWrapper', () {
    test('converts from map', () {
      final PurchaseHistoryRecordWrapper expected = dummyPurchaseHistoryRecord;
      final PurchaseHistoryRecordWrapper parsed =
          PurchaseHistoryRecordWrapper.fromJson(
              buildPurchaseHistoryRecordMap(expected));

      expect(parsed, equals(expected));
    });
  });

  group('PurchasesResultWrapper', () {
    test('parsed from map', () {
      final BillingResponse responseCode = BillingResponse.ok;
      final List<PurchaseWrapper> purchases = <PurchaseWrapper>[
        dummyPurchase,
        dummyPurchase
      ];
      const String debugMessage = 'dummy Message';
      final BillingResultWrapper billingResult = BillingResultWrapper(
          responseCode: responseCode, debugMessage: debugMessage);
      final PurchasesResultWrapper expected = PurchasesResultWrapper(
          billingResult: billingResult,
          responseCode: responseCode,
          purchasesList: purchases);
      final PurchasesResultWrapper parsed =
          PurchasesResultWrapper.fromJson(<String, dynamic>{
        'billingResult': buildBillingResultMap(billingResult),
        'responseCode': BillingResponseConverter().toJson(responseCode),
        'purchasesList': <Map<String, dynamic>>[
          buildPurchaseMap(dummyPurchase),
          buildPurchaseMap(dummyPurchase)
        ]
      });
      expect(parsed.billingResult, equals(expected.billingResult));
      expect(parsed.responseCode, equals(expected.responseCode));
      expect(parsed.purchasesList, containsAll(expected.purchasesList));
    });

    test('parsed from empty map', () {
      final PurchasesResultWrapper parsed =
          PurchasesResultWrapper.fromJson(<String, dynamic>{});
      expect(
          parsed.billingResult,
          equals(BillingResultWrapper(
              responseCode: BillingResponse.error,
              debugMessage: kInvalidBillingResultErrorMessage)));
      expect(parsed.responseCode, BillingResponse.error);
      expect(parsed.purchasesList, isEmpty);
    });
  });

  group('PurchasesHistoryResult', () {
    test('parsed from map', () {
      final BillingResponse responseCode = BillingResponse.ok;
      final List<PurchaseHistoryRecordWrapper> purchaseHistoryRecordList =
          <PurchaseHistoryRecordWrapper>[
        dummyPurchaseHistoryRecord,
        dummyPurchaseHistoryRecord
      ];
      const String debugMessage = 'dummy Message';
      final BillingResultWrapper billingResult = BillingResultWrapper(
          responseCode: responseCode, debugMessage: debugMessage);
      final PurchasesHistoryResult expected = PurchasesHistoryResult(
          billingResult: billingResult,
          purchaseHistoryRecordList: purchaseHistoryRecordList);
      final PurchasesHistoryResult parsed =
          PurchasesHistoryResult.fromJson(<String, dynamic>{
        'billingResult': buildBillingResultMap(billingResult),
        'purchaseHistoryRecordList': <Map<String, dynamic>>[
          buildPurchaseHistoryRecordMap(dummyPurchaseHistoryRecord),
          buildPurchaseHistoryRecordMap(dummyPurchaseHistoryRecord)
        ]
      });
      expect(parsed.billingResult, equals(billingResult));
      expect(parsed.purchaseHistoryRecordList,
          containsAll(expected.purchaseHistoryRecordList));
    });

    test('parsed from empty map', () {
      final PurchasesHistoryResult parsed =
          PurchasesHistoryResult.fromJson(<String, dynamic>{});
      expect(
          parsed.billingResult,
          equals(BillingResultWrapper(
              responseCode: BillingResponse.error,
              debugMessage: kInvalidBillingResultErrorMessage)));
      expect(parsed.purchaseHistoryRecordList, isEmpty);
    });
  });
}

Map<String, dynamic> buildPurchaseMap(PurchaseWrapper original) {
  return <String, dynamic>{
    'orderId': original.orderId,
    'packageName': original.packageName,
    'purchaseTime': original.purchaseTime,
    'signature': original.signature,
    'sku': original.sku,
    'purchaseToken': original.purchaseToken,
    'isAutoRenewing': original.isAutoRenewing,
    'originalJson': original.originalJson,
    'developerPayload': original.developerPayload,
    'purchaseState': PurchaseStateConverter().toJson(original.purchaseState),
    'isAcknowledged': original.isAcknowledged,
    'obfuscatedAccountId': original.obfuscatedAccountId,
    'obfuscatedProfileId': original.obfuscatedProfileId,
  };
}

Map<String, dynamic> buildPurchaseHistoryRecordMap(
    PurchaseHistoryRecordWrapper original) {
  return <String, dynamic>{
    'purchaseTime': original.purchaseTime,
    'signature': original.signature,
    'sku': original.sku,
    'purchaseToken': original.purchaseToken,
    'originalJson': original.originalJson,
    'developerPayload': original.developerPayload,
  };
}

Map<String, dynamic> buildBillingResultMap(BillingResultWrapper original) {
  return <String, dynamic>{
    'responseCode': BillingResponseConverter().toJson(original.responseCode),
    'debugMessage': original.debugMessage,
  };
}
