// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.

package shared

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/airbytehq/terraform-provider-airbyte/internal/sdk/internal/utils"
)

type SourceOracleConnectionType string

const (
	SourceOracleConnectionTypeSid SourceOracleConnectionType = "sid"
)

func (e SourceOracleConnectionType) ToPointer() *SourceOracleConnectionType {
	return &e
}
func (e *SourceOracleConnectionType) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch v {
	case "sid":
		*e = SourceOracleConnectionType(v)
		return nil
	default:
		return fmt.Errorf("invalid value for SourceOracleConnectionType: %v", v)
	}
}

// SystemIDSID - Use SID (Oracle System Identifier)
type SystemIDSID struct {
	connectionType *SourceOracleConnectionType `const:"sid" json:"connection_type,omitempty"`
	Sid            string                      `json:"sid"`
}

func (s SystemIDSID) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(s, "", false)
}

func (s *SystemIDSID) UnmarshalJSON(data []byte) error {
	if err := utils.UnmarshalJSON(data, &s, "", false, true); err != nil {
		return err
	}
	return nil
}

func (o *SystemIDSID) GetConnectionType() *SourceOracleConnectionType {
	return SourceOracleConnectionTypeSid.ToPointer()
}

func (o *SystemIDSID) GetSid() string {
	if o == nil {
		return ""
	}
	return o.Sid
}

type ConnectionType string

const (
	ConnectionTypeServiceName ConnectionType = "service_name"
)

func (e ConnectionType) ToPointer() *ConnectionType {
	return &e
}
func (e *ConnectionType) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch v {
	case "service_name":
		*e = ConnectionType(v)
		return nil
	default:
		return fmt.Errorf("invalid value for ConnectionType: %v", v)
	}
}

// ServiceName - Use service name
type ServiceName struct {
	connectionType *ConnectionType `const:"service_name" json:"connection_type,omitempty"`
	ServiceName    string          `json:"service_name"`
}

func (s ServiceName) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(s, "", false)
}

func (s *ServiceName) UnmarshalJSON(data []byte) error {
	if err := utils.UnmarshalJSON(data, &s, "", false, true); err != nil {
		return err
	}
	return nil
}

func (o *ServiceName) GetConnectionType() *ConnectionType {
	return ConnectionTypeServiceName.ToPointer()
}

func (o *ServiceName) GetServiceName() string {
	if o == nil {
		return ""
	}
	return o.ServiceName
}

type ConnectByType string

const (
	ConnectByTypeServiceName ConnectByType = "Service name"
	ConnectByTypeSystemIDSID ConnectByType = "System ID (SID)"
)

// ConnectBy - Connect data that will be used for DB connection
type ConnectBy struct {
	ServiceName *ServiceName `queryParam:"inline"`
	SystemIDSID *SystemIDSID `queryParam:"inline"`

	Type ConnectByType
}

func CreateConnectByServiceName(serviceName ServiceName) ConnectBy {
	typ := ConnectByTypeServiceName

	return ConnectBy{
		ServiceName: &serviceName,
		Type:        typ,
	}
}

func CreateConnectBySystemIDSID(systemIDSID SystemIDSID) ConnectBy {
	typ := ConnectByTypeSystemIDSID

	return ConnectBy{
		SystemIDSID: &systemIDSID,
		Type:        typ,
	}
}

func (u *ConnectBy) UnmarshalJSON(data []byte) error {

	var serviceName ServiceName = ServiceName{}
	if err := utils.UnmarshalJSON(data, &serviceName, "", true, true); err == nil {
		u.ServiceName = &serviceName
		u.Type = ConnectByTypeServiceName
		return nil
	}

	var systemIDSID SystemIDSID = SystemIDSID{}
	if err := utils.UnmarshalJSON(data, &systemIDSID, "", true, true); err == nil {
		u.SystemIDSID = &systemIDSID
		u.Type = ConnectByTypeSystemIDSID
		return nil
	}

	return fmt.Errorf("could not unmarshal `%s` into any supported union types for ConnectBy", string(data))
}

