/*
 * The version of the OpenAPI document: v2
 * Contact: developer-experience@adyen.com
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit this class manually.
 */


export * from './accountHolder';
export * from './accountHolderCapability';
export * from './accountHolderInfo';
export * from './activeNetworkTokensRestriction';
export * from './address';
export * from './address2';
export * from './amount';
export * from './authentication';
export * from './balance';
export * from './balanceAccount';
export * from './balanceAccountInfo';
export * from './balanceAccountUpdateRequest';
export * from './balancePlatform';
export * from './balanceSweepConfigurationsResponse';
export * from './bankAccount';
export * from './brandVariantsRestriction';
export * from './bulkAddress';
export * from './card';
export * from './cardConfiguration';
export * from './cardInfo';
export * from './contactDetails';
export * from './countriesRestriction';
export * from './cronSweepSchedule';
export * from './deliveryContact';
export * from './differentCurrenciesRestriction';
export * from './duration';
export * from './entryModesRestriction';
export * from './expiry';
export * from './internationalTransactionRestriction';
export * from './invalidField';
export * from './jSONObject';
export * from './jSONPath';
export * from './matchingTransactionsRestriction';
export * from './mccsRestriction';
export * from './merchantAcquirerPair';
export * from './merchantsRestriction';
export * from './name';
export * from './paginatedAccountHoldersResponse';
export * from './paginatedBalanceAccountsResponse';
export * from './paginatedPaymentInstrumentsResponse';
export * from './paymentInstrument';
export * from './paymentInstrumentGroup';
export * from './paymentInstrumentGroupInfo';
export * from './paymentInstrumentInfo';
export * from './paymentInstrumentUpdateRequest';
export * from './phone';
export * from './phoneNumber';
export * from './processingTypesRestriction';
export * from './remediatingAction';
export * from './restServiceError';
export * from './sweepConfigurationV2';
export * from './sweepCounterparty';
export * from './sweepSchedule';
export * from './timeOfDay';
export * from './timeOfDayRestriction';
export * from './totalAmountRestriction';
export * from './transactionRule';
export * from './transactionRuleEntityKey';
export * from './transactionRuleInfo';
export * from './transactionRuleInterval';
export * from './transactionRuleResponse';
export * from './transactionRuleRestrictions';
export * from './transactionRulesResponse';
export * from './verificationError';
export * from './verificationErrorRecursive';


import { AccountHolder } from './accountHolder';
import { AccountHolderCapability } from './accountHolderCapability';
import { AccountHolderInfo } from './accountHolderInfo';
import { ActiveNetworkTokensRestriction } from './activeNetworkTokensRestriction';
import { Address } from './address';
import { Address2 } from './address2';
import { Amount } from './amount';
import { Authentication } from './authentication';
import { Balance } from './balance';
import { BalanceAccount } from './balanceAccount';
import { BalanceAccountInfo } from './balanceAccountInfo';
import { BalanceAccountUpdateRequest } from './balanceAccountUpdateRequest';
import { BalancePlatform } from './balancePlatform';
import { BalanceSweepConfigurationsResponse } from './balanceSweepConfigurationsResponse';
import { BankAccount } from './bankAccount';
import { BrandVariantsRestriction } from './brandVariantsRestriction';
import { BulkAddress } from './bulkAddress';
import { Card } from './card';
import { CardConfiguration } from './cardConfiguration';
import { CardInfo } from './cardInfo';
import { ContactDetails } from './contactDetails';
import { CountriesRestriction } from './countriesRestriction';
import { CronSweepSchedule } from './cronSweepSchedule';
import { DeliveryContact } from './deliveryContact';
import { DifferentCurrenciesRestriction } from './differentCurrenciesRestriction';
import { Duration } from './duration';
import { EntryModesRestriction } from './entryModesRestriction';
import { Expiry } from './expiry';
import { InternationalTransactionRestriction } from './internationalTransactionRestriction';
import { InvalidField } from './invalidField';
import { JSONObject } from './jSONObject';
import { JSONPath } from './jSONPath';
import { MatchingTransactionsRestriction } from './matchingTransactionsRestriction';
import { MccsRestriction } from './mccsRestriction';
import { MerchantAcquirerPair } from './merchantAcquirerPair';
import { MerchantsRestriction } from './merchantsRestriction';
import { Name } from './name';
import { PaginatedAccountHoldersResponse } from './paginatedAccountHoldersResponse';
import { PaginatedBalanceAccountsResponse } from './paginatedBalanceAccountsResponse';
import { PaginatedPaymentInstrumentsResponse } from './paginatedPaymentInstrumentsResponse';
import { PaymentInstrument } from './paymentInstrument';
import { PaymentInstrumentGroup } from './paymentInstrumentGroup';
import { PaymentInstrumentGroupInfo } from './paymentInstrumentGroupInfo';
import { PaymentInstrumentInfo } from './paymentInstrumentInfo';
import { PaymentInstrumentUpdateRequest } from './paymentInstrumentUpdateRequest';
import { Phone } from './phone';
import { PhoneNumber } from './phoneNumber';
import { ProcessingTypesRestriction } from './processingTypesRestriction';
import { RemediatingAction } from './remediatingAction';
import { RestServiceError } from './restServiceError';
import { SweepConfigurationV2 } from './sweepConfigurationV2';
import { SweepCounterparty } from './sweepCounterparty';
import { SweepSchedule } from './sweepSchedule';
import { TimeOfDay } from './timeOfDay';
import { TimeOfDayRestriction } from './timeOfDayRestriction';
import { TotalAmountRestriction } from './totalAmountRestriction';
import { TransactionRule } from './transactionRule';
import { TransactionRuleEntityKey } from './transactionRuleEntityKey';
import { TransactionRuleInfo } from './transactionRuleInfo';
import { TransactionRuleInterval } from './transactionRuleInterval';
import { TransactionRuleResponse } from './transactionRuleResponse';
import { TransactionRuleRestrictions } from './transactionRuleRestrictions';
import { TransactionRulesResponse } from './transactionRulesResponse';
import { VerificationError } from './verificationError';
import { VerificationErrorRecursive } from './verificationErrorRecursive';

