// 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 "FIAObjectTranslator.h"

#pragma mark - SKProduct Coders

@implementation FIAObjectTranslator

+ (NSDictionary *)getMapFromSKProduct:(SKProduct *)product {
  if (!product) {
    return nil;
  }
  NSMutableDictionary *map = [[NSMutableDictionary alloc] initWithDictionary:@{
    @"localizedDescription" : product.localizedDescription ?: [NSNull null],
    @"localizedTitle" : product.localizedTitle ?: [NSNull null],
    @"productIdentifier" : product.productIdentifier ?: [NSNull null],
    @"price" : product.price.description ?: [NSNull null]

  }];
  // TODO(cyanglaz): NSLocale is a complex object, want to see the actual need of getting this
  // expanded to a map. Matching android to only get the currencySymbol for now.
  // https://github.com/flutter/flutter/issues/26610
  [map setObject:[FIAObjectTranslator getMapFromNSLocale:product.priceLocale] ?: [NSNull null]
          forKey:@"priceLocale"];
  if (@available(iOS 11.2, *)) {
    [map setObject:[FIAObjectTranslator
                       getMapFromSKProductSubscriptionPeriod:product.subscriptionPeriod]
                       ?: [NSNull null]
            forKey:@"subscriptionPeriod"];
  }
  if (@available(iOS 11.2, *)) {
    [map setObject:[FIAObjectTranslator getMapFromSKProductDiscount:product.introductoryPrice]
                       ?: [NSNull null]
            forKey:@"introductoryPrice"];
  }
  if (@available(iOS 12.2, *)) {
    [map setObject:[FIAObjectTranslator getMapArrayFromSKProductDiscounts:product.discounts]
            forKey:@"discounts"];
  }
  if (@available(iOS 12.0, *)) {
    [map setObject:product.subscriptionGroupIdentifier ?: [NSNull null]
            forKey:@"subscriptionGroupIdentifier"];
  }
  return map;
}

+ (NSDictionary *)getMapFromSKProductSubscriptionPeriod:(SKProductSubscriptionPeriod *)period {
  if (!period) {
    return nil;
  }
  return @{@"numberOfUnits" : @(period.numberOfUnits), @"unit" : @(period.unit)};
}

+ (nonnull NSArray *)getMapArrayFromSKProductDiscounts:
    (nonnull NSArray<SKProductDiscount *> *)productDiscounts {
  NSMutableArray *discountsMapArray = [[NSMutableArray alloc] init];

  for (SKProductDiscount *productDiscount in productDiscounts) {
    [discountsMapArray addObject:[FIAObjectTranslator getMapFromSKProductDiscount:productDiscount]];
  }

  return discountsMapArray;
}

+ (NSDictionary *)getMapFromSKProductDiscount:(SKProductDiscount *)discount {
  if (!discount) {
    return nil;
  }
  NSMutableDictionary *map = [[NSMutableDictionary alloc] initWithDictionary:@{
    @"price" : discount.price.description ?: [NSNull null],
    @"numberOfPeriods" : @(discount.numberOfPeriods),
    @"subscriptionPeriod" :
            [FIAObjectTranslator getMapFromSKProductSubscriptionPeriod:discount.subscriptionPeriod]
        ?: [NSNull null],
    @"paymentMode" : @(discount.paymentMode),
  }];
  if (@available(iOS 12.2, *)) {
    [map setObject:discount.identifier ?: [NSNull null] forKey:@"identifier"];
    [map setObject:@(discount.type) forKey:@"type"];
  }

  // TODO(cyanglaz): NSLocale is a complex object, want to see the actual need of getting this
  // expanded to a map. Matching android to only get the currencySymbol for now.
  // https://github.com/flutter/flutter/issues/26610
  [map setObject:[FIAObjectTranslator getMapFromNSLocale:discount.priceLocale] ?: [NSNull null]
          forKey:@"priceLocale"];
  return map;
}