func (u ConnectBy) MarshalJSON() ([]byte, error) {
	if u.ServiceName != nil {
		return utils.MarshalJSON(u.ServiceName, "", true)
	}

	if u.SystemIDSID != nil {
		return utils.MarshalJSON(u.SystemIDSID, "", true)
	}

	return nil, errors.New("could not marshal union type ConnectBy: all fields are null")
}

type SourceOracleSchemasEncryptionMethod string

const (
	SourceOracleSchemasEncryptionMethodEncryptedVerifyCertificate SourceOracleSchemasEncryptionMethod = "encrypted_verify_certificate"
)

func (e SourceOracleSchemasEncryptionMethod) ToPointer() *SourceOracleSchemasEncryptionMethod {
	return &e
}
func (e *SourceOracleSchemasEncryptionMethod) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch v {
	case "encrypted_verify_certificate":
		*e = SourceOracleSchemasEncryptionMethod(v)
		return nil
	default:
		return fmt.Errorf("invalid value for SourceOracleSchemasEncryptionMethod: %v", v)
	}
}

// TLSEncryptedVerifyCertificate - Verify and use the certificate provided by the server.
type TLSEncryptedVerifyCertificate struct {
	encryptionMethod SourceOracleSchemasEncryptionMethod `const:"encrypted_verify_certificate" json:"encryption_method"`
	// Privacy Enhanced Mail (PEM) files are concatenated certificate containers frequently used in certificate installations.
	SslCertificate string `json:"ssl_certificate"`
}

func (t TLSEncryptedVerifyCertificate) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(t, "", false)
}

func (t *TLSEncryptedVerifyCertificate) UnmarshalJSON(data []byte) error {
	if err := utils.UnmarshalJSON(data, &t, "", false, true); err != nil {
		return err
	}
	return nil
}

func (o *TLSEncryptedVerifyCertificate) GetEncryptionMethod() SourceOracleSchemasEncryptionMethod {
	return SourceOracleSchemasEncryptionMethodEncryptedVerifyCertificate
}

func (o *TLSEncryptedVerifyCertificate) GetSslCertificate() string {
	if o == nil {
		return ""
	}
	return o.SslCertificate
}

// EncryptionAlgorithm - This parameter defines what encryption algorithm is used.
type EncryptionAlgorithm string

const (
	EncryptionAlgorithmAes256      EncryptionAlgorithm = "AES256"
	EncryptionAlgorithmRc456       EncryptionAlgorithm = "RC4_56"
	EncryptionAlgorithmThreeDes168 EncryptionAlgorithm = "3DES168"
)

func (e EncryptionAlgorithm) ToPointer() *EncryptionAlgorithm {
	return &e
}
func (e *EncryptionAlgorithm) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch v {
	case "AES256":
		fallthrough
	case "RC4_56":
		fallthrough
	case "3DES168":
		*e = EncryptionAlgorithm(v)
		return nil
	default:
		return fmt.Errorf("invalid value for EncryptionAlgorithm: %v", v)
	}
}

type SourceOracleEncryptionMethod string

const (
	SourceOracleEncryptionMethodClientNne SourceOracleEncryptionMethod = "client_nne"
)

func (e SourceOracleEncryptionMethod) ToPointer() *SourceOracleEncryptionMethod {
	return &e
}
func (e *SourceOracleEncryptionMethod) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch v {
	case "client_nne":
		*e = SourceOracleEncryptionMethod(v)
		return nil
	default:
		return fmt.Errorf("invalid value for SourceOracleEncryptionMethod: %v", v)
	}
}

// NativeNetworkEncryptionNNE - The native network encryption gives you the ability to encrypt database connections, without the configuration overhead of TCP/IP and SSL/TLS and without the need to open and listen on different ports.
type NativeNetworkEncryptionNNE struct {
	// This parameter defines what encryption algorithm is used.
	EncryptionAlgorithm *EncryptionAlgorithm         `default:"AES256" json:"encryption_algorithm"`
	encryptionMethod    SourceOracleEncryptionMethod `const:"client_nne" json:"encryption_method"`
}

func (n NativeNetworkEncryptionNNE) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(n, "", false)
}

func (n *NativeNetworkEncryptionNNE) UnmarshalJSON(data []byte) error {
	if err := utils.UnmarshalJSON(data, &n, "", false, true); err != nil {
		return err
	}
	return nil
}