/* tslint:disable:no-unused-variable */
let primitives = [
                    "string",
                    "boolean",
                    "double",
                    "integer",
                    "long",
                    "float",
                    "number",
                    "any"
                 ];

let enumsMap: {[index: string]: any} = {
        "AccountHolder.StatusEnum": AccountHolder.StatusEnum,
        "AccountHolderCapability.AllowedLevelEnum": AccountHolderCapability.AllowedLevelEnum,
        "AccountHolderCapability.RequestedLevelEnum": AccountHolderCapability.RequestedLevelEnum,
        "AccountHolderCapability.VerificationStatusEnum": AccountHolderCapability.VerificationStatusEnum,
        "BalanceAccount.StatusEnum": BalanceAccount.StatusEnum,
        "BalanceAccountUpdateRequest.StatusEnum": BalanceAccountUpdateRequest.StatusEnum,
        "Card.FormFactorEnum": Card.FormFactorEnum,
        "CardInfo.FormFactorEnum": CardInfo.FormFactorEnum,
        "CronSweepSchedule.TypeEnum": CronSweepSchedule.TypeEnum,
        "Duration.UnitEnum": Duration.UnitEnum,
        "EntryModesRestriction.ValueEnum": EntryModesRestriction.ValueEnum,
        "PaymentInstrument.StatusEnum": PaymentInstrument.StatusEnum,
        "PaymentInstrument.StatusReasonEnum": PaymentInstrument.StatusReasonEnum,
        "PaymentInstrument.TypeEnum": PaymentInstrument.TypeEnum,
        "PaymentInstrumentInfo.StatusEnum": PaymentInstrumentInfo.StatusEnum,
        "PaymentInstrumentInfo.StatusReasonEnum": PaymentInstrumentInfo.StatusReasonEnum,
        "PaymentInstrumentInfo.TypeEnum": PaymentInstrumentInfo.TypeEnum,
        "PaymentInstrumentUpdateRequest.StatusEnum": PaymentInstrumentUpdateRequest.StatusEnum,
        "PaymentInstrumentUpdateRequest.StatusReasonEnum": PaymentInstrumentUpdateRequest.StatusReasonEnum,
        "Phone.TypeEnum": Phone.TypeEnum,
        "PhoneNumber.PhoneTypeEnum": PhoneNumber.PhoneTypeEnum,
        "ProcessingTypesRestriction.ValueEnum": ProcessingTypesRestriction.ValueEnum,
        "SweepConfigurationV2.StatusEnum": SweepConfigurationV2.StatusEnum,
        "SweepConfigurationV2.TypeEnum": SweepConfigurationV2.TypeEnum,
        "SweepSchedule.TypeEnum": SweepSchedule.TypeEnum,
        "TransactionRule.OutcomeTypeEnum": TransactionRule.OutcomeTypeEnum,
        "TransactionRule.StatusEnum": TransactionRule.StatusEnum,
        "TransactionRule.TypeEnum": TransactionRule.TypeEnum,
        "TransactionRuleInfo.OutcomeTypeEnum": TransactionRuleInfo.OutcomeTypeEnum,
        "TransactionRuleInfo.StatusEnum": TransactionRuleInfo.StatusEnum,
        "TransactionRuleInfo.TypeEnum": TransactionRuleInfo.TypeEnum,
        "TransactionRuleInterval.DayOfWeekEnum": TransactionRuleInterval.DayOfWeekEnum,
        "TransactionRuleInterval.TypeEnum": TransactionRuleInterval.TypeEnum,
        "VerificationError.TypeEnum": VerificationError.TypeEnum,
        "VerificationErrorRecursive.TypeEnum": VerificationErrorRecursive.TypeEnum,
}