+ (NSDictionary *)getMapFromSKProductsResponse:(SKProductsResponse *)productResponse {
  if (!productResponse) {
    return nil;
  }
  NSMutableArray *productsMapArray = [NSMutableArray new];
  for (SKProduct *product in productResponse.products) {
    [productsMapArray addObject:[FIAObjectTranslator getMapFromSKProduct:product]];
  }
  return @{
    @"products" : productsMapArray,
    @"invalidProductIdentifiers" : productResponse.invalidProductIdentifiers ?: @[]
  };
}

+ (NSDictionary *)getMapFromSKPayment:(SKPayment *)payment {
  if (!payment) {
    return nil;
  }
  NSMutableDictionary *map = [[NSMutableDictionary alloc] initWithDictionary:@{
    @"productIdentifier" : payment.productIdentifier ?: [NSNull null],
    @"requestData" : payment.requestData ? [[NSString alloc] initWithData:payment.requestData
                                                                 encoding:NSUTF8StringEncoding]
                                         : [NSNull null],
    @"quantity" : @(payment.quantity),
    @"applicationUsername" : payment.applicationUsername ?: [NSNull null]
  }];
  [map setObject:@(payment.simulatesAskToBuyInSandbox) forKey:@"simulatesAskToBuyInSandbox"];
  return map;
}

+ (NSDictionary *)getMapFromNSLocale:(NSLocale *)locale {
  if (!locale) {
    return nil;
  }
  NSMutableDictionary *map = [[NSMutableDictionary alloc] init];
  [map setObject:[locale objectForKey:NSLocaleCurrencySymbol] ?: [NSNull null]
          forKey:@"currencySymbol"];
  [map setObject:[locale objectForKey:NSLocaleCurrencyCode] ?: [NSNull null]
          forKey:@"currencyCode"];
  [map setObject:[locale objectForKey:NSLocaleCountryCode] ?: [NSNull null] forKey:@"countryCode"];
  return map;
}

+ (SKMutablePayment *)getSKMutablePaymentFromMap:(NSDictionary *)map {
  if (!map) {
    return nil;
  }
  SKMutablePayment *payment = [[SKMutablePayment alloc] init];
  payment.productIdentifier = map[@"productIdentifier"];
  NSString *utf8String = map[@"requestData"];
  payment.requestData = [utf8String dataUsingEncoding:NSUTF8StringEncoding];
  payment.quantity = [map[@"quantity"] integerValue];
  payment.applicationUsername = map[@"applicationUsername"];
  payment.simulatesAskToBuyInSandbox = [map[@"simulatesAskToBuyInSandbox"] boolValue];
  return payment;
}

+ (NSDictionary *)getMapFromSKPaymentTransaction:(SKPaymentTransaction *)transaction {
  if (!transaction) {
    return nil;
  }
  NSMutableDictionary *map = [[NSMutableDictionary alloc] initWithDictionary:@{
    @"error" : [FIAObjectTranslator getMapFromNSError:transaction.error] ?: [NSNull null],
    @"payment" : transaction.payment ? [FIAObjectTranslator getMapFromSKPayment:transaction.payment]
                                     : [NSNull null],
    @"originalTransaction" : transaction.originalTransaction
        ? [FIAObjectTranslator getMapFromSKPaymentTransaction:transaction.originalTransaction]
        : [NSNull null],
    @"transactionTimeStamp" : transaction.transactionDate
        ? @(transaction.transactionDate.timeIntervalSince1970)
        : [NSNull null],
    @"transactionIdentifier" : transaction.transactionIdentifier ?: [NSNull null],
    @"transactionState" : @(transaction.transactionState)
  }];

  return map;
}

+ (NSDictionary *)getMapFromNSError:(NSError *)error {
  if (!error) {
    return nil;
  }

  NSMutableDictionary *userInfo = [NSMutableDictionary new];
  for (NSErrorUserInfoKey key in error.userInfo) {
    id value = error.userInfo[key];
    userInfo[key] = [FIAObjectTranslator encodeNSErrorUserInfo:value];
  }
  return @{@"code" : @(error.code), @"domain" : error.domain ?: @"", @"userInfo" : userInfo};
}

