/*
Configuration API

API version: 2
*/

// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.

package balanceplatform

import (
	"encoding/json"
	"fmt"
)

// TransferRouteRequirementsInner - struct for TransferRouteRequirementsInner
type TransferRouteRequirementsInner struct {
	AddressRequirement                       *AddressRequirement
	AmountMinMaxRequirement                  *AmountMinMaxRequirement
	AmountNonZeroDecimalsRequirement         *AmountNonZeroDecimalsRequirement
	BankAccountIdentificationTypeRequirement *BankAccountIdentificationTypeRequirement
	IbanAccountIdentificationRequirement     *IbanAccountIdentificationRequirement
	PaymentInstrumentRequirement             *PaymentInstrumentRequirement
	USInstantPayoutAddressRequirement        *USInstantPayoutAddressRequirement
	USInternationalAchAddressRequirement     *USInternationalAchAddressRequirement
}

// AddressRequirementAsTransferRouteRequirementsInner is a convenience function that returns AddressRequirement wrapped in TransferRouteRequirementsInner
func AddressRequirementAsTransferRouteRequirementsInner(v *AddressRequirement) TransferRouteRequirementsInner {
	return TransferRouteRequirementsInner{
		AddressRequirement: v,
	}
}

// AmountMinMaxRequirementAsTransferRouteRequirementsInner is a convenience function that returns AmountMinMaxRequirement wrapped in TransferRouteRequirementsInner
func AmountMinMaxRequirementAsTransferRouteRequirementsInner(v *AmountMinMaxRequirement) TransferRouteRequirementsInner {
	return TransferRouteRequirementsInner{
		AmountMinMaxRequirement: v,
	}
}

// AmountNonZeroDecimalsRequirementAsTransferRouteRequirementsInner is a convenience function that returns AmountNonZeroDecimalsRequirement wrapped in TransferRouteRequirementsInner
func AmountNonZeroDecimalsRequirementAsTransferRouteRequirementsInner(v *AmountNonZeroDecimalsRequirement) TransferRouteRequirementsInner {
	return TransferRouteRequirementsInner{
		AmountNonZeroDecimalsRequirement: v,
	}
}

// BankAccountIdentificationTypeRequirementAsTransferRouteRequirementsInner is a convenience function that returns BankAccountIdentificationTypeRequirement wrapped in TransferRouteRequirementsInner
func BankAccountIdentificationTypeRequirementAsTransferRouteRequirementsInner(v *BankAccountIdentificationTypeRequirement) TransferRouteRequirementsInner {
	return TransferRouteRequirementsInner{
		BankAccountIdentificationTypeRequirement: v,
	}
}

// IbanAccountIdentificationRequirementAsTransferRouteRequirementsInner is a convenience function that returns IbanAccountIdentificationRequirement wrapped in TransferRouteRequirementsInner
func IbanAccountIdentificationRequirementAsTransferRouteRequirementsInner(v *IbanAccountIdentificationRequirement) TransferRouteRequirementsInner {
	return TransferRouteRequirementsInner{
		IbanAccountIdentificationRequirement: v,
	}
}

// PaymentInstrumentRequirementAsTransferRouteRequirementsInner is a convenience function that returns PaymentInstrumentRequirement wrapped in TransferRouteRequirementsInner
func PaymentInstrumentRequirementAsTransferRouteRequirementsInner(v *PaymentInstrumentRequirement) TransferRouteRequirementsInner {
	return TransferRouteRequirementsInner{
		PaymentInstrumentRequirement: v,
	}
}

// USInstantPayoutAddressRequirementAsTransferRouteRequirementsInner is a convenience function that returns USInstantPayoutAddressRequirement wrapped in TransferRouteRequirementsInner
func USInstantPayoutAddressRequirementAsTransferRouteRequirementsInner(v *USInstantPayoutAddressRequirement) TransferRouteRequirementsInner {
	return TransferRouteRequirementsInner{
		USInstantPayoutAddressRequirement: v,
	}
}

// USInternationalAchAddressRequirementAsTransferRouteRequirementsInner is a convenience function that returns USInternationalAchAddressRequirement wrapped in TransferRouteRequirementsInner
func USInternationalAchAddressRequirementAsTransferRouteRequirementsInner(v *USInternationalAchAddressRequirement) TransferRouteRequirementsInner {
	return TransferRouteRequirementsInner{
		USInternationalAchAddressRequirement: v,
	}
}