func (o *NativeNetworkEncryptionNNE) GetEncryptionAlgorithm() *EncryptionAlgorithm {
	if o == nil {
		return nil
	}
	return o.EncryptionAlgorithm
}

func (o *NativeNetworkEncryptionNNE) GetEncryptionMethod() SourceOracleEncryptionMethod {
	return SourceOracleEncryptionMethodClientNne
}

type EncryptionMethod string

const (
	EncryptionMethodUnencrypted EncryptionMethod = "unencrypted"
)

func (e EncryptionMethod) ToPointer() *EncryptionMethod {
	return &e
}
func (e *EncryptionMethod) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch v {
	case "unencrypted":
		*e = EncryptionMethod(v)
		return nil
	default:
		return fmt.Errorf("invalid value for EncryptionMethod: %v", v)
	}
}

// SourceOracleUnencrypted - Data transfer will not be encrypted.
type SourceOracleUnencrypted struct {
	encryptionMethod EncryptionMethod `const:"unencrypted" json:"encryption_method"`
}

func (s SourceOracleUnencrypted) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(s, "", false)
}

func (s *SourceOracleUnencrypted) UnmarshalJSON(data []byte) error {
	if err := utils.UnmarshalJSON(data, &s, "", false, true); err != nil {
		return err
	}
	return nil
}

func (o *SourceOracleUnencrypted) GetEncryptionMethod() EncryptionMethod {
	return EncryptionMethodUnencrypted
}

type SourceOracleEncryptionType string

const (
	SourceOracleEncryptionTypeSourceOracleUnencrypted       SourceOracleEncryptionType = "source-oracle_Unencrypted"
	SourceOracleEncryptionTypeNativeNetworkEncryptionNNE    SourceOracleEncryptionType = "Native Network Encryption (NNE)"
	SourceOracleEncryptionTypeTLSEncryptedVerifyCertificate SourceOracleEncryptionType = "TLS Encrypted (verify certificate)"
)

// SourceOracleEncryption - The encryption method with is used when communicating with the database.
type SourceOracleEncryption struct {
	SourceOracleUnencrypted       *SourceOracleUnencrypted       `queryParam:"inline"`
	NativeNetworkEncryptionNNE    *NativeNetworkEncryptionNNE    `queryParam:"inline"`
	TLSEncryptedVerifyCertificate *TLSEncryptedVerifyCertificate `queryParam:"inline"`

	Type SourceOracleEncryptionType
}

func CreateSourceOracleEncryptionSourceOracleUnencrypted(sourceOracleUnencrypted SourceOracleUnencrypted) SourceOracleEncryption {
	typ := SourceOracleEncryptionTypeSourceOracleUnencrypted

	return SourceOracleEncryption{
		SourceOracleUnencrypted: &sourceOracleUnencrypted,
		Type:                    typ,
	}
}

func CreateSourceOracleEncryptionNativeNetworkEncryptionNNE(nativeNetworkEncryptionNNE NativeNetworkEncryptionNNE) SourceOracleEncryption {
	typ := SourceOracleEncryptionTypeNativeNetworkEncryptionNNE

	return SourceOracleEncryption{
		NativeNetworkEncryptionNNE: &nativeNetworkEncryptionNNE,
		Type:                       typ,
	}
}

func CreateSourceOracleEncryptionTLSEncryptedVerifyCertificate(tlsEncryptedVerifyCertificate TLSEncryptedVerifyCertificate) SourceOracleEncryption {
	typ := SourceOracleEncryptionTypeTLSEncryptedVerifyCertificate

	return SourceOracleEncryption{
		TLSEncryptedVerifyCertificate: &tlsEncryptedVerifyCertificate,
		Type:                          typ,
	}
}

