//
//  Util.m
//  CoreSDKExample
//
//  Created by Dominik on 01/06/2017.
//
//

#import "Util.h"

@implementation NSData (NSData_Conversion)

- (NSString *)hexadecimalString
{
    /* Returns hexadecimal string of NSData. Empty string if data is empty.   */
    const unsigned char *dataBuffer = (const unsigned char *)[self bytes];
    
    if (!dataBuffer)
    {
        return [NSString string];
    }
    
    NSUInteger dataLength  = [self length];
    NSMutableString *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
    for (int i = 0; i < dataLength; ++i)
    {
        [hexString appendFormat:@"%02x", (unsigned int)dataBuffer[i]];
    }
    
    return [NSString stringWithString:hexString];
}

@end

@implementation TableData



@end

@implementation Util

+ (NSString *)formatDateToServerFormat:(NSDate *)date{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"dd-MM-yyyy:HH:mm:ss:SSS"];
    [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"]];
    return [formatter stringFromDate:date];
}

+ (void)saveToSettings:(NSString *)key withValue:(NSString *)value{
    [[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSString*) getFromSettings:(NSString *)key{
    return [[NSUserDefaults standardUserDefaults] stringForKey:key];
}

+ (CoreMode)coreMode:(NSString *)mode{
    if ([mode isEqualToString:@"TEST"]) {
        return TEST;
    } else  if ([mode isEqualToString:@"DEV"]) {
        return DEV;
    } else {
        return LIVE;
    }
}

+ (NSString*)parseCoreError:(CoreError)error withMessage:(NSString*) message{
    NSString *value = @"";
    switch (error) {
        case ERROR_UNKNOWN:
            value = @"Unknown error has occured. ";
            break;
        case ERROR_TRANSACTION:
            value = @"Transaction error has occured. ";
            break;
        case ERROR_TIMEOUT:
            value = @"Timeout. Please try again. ";
            break;
        case ERROR_NETWORK:
            value = @"Please check your internet connection. ";
            break;
        case ERROR_JSON:
            value = @"Json object cannot be parsed. ";
            break;
        case ERROR_CURRENCY_NOT_SUPPORTED:
            value = @"Currency is not supported. ";
            break;
        case ERROR_AUTHENTICATION_TOKEN:
            value = @"Authentication token is invalid. ";
            break;
        case ERROR_SIGNATURE_NULL:
            value = @"Signature cannot be empty. ";
            break;
        case ERROR_SERVER:
            value = @"Server error has occured. ";
            break;
        case ERROR_CONNECTION:
            value = @"Connection error has occured. ";
            break;
        case VALIDATION_ERROR:
            value = [NSString stringWithFormat:@"Validation error. Field %@ is missing. ",message];
            break;
        case RESOURCE_FILE_WITH_COREPAY_URL_NOT_FOUND:
            value = @"URL not found. ";
            break;
        case INCORRECT_SETTINGS_TERMINAL:
            value = @"Terminal ID is incorrect. ";
            break;
        case INCORRECT_SETTINGS_SECRET:
            value = @"Secret is incorrect. ";
            break;
        case INCORRECT_SETTINGS:
            value = @"Incorrect settings. ";
            break;
        case ERROR_GENERAL_COUNTRY_UNKNOWN:
            value = @"Country missing. ";
            break;
        case ERROR_DIGEST_MISMATCH:
            value = @"Digest mismatch. ";
            break;
        case ERROR_INVALID_USER_ACCESS:
            value = @"Invalid user access. ";
            break;
        case ERROR_METHOD_NOT_SUPPORTED:
            value = @"Method not supported. ";
            break;
        case ERROR_VALIDATION_LIMIT_HIT:
            value = @"Validation limit hit. ";
            break;
        case ERROR_SWIPE_WITHOUT_FALLBACK_NOT_ALLOWED:
            value = @"Swipe without fallback not allowed. ";
            break;
        case ERROR_INVALID_TRACK_DATA:
            value = @"Invalid track data. ";
            break;
        case ERROR_INVALID_EMV_TAGS:
            value = @"Invalid EMV tags. ";
            break;
        case ERROR_INVALID_APPLE_PAYLOAD:
            value = @"Invalid apple payload. ";
            break;
        case ERROR_INVALID_AMOUNT:
            value = @"Invalid amount. ";
            break;
        case ERROR_INVALID_CURRENCY:
            value = @"Invalid currency. ";
            break;
        case ERROR_INVALID_ARGUMENT:
            value = @"Invalid argument. ";
            break;
        case ERROR_GENERAL:
            value = @"Error general. ";
            break;
        case ERROR_ORDER_ALREADY_PROCESSED:
            value = @"Order already processed. ";
            break;
        case DECRYPTION_FAILED_DEVICE_NOT_REGISTERED:
            value = @"Decryption failed. ";
            break;
        case CANT_REFUND_TRANSACTION:
            value = @"Cant refund transaction. ";
            break;
        case TERMINAL_DOES_NOT_ALLOW_CHP:
            value = @"Terminal does not allow CHP. ";
            break;
        case VALIDATION_LIMIT_REACHED:
            value = @"Validation limit reached. ";
            break;
        case UNREFERENCED_REFUND_SHOULD_BE_ENABLED:
            value = @"Unreferenced refund should be enabled. ";
            break;
        case INVALID_REFUND_AMOUNT:
            value = @"Invalid refund amount. ";
            break;
        case TAX_AMOUNT_MUST_BE_GREATER_THAN_ZERO:
            value = @"Tax amount must be greater than 0. ";
            break;
        case TIP_AMOUNT_MUST_BE_GREATER_THAN_ZERO:
            value = @"Tip amount must be greater than 0. ";
            break;
        case USER_DOESNT_HAVE_ASSOCIATED_PRIVILEGE:
            value = @"User doesn't have associated privilege. ";
            break;
        case INVALID_MERCHANT_REFERENCE:
            value = @"Invalid merchant reference. ";
            break;
        case THIS_CALL_IS_NOT_SUPPORTED_FOR_PAYCONEX_SDK:
            value = @"Not supported call. ";
            break;
        case TERMINALID_OR_SECRET_NOT_DEFINED_IN_PAYCONFIG:
            value = @"Terminal ID or secret not defined in payconfig. ";
            break;
        case LEVEL_FULL_NOT_SUPPORTED_IN_LIVE_MODE:
            value = @"Log level FULL not supported in LIVE mode. ";
            break;
        case ERROR_ORDER_ALREADY_IN_PROGRESS:
            value = @"Order is already in progress, please wait. ";
            break;
        case SECURE_CARD_NOT_FOUND:
            value = @"Secure Card was not found. ";
            break;
        default:
            value = @"Error occurred. ";
            break;
    }
    NSLog(@"****** onError: %@ ", value);
    if (message != nil && message.length != 0)
        return message;
    else
        return value;
}

+ (NSString*)parseCoreDeviceError:(CoreDeviceError)deviceError withDescription:(NSString *)message{
    NSLog(@"onDeviceError");
    
    NSString *value = @"";
    switch (deviceError) {
        case UNSUPPORTED_CARD_TYPE:
            value = @"UNSUPPORTED_CARD_TYPE";
            break;
        case ERROR_DEVICE_NOT_SUPPORTED:
            value = @"ERROR_DEVICE_NOT_SUPPORTED";
            break;
        case WRONG_DEVICE:
            value = @"WRONG_DEVICE";
            break;
        case SWIPE_FAILED:
            value = @"SWIPE_FAILED";
            break;
        case TRANSACTION_ERROR:
            value = @"TRANSACTION_ERROR";
            break;
        case INTERRUPTED:
            value = @"INTERRUPTED.";
            break;
        case TIMEOUT_ERROR:
            value = @"TIMEOUT_ERROR";
            break;
        case TRANSACTION_CANCELLED:
            value = @"TRANSACTION_CANCELLED.";
            break;
        case UNKNOWN_ERROR:
            value = @"UNKNOWN_ERROR.";
            break;
        case PIN_TIMEOUT:
            value = @"PIN_TIMEOUT.";
            break;
        case INVALID_CARD:
            value = @"INVALID_CARD.";
            break;
        case InvalidInput:
            value = @"InvalidInput.";
            break;
        case InvalidInput_NotNumeric:
            value = @"InvalidInput_NotNumeric.";
            break;
        case InvalidInput_InputValueOutOfRange:
            value = @"InvalidInput_InputValueOutOfRange.";
            break;
        case InvalidInput_InvalidDataFormat:
            value = @"InvalidInput_InvalidDataFormat.";
            break;
        case InvalidInput_NoAcceptAmountForThisTransactionType:
            value = @"InvalidInput_NoAcceptAmountForThisTransactionType.";
            break;
        case InvalidInput_NotAcceptCashbackForThisTransactionType:
            value = @"InvalidInput_NotAcceptCashbackForThisTransactionType.";
            break;
        case DeviceReset:
            value = @"DeviceReset.";
            break;
        case DeviceBusy:
            value = @"DeviceBusy";
            break;
        case CommandNotAvailable:
            value = @"CommandNotAvailable.";
            break;
        case CommError:
            value = @"CommError.";
            break;
        case IllegalStateException:
            value = @"IllegalStateException";
            break;
        case BTv2FailToStart:
            value = @"BTv2FailToStart";
            break;
        case InvalidFunctionInBTv2Mode:
            value = @"InvalidFunctionInBTv2Mode";
            break;
        case DeviceError:
            value = @"DeviceError";
            break;
        case BTv4AlreadyConnected:
            value = @"BTv4AlreadyConnected";
            break;
        case AudioFailToStart:
            value = @"AudioFailToStart";
            break;
        case BackgroundTimeout:
            value = @"BackgroundTimeout";
            break;
        case DECLINED_ERROR:
            value = @"DECLINED_ERROR";
            break;
        case TEST_NOT_SUPPORTED_BY_DEVICE:
            value = @"TEST_NOT_SUPPORTED_BY_DEVICE";
            break;
        case PIN_FAILED:
            value = @"PIN_FAILED";
            break;
        case VALIDATION_FAILED_TESTS_NOT_COMPLETED:
            value = @"VALIDATION_FAILED_TESTS_NOT_COMPLETED";
            break;
        case DELAYED_AUTH_NOT_SUPPORTED:
            value = @"DELAYED_AUTH_NOT_SUPPORTED";
            break;
        case INPUT_METHOD_NOT_SUPPORTED_FOR_DELAYED_AUTH:
            value = @"INPUT_METHOD_NOT_SUPPORTED_FOR_DELAYED_AUTH";
            break;
        case INPUT_METHOD_NOT_SUPPORTED:
            value = @"INPUT_METHOD_NOT_SUPPORTED";
            break;
        case DEVICE_IS_NOT_CONNECTED:
            value = @"DEVICE_IS_NOT_CONNECTED";
            break;
        case TIPS_NOT_ENABLED_ON_THE_SERVER:
            value = @"TIPS_NOT_ENABLED_ON_THE_SERVER";
            break;
        default:
            value = @"Device error";
            break;
            
    }
    NSLog(@"****** onDeviceError: %@", value);
    return value;
}


+ (NSString*)parseCoreMessage:(CoreMessage)message{
    NSLog(@"onMessage");
    NSString *value = @"";
    switch (message) {
        case DEVICE_INITIALISING:
            value = @"DEVICE_INITIALISING";
            break;
        case DEVICE_NOT_CONNECTED:
            value = @"DEVICE_NOT_CONNECTED";
            break;
        case GOING_ONLINE:
            value = @"GOING_ONLINE";
            break;
        case WRONG_DEVICE:
            value = @"WRONG_DEVICE.";
            break;
        case CARD_SWIPE_DETECTED:
            value = @"CARD_SWIPE_DETECTED.";
            break;
        case SIGNATURE_IS_REQUIRED:
            value = @"SIGNATURE_IS_REQUIRED.";
            break;
        case CARD_SWIPE:
            value = @"CARD_SWIPE.";
            break;
        case CARD_INSERT_SWIPE:
            value = @"CARD_INSERT_SWIPE.";
            break;
        case CARD_DETECTED:
            value = @"CARD_DETECTED.";
            break;
        case REINSERT_OR_SWIPE:
            value = @"REINSERT_OR_SWIPE.";
            break;
        case CARD_REQUIRES_CHIP_READ:
            value = @"CARD_REQUIRES_CHIP_READ.";
            break;
        case PIN_ENTRY_SUCCESSFUL:
            value = @"PIN_ENTRY_SUCCESSFUL.";
            break;
        case INVALID_PIN_ENTERED:
            value = @"INVALID_PIN_ENTERED.";
            break;
        case INVALID_PIN_ENTERED_LAST_ATTEMPT:
            value = @"INVALID_PIN_ENTERED_LAST_ATTEMPT.";
            break;
        case SENDING_TRANSACTION:
            value = @"SENDING_TRANSACTION.";
            break;
        case INSERT_OR_SWIPE:
            value = @"INSERT_OR_SWIPE.";
            break;
        case SMART_CARD_INSERTED:
            value = @"SMART_CARD_INSERTED.";
            break;
        case SETTINGS_HERE:
            value = @"SETTINGS_HERE";
            break;
        case SETTINGS_UPDATE_SUCCESSFUL:
            value = @"SETINGS_UPDATE_SUCCESSFUl";
            break;
        case PLEASE_WAIT:
            value = @"PLEASE_WAIT";
            break;
        case CARD_ACCEPTED:
            value = @"CARD_ACCEPTED";
            break;
        case SELF_TEST_BLUEPAD:
            value = @"SELF_TEST_BLUEPAD";
            break;
        case SELF_TEST_WALKER:
            value = @"SELF_TEST_WALKER";
            break;
        case SELF_TEST_NOMAD:
            value = @"SELF_TEST_NOMAD";
            break;
        case INSERT_CARD:
            value = @"INSERT_CARD";
            break;
        case ENTER_PIN:
            value = @"ENTER_PIN";
            break;
        case TRANSACTION_CANCELLED_BY_USER:
            value = @"TRANSACTION_CANCELLED_BY_USER";
            break;
        case TRY_AGAIN:
            value = @"TRY_AGAIN";
            break;
        case SWIPE_AGAIN_PLEASE:
            value = @"SWIPE_AGAIN_PLEASE";
            break;
        case SCAN_STOPPED:
            value = @"SCAN_STOPPED";
            break;
        case SCAN_STARTED:
            value = @"SCAN_STARTED";
            break;
        case REVERSAL_ATTEMPTING:
            value = @"REVERSAL_ATTEMPTING";
            break;
        case PIN_REQUIRED:
            value = @"PIN_REQUIRED";
            break;
        case CARD_INSERT:
            value = @"CARD_INSERT";
            break;
        case CARD_TAP:
            value = @"CARD_TAP";
            break;
        case CARD_INSERT_OR_TAP:
            value = @"CARD_INSERT_OR_TAP";
            break;
        case CARD_SWIPE_OR_TAP:
            value = @"CARD_SWIPE_OR_TAP";
            break;
        case INSERT_OR_SWIPE_OR_TAP_CARD:
            value = @"INSERT_OR_SWIPE_OR_TAP_CARD";
            break;
        case DEVICE_ALREADY_CONNECTED:
            value = @"DEVICE_ALREADY_CONNECTED";
            break;
        case PROCESSING:
            value = @"PROCESSING";
            break;
        case BLUETOOTH_OFF:
            value = @"BLUETOOTH_OFF";
            break;
        default:
            value = @"Message";
            break;
    }
    NSLog(@"****** onMessage: %@", value);
    return value;
}

+ (NSLocale *) findLocaleByCurrencyCode:(NSString *)_currencyCode
{
    NSArray *locales = [NSLocale availableLocaleIdentifiers];
    NSLocale *locale = nil;
    
    for (NSString *localeId in locales) {
        locale = [[NSLocale alloc] initWithLocaleIdentifier:localeId];
        NSString *code = [locale objectForKey:NSLocaleCurrencyCode];
        if ([code isEqualToString:_currencyCode])
            break;
        else
            locale = nil;
        
    }
    
    return locale;
}

+ (NSString *)findCurrencySymbolByCode:(NSString *)_currencyCode
{
    NSNumberFormatter *fmtr = [[NSNumberFormatter alloc] init];
    NSLocale *locale = [self findLocaleByCurrencyCode:_currencyCode];
    NSString *currencySymbol;
    if (locale)
        [fmtr setLocale:locale];
    [fmtr setNumberStyle:NSNumberFormatterCurrencyStyle];
    currencySymbol = [fmtr currencySymbol];
    return currencySymbol;
}

@end