+ (id)encodeNSErrorUserInfo:(id)value {
  if ([value isKindOfClass:[NSError class]]) {
    return [FIAObjectTranslator getMapFromNSError:value];
  } else if ([value isKindOfClass:[NSURL class]]) {
    return [value absoluteString];
  } else if ([value isKindOfClass:[NSNumber class]]) {
    return value;
  } else if ([value isKindOfClass:[NSString class]]) {
    return value;
  } else if ([value isKindOfClass:[NSArray class]]) {
    NSMutableArray *errors = [[NSMutableArray alloc] init];
    for (id error in value) {
      [errors addObject:[FIAObjectTranslator encodeNSErrorUserInfo:error]];
    }
    return errors;
  } else {
    return [NSString
        stringWithFormat:
            @"Unable to encode native userInfo object of type %@ to map. Please submit an issue at "
            @"https://github.com/flutter/flutter/issues/new with the title "
            @"\"[in_app_purchase_storekit] "
            @"Unable to encode userInfo of type %@\" and add reproduction steps and the error "
            @"details in "
            @"the description field.",
            [value class], [value class]];
  }
}

+ (NSDictionary *)getMapFromSKStorefront:(SKStorefront *)storefront {
  if (!storefront) {
    return nil;
  }

  NSMutableDictionary *map = [[NSMutableDictionary alloc] initWithDictionary:@{
    @"countryCode" : storefront.countryCode,
    @"identifier" : storefront.identifier
  }];

  return map;
}

+ (NSDictionary *)getMapFromSKStorefront:(SKStorefront *)storefront
                 andSKPaymentTransaction:(SKPaymentTransaction *)transaction {
  if (!storefront || !transaction) {
    return nil;
  }

  NSMutableDictionary *map = [[NSMutableDictionary alloc] initWithDictionary:@{
    @"storefront" : [FIAObjectTranslator getMapFromSKStorefront:storefront],
    @"transaction" : [FIAObjectTranslator getMapFromSKPaymentTransaction:transaction]
  }];

  return map;
}

+ (SKPaymentDiscount *)getSKPaymentDiscountFromMap:(NSDictionary *)map
                                         withError:(NSString **)error {
  if (!map || map.count <= 0) {
    return nil;
  }

  NSString *identifier = map[@"identifier"];
  NSString *keyIdentifier = map[@"keyIdentifier"];
  NSString *nonce = map[@"nonce"];
  NSString *signature = map[@"signature"];
  NSNumber *timestamp = map[@"timestamp"];

  if (!identifier || ![identifier isKindOfClass:NSString.class] ||
      [identifier isEqualToString:@""]) {
    if (error) {
      *error = @"When specifying a payment discount the 'identifier' field is mandatory.";
    }
    return nil;
  }

  if (!keyIdentifier || ![keyIdentifier isKindOfClass:NSString.class] ||
      [keyIdentifier isEqualToString:@""]) {
    if (error) {
      *error = @"When specifying a payment discount the 'keyIdentifier' field is mandatory.";
    }
    return nil;
  }

  if (!nonce || ![nonce isKindOfClass:NSString.class] || [nonce isEqualToString:@""]) {
    if (error) {
      *error = @"When specifying a payment discount the 'nonce' field is mandatory.";
    }
    return nil;
  }

  if (!signature || ![signature isKindOfClass:NSString.class] || [signature isEqualToString:@""]) {
    if (error) {
      *error = @"When specifying a payment discount the 'signature' field is mandatory.";
    }
    return nil;
  }

  if (!timestamp || ![timestamp isKindOfClass:NSNumber.class] || [timestamp longLongValue] <= 0) {
    if (error) {
      *error = @"When specifying a payment discount the 'timestamp' field is mandatory.";
    }
    return nil;
  }

  SKPaymentDiscount *discount =
      [[SKPaymentDiscount alloc] initWithIdentifier:identifier
                                      keyIdentifier:keyIdentifier
                                              nonce:[[NSUUID alloc] initWithUUIDString:nonce]
                                          signature:signature
                                          timestamp:timestamp];

  return discount;
}

@end