let typeMap: {[index: string]: any} = {
    "AccountHolder": AccountHolder,
    "AccountHolderCapability": AccountHolderCapability,
    "AccountHolderInfo": AccountHolderInfo,
    "ActiveNetworkTokensRestriction": ActiveNetworkTokensRestriction,
    "Address": Address,
    "Address2": Address2,
    "Amount": Amount,
    "Authentication": Authentication,
    "Balance": Balance,
    "BalanceAccount": BalanceAccount,
    "BalanceAccountInfo": BalanceAccountInfo,
    "BalanceAccountUpdateRequest": BalanceAccountUpdateRequest,
    "BalancePlatform": BalancePlatform,
    "BalanceSweepConfigurationsResponse": BalanceSweepConfigurationsResponse,
    "BankAccount": BankAccount,
    "BrandVariantsRestriction": BrandVariantsRestriction,
    "BulkAddress": BulkAddress,
    "Card": Card,
    "CardConfiguration": CardConfiguration,
    "CardInfo": CardInfo,
    "ContactDetails": ContactDetails,
    "CountriesRestriction": CountriesRestriction,
    "CronSweepSchedule": CronSweepSchedule,
    "DeliveryContact": DeliveryContact,
    "DifferentCurrenciesRestriction": DifferentCurrenciesRestriction,
    "Duration": Duration,
    "EntryModesRestriction": EntryModesRestriction,
    "Expiry": Expiry,
    "InternationalTransactionRestriction": InternationalTransactionRestriction,
    "InvalidField": InvalidField,
    "JSONObject": JSONObject,
    "JSONPath": JSONPath,
    "MatchingTransactionsRestriction": MatchingTransactionsRestriction,
    "MccsRestriction": MccsRestriction,
    "MerchantAcquirerPair": MerchantAcquirerPair,
    "MerchantsRestriction": MerchantsRestriction,
    "Name": Name,
    "PaginatedAccountHoldersResponse": PaginatedAccountHoldersResponse,
    "PaginatedBalanceAccountsResponse": PaginatedBalanceAccountsResponse,
    "PaginatedPaymentInstrumentsResponse": PaginatedPaymentInstrumentsResponse,
    "PaymentInstrument": PaymentInstrument,
    "PaymentInstrumentGroup": PaymentInstrumentGroup,
    "PaymentInstrumentGroupInfo": PaymentInstrumentGroupInfo,
    "PaymentInstrumentInfo": PaymentInstrumentInfo,
    "PaymentInstrumentUpdateRequest": PaymentInstrumentUpdateRequest,
    "Phone": Phone,
    "PhoneNumber": PhoneNumber,
    "ProcessingTypesRestriction": ProcessingTypesRestriction,
    "RemediatingAction": RemediatingAction,
    "RestServiceError": RestServiceError,
    "SweepConfigurationV2": SweepConfigurationV2,
    "SweepCounterparty": SweepCounterparty,
    "SweepSchedule": SweepSchedule,
    "TimeOfDay": TimeOfDay,
    "TimeOfDayRestriction": TimeOfDayRestriction,
    "TotalAmountRestriction": TotalAmountRestriction,
    "TransactionRule": TransactionRule,
    "TransactionRuleEntityKey": TransactionRuleEntityKey,
    "TransactionRuleInfo": TransactionRuleInfo,
    "TransactionRuleInterval": TransactionRuleInterval,
    "TransactionRuleResponse": TransactionRuleResponse,
    "TransactionRuleRestrictions": TransactionRuleRestrictions,
    "TransactionRulesResponse": TransactionRulesResponse,
    "VerificationError": VerificationError,
    "VerificationErrorRecursive": VerificationErrorRecursive,
}

