/*
Adyen Checkout API

API version: 71
*/

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

package checkout

import (
	"encoding/json"
	"fmt"
)

// DonationPaymentMethod - The type and required details of a payment method to use.
type DonationPaymentMethod struct {
	ApplePayDonations      *ApplePayDonations
	CardDonations          *CardDonations
	GooglePayDonations     *GooglePayDonations
	IdealDonations         *IdealDonations
	PayWithGoogleDonations *PayWithGoogleDonations
}

// ApplePayDonationsAsDonationPaymentMethod is a convenience function that returns ApplePayDonations wrapped in DonationPaymentMethod
func ApplePayDonationsAsDonationPaymentMethod(v *ApplePayDonations) DonationPaymentMethod {
	return DonationPaymentMethod{
		ApplePayDonations: v,
	}
}

// CardDonationsAsDonationPaymentMethod is a convenience function that returns CardDonations wrapped in DonationPaymentMethod
func CardDonationsAsDonationPaymentMethod(v *CardDonations) DonationPaymentMethod {
	return DonationPaymentMethod{
		CardDonations: v,
	}
}

// GooglePayDonationsAsDonationPaymentMethod is a convenience function that returns GooglePayDonations wrapped in DonationPaymentMethod
func GooglePayDonationsAsDonationPaymentMethod(v *GooglePayDonations) DonationPaymentMethod {
	return DonationPaymentMethod{
		GooglePayDonations: v,
	}
}

// IdealDonationsAsDonationPaymentMethod is a convenience function that returns IdealDonations wrapped in DonationPaymentMethod
func IdealDonationsAsDonationPaymentMethod(v *IdealDonations) DonationPaymentMethod {
	return DonationPaymentMethod{
		IdealDonations: v,
	}
}

// PayWithGoogleDonationsAsDonationPaymentMethod is a convenience function that returns PayWithGoogleDonations wrapped in DonationPaymentMethod
func PayWithGoogleDonationsAsDonationPaymentMethod(v *PayWithGoogleDonations) DonationPaymentMethod {
	return DonationPaymentMethod{
		PayWithGoogleDonations: v,
	}
}

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

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

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

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

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

	if match > 1 { // more than 1 match
		// reset to nil
		dst.ApplePayDonations = nil
		dst.CardDonations = nil
		dst.GooglePayDonations = nil
		dst.IdealDonations = nil
		dst.PayWithGoogleDonations = nil

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

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

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

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

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

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

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

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

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

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

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

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

	// all schemas are nil
	return nil
}

type NullableDonationPaymentMethod struct {
	value *DonationPaymentMethod
	isSet bool
}

func (v NullableDonationPaymentMethod) Get() *DonationPaymentMethod {
	return v.value
}

func (v *NullableDonationPaymentMethod) Set(val *DonationPaymentMethod) {
	v.value = val
	v.isSet = true
}

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

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

func NewNullableDonationPaymentMethod(val *DonationPaymentMethod) *NullableDonationPaymentMethod {
	return &NullableDonationPaymentMethod{value: val, isSet: true}
}

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

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