func (u *SourceOracleEncryption) UnmarshalJSON(data []byte) error {

	var sourceOracleUnencrypted SourceOracleUnencrypted = SourceOracleUnencrypted{}
	if err := utils.UnmarshalJSON(data, &sourceOracleUnencrypted, "", true, true); err == nil {
		u.SourceOracleUnencrypted = &sourceOracleUnencrypted
		u.Type = SourceOracleEncryptionTypeSourceOracleUnencrypted
		return nil
	}

	var nativeNetworkEncryptionNNE NativeNetworkEncryptionNNE = NativeNetworkEncryptionNNE{}
	if err := utils.UnmarshalJSON(data, &nativeNetworkEncryptionNNE, "", true, true); err == nil {
		u.NativeNetworkEncryptionNNE = &nativeNetworkEncryptionNNE
		u.Type = SourceOracleEncryptionTypeNativeNetworkEncryptionNNE
		return nil
	}

	var tlsEncryptedVerifyCertificate TLSEncryptedVerifyCertificate = TLSEncryptedVerifyCertificate{}
	if err := utils.UnmarshalJSON(data, &tlsEncryptedVerifyCertificate, "", true, true); err == nil {
		u.TLSEncryptedVerifyCertificate = &tlsEncryptedVerifyCertificate
		u.Type = SourceOracleEncryptionTypeTLSEncryptedVerifyCertificate
		return nil
	}

	return fmt.Errorf("could not unmarshal `%s` into any supported union types for SourceOracleEncryption", string(data))
}

func (u SourceOracleEncryption) MarshalJSON() ([]byte, error) {
	if u.SourceOracleUnencrypted != nil {
		return utils.MarshalJSON(u.SourceOracleUnencrypted, "", true)
	}

	if u.NativeNetworkEncryptionNNE != nil {
		return utils.MarshalJSON(u.NativeNetworkEncryptionNNE, "", true)
	}

	if u.TLSEncryptedVerifyCertificate != nil {
		return utils.MarshalJSON(u.TLSEncryptedVerifyCertificate, "", true)
	}

	return nil, errors.New("could not marshal union type SourceOracleEncryption: all fields are null")
}

// SourceOracleSchemasTunnelMethodTunnelMethod - Connect through a jump server tunnel host using username and password authentication
type SourceOracleSchemasTunnelMethodTunnelMethod string

const (
	SourceOracleSchemasTunnelMethodTunnelMethodSSHPasswordAuth SourceOracleSchemasTunnelMethodTunnelMethod = "SSH_PASSWORD_AUTH"
)

func (e SourceOracleSchemasTunnelMethodTunnelMethod) ToPointer() *SourceOracleSchemasTunnelMethodTunnelMethod {
	return &e
}
func (e *SourceOracleSchemasTunnelMethodTunnelMethod) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch v {
	case "SSH_PASSWORD_AUTH":
		*e = SourceOracleSchemasTunnelMethodTunnelMethod(v)
		return nil
	default:
		return fmt.Errorf("invalid value for SourceOracleSchemasTunnelMethodTunnelMethod: %v", v)
	}
}

type SourceOraclePasswordAuthentication struct {
	// Hostname of the jump server host that allows inbound ssh tunnel.
	TunnelHost string `json:"tunnel_host"`
	// Connect through a jump server tunnel host using username and password authentication
	tunnelMethod SourceOracleSchemasTunnelMethodTunnelMethod `const:"SSH_PASSWORD_AUTH" json:"tunnel_method"`
	// Port on the proxy/jump server that accepts inbound ssh connections.
	TunnelPort *int64 `default:"22" json:"tunnel_port"`
	// OS-level username for logging into the jump server host
	TunnelUser string `json:"tunnel_user"`
	// OS-level password for logging into the jump server host
	TunnelUserPassword string `json:"tunnel_user_password"`
}

func (s SourceOraclePasswordAuthentication) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(s, "", false)
}

func (s *SourceOraclePasswordAuthentication) UnmarshalJSON(data []byte) error {
	if err := utils.UnmarshalJSON(data, &s, "", false, true); err != nil {
		return err
	}
	return nil
}

func (o *SourceOraclePasswordAuthentication) GetTunnelHost() string {
	if o == nil {
		return ""
	}
	return o.TunnelHost
}

func (o *SourceOraclePasswordAuthentication) GetTunnelMethod() SourceOracleSchemasTunnelMethodTunnelMethod {
	return SourceOracleSchemasTunnelMethodTunnelMethodSSHPasswordAuth
}

func (o *SourceOraclePasswordAuthentication) GetTunnelPort() *int64 {
	if o == nil {
		return nil
	}
	return o.TunnelPort
}