export class ObjectSerializer {
    public static findCorrectType(data: any, expectedType: string) {
        if (data == undefined) {
            return expectedType;
        } else if (primitives.indexOf(expectedType.toLowerCase()) !== -1) {
            return expectedType;
        } else if (expectedType === "Date") {
            return expectedType;
        } else {
            if (enumsMap[expectedType]) {
                return expectedType;
            }

            if (!typeMap[expectedType]) {
                return expectedType; // w/e we don't know the type
            }

            // Check the discriminator
            let discriminatorProperty = typeMap[expectedType].discriminator;
            if (discriminatorProperty == null) {
                return expectedType; // the type does not have a discriminator. use it.
            } else {
                if (data[discriminatorProperty]) {
                    var discriminatorType = data[discriminatorProperty];
                    if(typeMap[discriminatorType]){
                        return discriminatorType; // use the type given in the discriminator
                    } else {
                        return expectedType; // discriminator did not map to a type
                    }
                } else {
                    return expectedType; // discriminator was not present (or an empty string)
                }
            }
        }
    }

    public static serialize(data: any, type: string) {
        if (data == undefined) {
            return data;
        } else if (primitives.indexOf(type.toLowerCase()) !== -1) {
            return data;
        } else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6
            let subType: string = type.replace("Array<", ""); // Array<Type> => Type>
            subType = subType.substring(0, subType.length - 1); // Type> => Type
            let transformedData: any[] = [];
            for (let index = 0; index < data.length; index++) {
                let datum = data[index];
                transformedData.push(ObjectSerializer.serialize(datum, subType));
            }
            return transformedData;
        } else if (type === "Date") {
            return data.toISOString();
        } else if (type === "SaleToAcquirerData") {
            const dataString = JSON.stringify(data);
            return Buffer.from(dataString).toString("base64");
        } else {
            if (enumsMap[type]) {
                return data;
            }
            if (!typeMap[type]) { // in case we dont know the type
                return data;
            }

            // Get the actual type of this object
            type = this.findCorrectType(data, type);

            // get the map for the correct type.
            let attributeTypes = typeMap[type].getAttributeTypeMap();
            let instance: {[index: string]: any} = {};
            for (let index = 0; index < attributeTypes.length; index++) {
                let attributeType = attributeTypes[index];
                instance[attributeType.baseName] = ObjectSerializer.serialize(data[attributeType.name], attributeType.type);
            }
            return instance;
        }
    }

    public static deserialize(data: any, type: string) {
        // polymorphism may change the actual type.
        type = ObjectSerializer.findCorrectType(data, type);
        if (data == undefined) {
            return data;
        } else if (primitives.indexOf(type.toLowerCase()) !== -1) {
            return data;
        } else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6
            let subType: string = type.replace("Array<", ""); // Array<Type> => Type>
            subType = subType.substring(0, subType.length - 1); // Type> => Type
            let transformedData: any[] = [];
            for (let index = 0; index < data.length; index++) {
                let datum = data[index];
                transformedData.push(ObjectSerializer.deserialize(datum, subType));
            }
            return transformedData;
        } else if (type === "Date") {
            return new Date(data);
        } else {
            if (enumsMap[type]) {// is Enum
                return data;
            }

            if (!typeMap[type]) { // dont know the type
                return data;
            }
            let instance = new typeMap[type]();
            let attributeTypes = typeMap[type].getAttributeTypeMap();
            for (let index = 0; index < attributeTypes.length; index++) {
                let attributeType = attributeTypes[index];
                instance[attributeType.name] = ObjectSerializer.deserialize(data[attributeType.baseName], attributeType.type);
            }
            return instance;
        }
    }
}