// Unmarshal JSON data into one of the pointers in the struct
func (dst *TransferRouteRequirementsInner) UnmarshalJSON(data []byte) error {
	var err error
	match := 0
	// try to unmarshal data into AddressRequirement
	err = json.Unmarshal(data, &dst.AddressRequirement)
	if err == nil {
		jsonAddressRequirement, _ := json.Marshal(dst.AddressRequirement)
		if string(jsonAddressRequirement) == "{}" || !dst.AddressRequirement.isValidType() { // empty struct
			dst.AddressRequirement = nil
		} else {
			match++
		}
	} else {
		dst.AddressRequirement = nil
	}

	// try to unmarshal data into AmountMinMaxRequirement
	err = json.Unmarshal(data, &dst.AmountMinMaxRequirement)
	if err == nil {
		jsonAmountMinMaxRequirement, _ := json.Marshal(dst.AmountMinMaxRequirement)
		if string(jsonAmountMinMaxRequirement) == "{}" || !dst.AmountMinMaxRequirement.isValidType() { // empty struct
			dst.AmountMinMaxRequirement = nil
		} else {
			match++
		}
	} else {
		dst.AmountMinMaxRequirement = nil
	}

	// try to unmarshal data into AmountNonZeroDecimalsRequirement
	err = json.Unmarshal(data, &dst.AmountNonZeroDecimalsRequirement)
	if err == nil {
		jsonAmountNonZeroDecimalsRequirement, _ := json.Marshal(dst.AmountNonZeroDecimalsRequirement)
		if string(jsonAmountNonZeroDecimalsRequirement) == "{}" || !dst.AmountNonZeroDecimalsRequirement.isValidType() { // empty struct
			dst.AmountNonZeroDecimalsRequirement = nil
		} else {
			match++
		}
	} else {
		dst.AmountNonZeroDecimalsRequirement = nil
	}

	// try to unmarshal data into BankAccountIdentificationTypeRequirement
	err = json.Unmarshal(data, &dst.BankAccountIdentificationTypeRequirement)
	if err == nil {
		jsonBankAccountIdentificationTypeRequirement, _ := json.Marshal(dst.BankAccountIdentificationTypeRequirement)
		if string(jsonBankAccountIdentificationTypeRequirement) == "{}" || !dst.BankAccountIdentificationTypeRequirement.isValidType() { // empty struct
			dst.BankAccountIdentificationTypeRequirement = nil
		} else {
			match++
		}
	} else {
		dst.BankAccountIdentificationTypeRequirement = nil
	}

	// try to unmarshal data into IbanAccountIdentificationRequirement
	err = json.Unmarshal(data, &dst.IbanAccountIdentificationRequirement)
	if err == nil {
		jsonIbanAccountIdentificationRequirement, _ := json.Marshal(dst.IbanAccountIdentificationRequirement)
		if string(jsonIbanAccountIdentificationRequirement) == "{}" || !dst.IbanAccountIdentificationRequirement.isValidType() { // empty struct
			dst.IbanAccountIdentificationRequirement = nil
		} else {
			match++
		}
	} else {
		dst.IbanAccountIdentificationRequirement = nil
	}

	// try to unmarshal data into PaymentInstrumentRequirement
	err = json.Unmarshal(data, &dst.PaymentInstrumentRequirement)
	if err == nil {
		jsonPaymentInstrumentRequirement, _ := json.Marshal(dst.PaymentInstrumentRequirement)
		if string(jsonPaymentInstrumentRequirement) == "{}" || !dst.PaymentInstrumentRequirement.isValidType() { // empty struct
			dst.PaymentInstrumentRequirement = nil
		} else {
			match++
		}
	} else {
		dst.PaymentInstrumentRequirement = nil
	}

	// try to unmarshal data into USInstantPayoutAddressRequirement
	err = json.Unmarshal(data, &dst.USInstantPayoutAddressRequirement)
	if err == nil {
		jsonUSInstantPayoutAddressRequirement, _ := json.Marshal(dst.USInstantPayoutAddressRequirement)
		if string(jsonUSInstantPayoutAddressRequirement) == "{}" || !dst.USInstantPayoutAddressRequirement.isValidType() { // empty struct
			dst.USInstantPayoutAddressRequirement = nil
		} else {
			match++
		}
	} else {
		dst.USInstantPayoutAddressRequirement = nil
	}

	// try to unmarshal data into USInternationalAchAddressRequirement
	err = json.Unmarshal(data, &dst.USInternationalAchAddressRequirement)
	if err == nil {
		jsonUSInternationalAchAddressRequirement, _ := json.Marshal(dst.USInternationalAchAddressRequirement)
		if string(jsonUSInternationalAchAddressRequirement) == "{}" || !dst.USInternationalAchAddressRequirement.isValidType() { // empty struct
			dst.USInternationalAchAddressRequirement = nil
		} else {
			match++
		}
	} else {
		dst.USInternationalAchAddressRequirement = nil
	}

	if match > 1 { // more than 1 match
		// reset to nil
		dst.AddressRequirement = nil
		dst.AmountMinMaxRequirement = nil
		dst.AmountNonZeroDecimalsRequirement = nil
		dst.BankAccountIdentificationTypeRequirement = nil
		dst.IbanAccountIdentificationRequirement = nil
		dst.PaymentInstrumentRequirement = nil
		dst.USInstantPayoutAddressRequirement = nil
		dst.USInternationalAchAddressRequirement = nil

		return fmt.Errorf("data matches more than one schema in oneOf(TransferRouteRequirementsInner)")
	} else if match == 1 {
		return nil // exactly one match
	} else { // no match
		return fmt.Errorf("data failed to match schemas in oneOf(TransferRouteRequirementsInner)")
	}
}