func (o *SourceOraclePasswordAuthentication) GetTunnelUser() string {
	if o == nil {
		return ""
	}
	return o.TunnelUser
}

func (o *SourceOraclePasswordAuthentication) GetTunnelUserPassword() string {
	if o == nil {
		return ""
	}
	return o.TunnelUserPassword
}

// SourceOracleSchemasTunnelMethod - Connect through a jump server tunnel host using username and ssh key
type SourceOracleSchemasTunnelMethod string

const (
	SourceOracleSchemasTunnelMethodSSHKeyAuth SourceOracleSchemasTunnelMethod = "SSH_KEY_AUTH"
)

func (e SourceOracleSchemasTunnelMethod) ToPointer() *SourceOracleSchemasTunnelMethod {
	return &e
}
func (e *SourceOracleSchemasTunnelMethod) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch v {
	case "SSH_KEY_AUTH":
		*e = SourceOracleSchemasTunnelMethod(v)
		return nil
	default:
		return fmt.Errorf("invalid value for SourceOracleSchemasTunnelMethod: %v", v)
	}
}

type SourceOracleSSHKeyAuthentication struct {
	// OS-level user account ssh key credentials in RSA PEM format ( created with ssh-keygen -t rsa -m PEM -f myuser_rsa )
	SSHKey string `json:"ssh_key"`
	// Hostname of the jump server host that allows inbound ssh tunnel.
	TunnelHost string `json:"tunnel_host"`
	// Connect through a jump server tunnel host using username and ssh key
	tunnelMethod SourceOracleSchemasTunnelMethod `const:"SSH_KEY_AUTH" json:"tunnel_method"`
	// Port on the proxy/jump server that accepts inbound ssh connections.
	TunnelPort *int64 `default:"22" json:"tunnel_port"`
	// OS-level username for logging into the jump server host.
	TunnelUser string `json:"tunnel_user"`
}

func (s SourceOracleSSHKeyAuthentication) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(s, "", false)
}

func (s *SourceOracleSSHKeyAuthentication) UnmarshalJSON(data []byte) error {
	if err := utils.UnmarshalJSON(data, &s, "", false, true); err != nil {
		return err
	}
	return nil
}

func (o *SourceOracleSSHKeyAuthentication) GetSSHKey() string {
	if o == nil {
		return ""
	}
	return o.SSHKey
}

func (o *SourceOracleSSHKeyAuthentication) GetTunnelHost() string {
	if o == nil {
		return ""
	}
	return o.TunnelHost
}

func (o *SourceOracleSSHKeyAuthentication) GetTunnelMethod() SourceOracleSchemasTunnelMethod {
	return SourceOracleSchemasTunnelMethodSSHKeyAuth
}

func (o *SourceOracleSSHKeyAuthentication) GetTunnelPort() *int64 {
	if o == nil {
		return nil
	}
	return o.TunnelPort
}

func (o *SourceOracleSSHKeyAuthentication) GetTunnelUser() string {
	if o == nil {
		return ""
	}
	return o.TunnelUser
}

// SourceOracleTunnelMethod - No ssh tunnel needed to connect to database
type SourceOracleTunnelMethod string

const (
	SourceOracleTunnelMethodNoTunnel SourceOracleTunnelMethod = "NO_TUNNEL"
)

func (e SourceOracleTunnelMethod) ToPointer() *SourceOracleTunnelMethod {
	return &e
}
func (e *SourceOracleTunnelMethod) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch v {
	case "NO_TUNNEL":
		*e = SourceOracleTunnelMethod(v)
		return nil
	default:
		return fmt.Errorf("invalid value for SourceOracleTunnelMethod: %v", v)
	}
}

type SourceOracleNoTunnel struct {
	// No ssh tunnel needed to connect to database
	tunnelMethod SourceOracleTunnelMethod `const:"NO_TUNNEL" json:"tunnel_method"`
}

func (s SourceOracleNoTunnel) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(s, "", false)
}

func (s *SourceOracleNoTunnel) UnmarshalJSON(data []byte) error {
	if err := utils.UnmarshalJSON(data, &s, "", false, true); err != nil {
		return err
	}
	return nil
}

func (o *SourceOracleNoTunnel) GetTunnelMethod() SourceOracleTunnelMethod {
	return SourceOracleTunnelMethodNoTunnel
}

type SourceOracleSSHTunnelMethodType string

const (
	SourceOracleSSHTunnelMethodTypeSourceOracleNoTunnel               SourceOracleSSHTunnelMethodType = "source-oracle_No Tunnel"
	SourceOracleSSHTunnelMethodTypeSourceOracleSSHKeyAuthentication   SourceOracleSSHTunnelMethodType = "source-oracle_SSH Key Authentication"
	SourceOracleSSHTunnelMethodTypeSourceOraclePasswordAuthentication SourceOracleSSHTunnelMethodType = "source-oracle_Password Authentication"
)

// SourceOracleSSHTunnelMethod - Whether to initiate an SSH tunnel before connecting to the database, and if so, which kind of authentication to use.
type SourceOracleSSHTunnelMethod struct {
	SourceOracleNoTunnel               *SourceOracleNoTunnel               `queryParam:"inline"`
	SourceOracleSSHKeyAuthentication   *SourceOracleSSHKeyAuthentication   `queryParam:"inline"`
	SourceOraclePasswordAuthentication *SourceOraclePasswordAuthentication `queryParam:"inline"`

	Type SourceOracleSSHTunnelMethodType
}

func CreateSourceOracleSSHTunnelMethodSourceOracleNoTunnel(sourceOracleNoTunnel SourceOracleNoTunnel) SourceOracleSSHTunnelMethod {
	typ := SourceOracleSSHTunnelMethodTypeSourceOracleNoTunnel

	return SourceOracleSSHTunnelMethod{
		SourceOracleNoTunnel: &sourceOracleNoTunnel,
		Type:                 typ,
	}
}

func CreateSourceOracleSSHTunnelMethodSourceOracleSSHKeyAuthentication(sourceOracleSSHKeyAuthentication SourceOracleSSHKeyAuthentication) SourceOracleSSHTunnelMethod {
	typ := SourceOracleSSHTunnelMethodTypeSourceOracleSSHKeyAuthentication

	return SourceOracleSSHTunnelMethod{
		SourceOracleSSHKeyAuthentication: &sourceOracleSSHKeyAuthentication,
		Type:                             typ,
	}
}

func CreateSourceOracleSSHTunnelMethodSourceOraclePasswordAuthentication(sourceOraclePasswordAuthentication SourceOraclePasswordAuthentication) SourceOracleSSHTunnelMethod {
	typ := SourceOracleSSHTunnelMethodTypeSourceOraclePasswordAuthentication

	return SourceOracleSSHTunnelMethod{
		SourceOraclePasswordAuthentication: &sourceOraclePasswordAuthentication,
		Type:                               typ,
	}
}

func (u *SourceOracleSSHTunnelMethod) UnmarshalJSON(data []byte) error {

	var sourceOracleNoTunnel SourceOracleNoTunnel = SourceOracleNoTunnel{}
	if err := utils.UnmarshalJSON(data, &sourceOracleNoTunnel, "", true, true); err == nil {
		u.SourceOracleNoTunnel = &sourceOracleNoTunnel
		u.Type = SourceOracleSSHTunnelMethodTypeSourceOracleNoTunnel
		return nil
	}

	var sourceOracleSSHKeyAuthentication SourceOracleSSHKeyAuthentication = SourceOracleSSHKeyAuthentication{}
	if err := utils.UnmarshalJSON(data, &sourceOracleSSHKeyAuthentication, "", true, true); err == nil {
		u.SourceOracleSSHKeyAuthentication = &sourceOracleSSHKeyAuthentication
		u.Type = SourceOracleSSHTunnelMethodTypeSourceOracleSSHKeyAuthentication
		return nil
	}

	var sourceOraclePasswordAuthentication SourceOraclePasswordAuthentication = SourceOraclePasswordAuthentication{}
	if err := utils.UnmarshalJSON(data, &sourceOraclePasswordAuthentication, "", true, true); err == nil {
		u.SourceOraclePasswordAuthentication = &sourceOraclePasswordAuthentication
		u.Type = SourceOracleSSHTunnelMethodTypeSourceOraclePasswordAuthentication
		return nil
	}

	return fmt.Errorf("could not unmarshal `%s` into any supported union types for SourceOracleSSHTunnelMethod", string(data))
}