// Marshal data from the first non-nil pointers in the struct to JSON
func (src TransferRouteRequirementsInner) MarshalJSON() ([]byte, error) {
	if src.AddressRequirement != nil {
		return json.Marshal(&src.AddressRequirement)
	}

	if src.AmountMinMaxRequirement != nil {
		return json.Marshal(&src.AmountMinMaxRequirement)
	}

	if src.AmountNonZeroDecimalsRequirement != nil {
		return json.Marshal(&src.AmountNonZeroDecimalsRequirement)
	}

	if src.BankAccountIdentificationTypeRequirement != nil {
		return json.Marshal(&src.BankAccountIdentificationTypeRequirement)
	}

	if src.IbanAccountIdentificationRequirement != nil {
		return json.Marshal(&src.IbanAccountIdentificationRequirement)
	}

	if src.PaymentInstrumentRequirement != nil {
		return json.Marshal(&src.PaymentInstrumentRequirement)
	}

	if src.USInstantPayoutAddressRequirement != nil {
		return json.Marshal(&src.USInstantPayoutAddressRequirement)
	}

	if src.USInternationalAchAddressRequirement != nil {
		return json.Marshal(&src.USInternationalAchAddressRequirement)
	}

	return nil, nil // no data in oneOf schemas
}

// Get the actual instance
func (obj *TransferRouteRequirementsInner) GetActualInstance() interface{} {
	if obj == nil {
		return nil
	}
	if obj.AddressRequirement != nil {
		return obj.AddressRequirement
	}

	if obj.AmountMinMaxRequirement != nil {
		return obj.AmountMinMaxRequirement
	}

	if obj.AmountNonZeroDecimalsRequirement != nil {
		return obj.AmountNonZeroDecimalsRequirement
	}

	if obj.BankAccountIdentificationTypeRequirement != nil {
		return obj.BankAccountIdentificationTypeRequirement
	}

	if obj.IbanAccountIdentificationRequirement != nil {
		return obj.IbanAccountIdentificationRequirement
	}

	if obj.PaymentInstrumentRequirement != nil {
		return obj.PaymentInstrumentRequirement
	}

	if obj.USInstantPayoutAddressRequirement != nil {
		return obj.USInstantPayoutAddressRequirement
	}

	if obj.USInternationalAchAddressRequirement != nil {
		return obj.USInternationalAchAddressRequirement
	}

	// all schemas are nil
	return nil
}

type NullableTransferRouteRequirementsInner struct {
	value *TransferRouteRequirementsInner
	isSet bool
}

func (v NullableTransferRouteRequirementsInner) Get() *TransferRouteRequirementsInner {
	return v.value
}

func (v *NullableTransferRouteRequirementsInner) Set(val *TransferRouteRequirementsInner) {
	v.value = val
	v.isSet = true
}

func (v NullableTransferRouteRequirementsInner) IsSet() bool {
	return v.isSet
}

func (v *NullableTransferRouteRequirementsInner) Unset() {
	v.value = nil
	v.isSet = false
}

func NewNullableTransferRouteRequirementsInner(val *TransferRouteRequirementsInner) *NullableTransferRouteRequirementsInner {
	return &NullableTransferRouteRequirementsInner{value: val, isSet: true}
}

func (v NullableTransferRouteRequirementsInner) MarshalJSON() ([]byte, error) {
	return json.Marshal(v.value)
}

func (v *NullableTransferRouteRequirementsInner) UnmarshalJSON(src []byte) error {
	v.isSet = true
	return json.Unmarshal(src, &v.value)
}