func (u SourceOracleSSHTunnelMethod) MarshalJSON() ([]byte, error) {
	if u.SourceOracleNoTunnel != nil {
		return utils.MarshalJSON(u.SourceOracleNoTunnel, "", true)
	}

	if u.SourceOracleSSHKeyAuthentication != nil {
		return utils.MarshalJSON(u.SourceOracleSSHKeyAuthentication, "", true)
	}

	if u.SourceOraclePasswordAuthentication != nil {
		return utils.MarshalJSON(u.SourceOraclePasswordAuthentication, "", true)
	}

	return nil, errors.New("could not marshal union type SourceOracleSSHTunnelMethod: all fields are null")
}

type Oracle string

const (
	OracleOracle Oracle = "oracle"
)

func (e Oracle) ToPointer() *Oracle {
	return &e
}
func (e *Oracle) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch v {
	case "oracle":
		*e = Oracle(v)
		return nil
	default:
		return fmt.Errorf("invalid value for Oracle: %v", v)
	}
}

type SourceOracle struct {
	// Connect data that will be used for DB connection
	ConnectionData *ConnectBy `json:"connection_data,omitempty"`
	// The encryption method with is used when communicating with the database.
	Encryption *SourceOracleEncryption `json:"encryption,omitempty"`
	// Hostname of the database.
	Host string `json:"host"`
	// Additional properties to pass to the JDBC URL string when connecting to the database formatted as 'key=value' pairs separated by the symbol '&'. (example: key1=value1&key2=value2&key3=value3).
	JdbcURLParams *string `json:"jdbc_url_params,omitempty"`
	// The password associated with the username.
	Password *string `json:"password,omitempty"`
	// Port of the database.
	// Oracle Corporations recommends the following port numbers:
	// 1521 - Default listening port for client connections to the listener.
	// 2484 - Recommended and officially registered listening port for client connections to the listener using TCP/IP with SSL
	Port *int64 `default:"1521" json:"port"`
	// The list of schemas to sync from. Defaults to user. Case sensitive.
	Schemas []string `json:"schemas,omitempty"`
	// Whether to initiate an SSH tunnel before connecting to the database, and if so, which kind of authentication to use.
	TunnelMethod *SourceOracleSSHTunnelMethod `json:"tunnel_method,omitempty"`
	// The username which is used to access the database.
	Username   string `json:"username"`
	sourceType Oracle `const:"oracle" json:"sourceType"`
}

func (s SourceOracle) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(s, "", false)
}

func (s *SourceOracle) UnmarshalJSON(data []byte) error {
	if err := utils.UnmarshalJSON(data, &s, "", false, false); err != nil {
		return err
	}
	return nil
}

func (o *SourceOracle) GetConnectionData() *ConnectBy {
	if o == nil {
		return nil
	}
	return o.ConnectionData
}

func (o *SourceOracle) GetEncryption() *SourceOracleEncryption {
	if o == nil {
		return nil
	}
	return o.Encryption
}

func (o *SourceOracle) GetHost() string {
	if o == nil {
		return ""
	}
	return o.Host
}

func (o *SourceOracle) GetJdbcURLParams() *string {
	if o == nil {
		return nil
	}
	return o.JdbcURLParams
}

func (o *SourceOracle) GetPassword() *string {
	if o == nil {
		return nil
	}
	return o.Password
}

func (o *SourceOracle) GetPort() *int64 {
	if o == nil {
		return nil
	}
	return o.Port
}

func (o *SourceOracle) GetSchemas() []string {
	if o == nil {
		return nil
	}
	return o.Schemas
}

func (o *SourceOracle) GetTunnelMethod() *SourceOracleSSHTunnelMethod {
	if o == nil {
		return nil
	}
	return o.TunnelMethod
}

func (o *SourceOracle) GetUsername() string {
	if o == nil {
		return ""
	}
	return o.Username
}

func (o *SourceOracle) GetSourceType() Oracle {
	return OracleOracle
}
