// 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 DestinationPostgresSchemasSSLModeSSLModes6Mode string

const (
	DestinationPostgresSchemasSSLModeSSLModes6ModeVerifyFull DestinationPostgresSchemasSSLModeSSLModes6Mode = "verify-full"
)

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

// DestinationPostgresVerifyFull - Verify-full SSL mode.
type DestinationPostgresVerifyFull struct {
	// CA certificate
	CaCertificate string `json:"ca_certificate"`
	// Client certificate
	ClientCertificate string `json:"client_certificate"`
	// Client key
	ClientKey string `json:"client_key"`
	// Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.
	ClientKeyPassword *string                                         `json:"client_key_password,omitempty"`
	mode              *DestinationPostgresSchemasSSLModeSSLModes6Mode `const:"verify-full" json:"mode"`
}

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

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

func (o *DestinationPostgresVerifyFull) GetCaCertificate() string {
	if o == nil {
		return ""
	}
	return o.CaCertificate
}

func (o *DestinationPostgresVerifyFull) GetClientCertificate() string {
	if o == nil {
		return ""
	}
	return o.ClientCertificate
}

func (o *DestinationPostgresVerifyFull) GetClientKey() string {
	if o == nil {
		return ""
	}
	return o.ClientKey
}

func (o *DestinationPostgresVerifyFull) GetClientKeyPassword() *string {
	if o == nil {
		return nil
	}
	return o.ClientKeyPassword
}

func (o *DestinationPostgresVerifyFull) GetMode() *DestinationPostgresSchemasSSLModeSSLModes6Mode {
	return DestinationPostgresSchemasSSLModeSSLModes6ModeVerifyFull.ToPointer()
}

type DestinationPostgresSchemasSSLModeSSLModes5Mode string

const (
	DestinationPostgresSchemasSSLModeSSLModes5ModeVerifyCa DestinationPostgresSchemasSSLModeSSLModes5Mode = "verify-ca"
)

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

// DestinationPostgresVerifyCa - Verify-ca SSL mode.
type DestinationPostgresVerifyCa struct {
	// CA certificate
	CaCertificate string `json:"ca_certificate"`
	// Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.
	ClientKeyPassword *string                                         `json:"client_key_password,omitempty"`
	mode              *DestinationPostgresSchemasSSLModeSSLModes5Mode `const:"verify-ca" json:"mode"`
}

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

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

func (o *DestinationPostgresVerifyCa) GetCaCertificate() string {
	if o == nil {
		return ""
	}
	return o.CaCertificate
}

func (o *DestinationPostgresVerifyCa) GetClientKeyPassword() *string {
	if o == nil {
		return nil
	}
	return o.ClientKeyPassword
}

func (o *DestinationPostgresVerifyCa) GetMode() *DestinationPostgresSchemasSSLModeSSLModes5Mode {
	return DestinationPostgresSchemasSSLModeSSLModes5ModeVerifyCa.ToPointer()
}

type DestinationPostgresSchemasSSLModeSSLModesMode string

const (
	DestinationPostgresSchemasSSLModeSSLModesModeRequire DestinationPostgresSchemasSSLModeSSLModesMode = "require"
)

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

// DestinationPostgresRequire - Require SSL mode.
type DestinationPostgresRequire struct {
	mode *DestinationPostgresSchemasSSLModeSSLModesMode `const:"require" json:"mode"`
}

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

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

func (o *DestinationPostgresRequire) GetMode() *DestinationPostgresSchemasSSLModeSSLModesMode {
	return DestinationPostgresSchemasSSLModeSSLModesModeRequire.ToPointer()
}

type DestinationPostgresSchemasSslModeMode string

const (
	DestinationPostgresSchemasSslModeModePrefer DestinationPostgresSchemasSslModeMode = "prefer"
)

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

// DestinationPostgresPrefer - Prefer SSL mode.
type DestinationPostgresPrefer struct {
	mode *DestinationPostgresSchemasSslModeMode `const:"prefer" json:"mode"`
}

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

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

func (o *DestinationPostgresPrefer) GetMode() *DestinationPostgresSchemasSslModeMode {
	return DestinationPostgresSchemasSslModeModePrefer.ToPointer()
}

type DestinationPostgresSchemasMode string

const (
	DestinationPostgresSchemasModeAllow DestinationPostgresSchemasMode = "allow"
)

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

// DestinationPostgresAllow - Allow SSL mode.
type DestinationPostgresAllow struct {
	mode *DestinationPostgresSchemasMode `const:"allow" json:"mode"`
}

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

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

func (o *DestinationPostgresAllow) GetMode() *DestinationPostgresSchemasMode {
	return DestinationPostgresSchemasModeAllow.ToPointer()
}

type DestinationPostgresMode string

const (
	DestinationPostgresModeDisable DestinationPostgresMode = "disable"
)

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

// DestinationPostgresDisable - Disable SSL.
type DestinationPostgresDisable struct {
	mode *DestinationPostgresMode `const:"disable" json:"mode"`
}

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

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

func (o *DestinationPostgresDisable) GetMode() *DestinationPostgresMode {
	return DestinationPostgresModeDisable.ToPointer()
}

type DestinationPostgresSSLModesType string

const (
	DestinationPostgresSSLModesTypeDestinationPostgresDisable    DestinationPostgresSSLModesType = "destination-postgres_disable"
	DestinationPostgresSSLModesTypeDestinationPostgresAllow      DestinationPostgresSSLModesType = "destination-postgres_allow"
	DestinationPostgresSSLModesTypeDestinationPostgresPrefer     DestinationPostgresSSLModesType = "destination-postgres_prefer"
	DestinationPostgresSSLModesTypeDestinationPostgresRequire    DestinationPostgresSSLModesType = "destination-postgres_require"
	DestinationPostgresSSLModesTypeDestinationPostgresVerifyCa   DestinationPostgresSSLModesType = "destination-postgres_verify-ca"
	DestinationPostgresSSLModesTypeDestinationPostgresVerifyFull DestinationPostgresSSLModesType = "destination-postgres_verify-full"
)

// DestinationPostgresSSLModes - SSL connection modes.
//
//	<b>disable</b> - Chose this mode to disable encryption of communication between Airbyte and destination database
//	<b>allow</b> - Chose this mode to enable encryption only when required by the source database
//	<b>prefer</b> - Chose this mode to allow unencrypted connection only if the source database does not support encryption
//	<b>require</b> - Chose this mode to always require encryption. If the source database server does not support encryption, connection will fail
//	 <b>verify-ca</b> - Chose this mode to always require encryption and to verify that the source database server has a valid SSL certificate
//	 <b>verify-full</b> - This is the most secure mode. Chose this mode to always require encryption and to verify the identity of the source database server
//	See more information - <a href="https://jdbc.postgresql.org/documentation/head/ssl-client.html"> in the docs</a>.
type DestinationPostgresSSLModes struct {
	DestinationPostgresDisable    *DestinationPostgresDisable    `queryParam:"inline"`
	DestinationPostgresAllow      *DestinationPostgresAllow      `queryParam:"inline"`
	DestinationPostgresPrefer     *DestinationPostgresPrefer     `queryParam:"inline"`
	DestinationPostgresRequire    *DestinationPostgresRequire    `queryParam:"inline"`
	DestinationPostgresVerifyCa   *DestinationPostgresVerifyCa   `queryParam:"inline"`
	DestinationPostgresVerifyFull *DestinationPostgresVerifyFull `queryParam:"inline"`

	Type DestinationPostgresSSLModesType
}

func CreateDestinationPostgresSSLModesDestinationPostgresDisable(destinationPostgresDisable DestinationPostgresDisable) DestinationPostgresSSLModes {
	typ := DestinationPostgresSSLModesTypeDestinationPostgresDisable

	return DestinationPostgresSSLModes{
		DestinationPostgresDisable: &destinationPostgresDisable,
		Type:                       typ,
	}
}

func CreateDestinationPostgresSSLModesDestinationPostgresAllow(destinationPostgresAllow DestinationPostgresAllow) DestinationPostgresSSLModes {
	typ := DestinationPostgresSSLModesTypeDestinationPostgresAllow

	return DestinationPostgresSSLModes{
		DestinationPostgresAllow: &destinationPostgresAllow,
		Type:                     typ,
	}
}

func CreateDestinationPostgresSSLModesDestinationPostgresPrefer(destinationPostgresPrefer DestinationPostgresPrefer) DestinationPostgresSSLModes {
	typ := DestinationPostgresSSLModesTypeDestinationPostgresPrefer

	return DestinationPostgresSSLModes{
		DestinationPostgresPrefer: &destinationPostgresPrefer,
		Type:                      typ,
	}
}

func CreateDestinationPostgresSSLModesDestinationPostgresRequire(destinationPostgresRequire DestinationPostgresRequire) DestinationPostgresSSLModes {
	typ := DestinationPostgresSSLModesTypeDestinationPostgresRequire

	return DestinationPostgresSSLModes{
		DestinationPostgresRequire: &destinationPostgresRequire,
		Type:                       typ,
	}
}

func CreateDestinationPostgresSSLModesDestinationPostgresVerifyCa(destinationPostgresVerifyCa DestinationPostgresVerifyCa) DestinationPostgresSSLModes {
	typ := DestinationPostgresSSLModesTypeDestinationPostgresVerifyCa

	return DestinationPostgresSSLModes{
		DestinationPostgresVerifyCa: &destinationPostgresVerifyCa,
		Type:                        typ,
	}
}

func CreateDestinationPostgresSSLModesDestinationPostgresVerifyFull(destinationPostgresVerifyFull DestinationPostgresVerifyFull) DestinationPostgresSSLModes {
	typ := DestinationPostgresSSLModesTypeDestinationPostgresVerifyFull

	return DestinationPostgresSSLModes{
		DestinationPostgresVerifyFull: &destinationPostgresVerifyFull,
		Type:                          typ,
	}
}

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

	var destinationPostgresDisable DestinationPostgresDisable = DestinationPostgresDisable{}
	if err := utils.UnmarshalJSON(data, &destinationPostgresDisable, "", true, true); err == nil {
		u.DestinationPostgresDisable = &destinationPostgresDisable
		u.Type = DestinationPostgresSSLModesTypeDestinationPostgresDisable
		return nil
	}

	var destinationPostgresAllow DestinationPostgresAllow = DestinationPostgresAllow{}
	if err := utils.UnmarshalJSON(data, &destinationPostgresAllow, "", true, true); err == nil {
		u.DestinationPostgresAllow = &destinationPostgresAllow
		u.Type = DestinationPostgresSSLModesTypeDestinationPostgresAllow
		return nil
	}

	var destinationPostgresPrefer DestinationPostgresPrefer = DestinationPostgresPrefer{}
	if err := utils.UnmarshalJSON(data, &destinationPostgresPrefer, "", true, true); err == nil {
		u.DestinationPostgresPrefer = &destinationPostgresPrefer
		u.Type = DestinationPostgresSSLModesTypeDestinationPostgresPrefer
		return nil
	}

	var destinationPostgresRequire DestinationPostgresRequire = DestinationPostgresRequire{}
	if err := utils.UnmarshalJSON(data, &destinationPostgresRequire, "", true, true); err == nil {
		u.DestinationPostgresRequire = &destinationPostgresRequire
		u.Type = DestinationPostgresSSLModesTypeDestinationPostgresRequire
		return nil
	}

	var destinationPostgresVerifyCa DestinationPostgresVerifyCa = DestinationPostgresVerifyCa{}
	if err := utils.UnmarshalJSON(data, &destinationPostgresVerifyCa, "", true, true); err == nil {
		u.DestinationPostgresVerifyCa = &destinationPostgresVerifyCa
		u.Type = DestinationPostgresSSLModesTypeDestinationPostgresVerifyCa
		return nil
	}

	var destinationPostgresVerifyFull DestinationPostgresVerifyFull = DestinationPostgresVerifyFull{}
	if err := utils.UnmarshalJSON(data, &destinationPostgresVerifyFull, "", true, true); err == nil {
		u.DestinationPostgresVerifyFull = &destinationPostgresVerifyFull
		u.Type = DestinationPostgresSSLModesTypeDestinationPostgresVerifyFull
		return nil
	}

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

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

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

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

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

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

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

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

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

const (
	DestinationPostgresSchemasTunnelMethodTunnelMethodSSHPasswordAuth DestinationPostgresSchemasTunnelMethodTunnelMethod = "SSH_PASSWORD_AUTH"
)

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

type DestinationPostgresPasswordAuthentication 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 DestinationPostgresSchemasTunnelMethodTunnelMethod `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 (d DestinationPostgresPasswordAuthentication) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(d, "", false)
}

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

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

func (o *DestinationPostgresPasswordAuthentication) GetTunnelMethod() DestinationPostgresSchemasTunnelMethodTunnelMethod {
	return DestinationPostgresSchemasTunnelMethodTunnelMethodSSHPasswordAuth
}

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

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

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

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

const (
	DestinationPostgresSchemasTunnelMethodSSHKeyAuth DestinationPostgresSchemasTunnelMethod = "SSH_KEY_AUTH"
)

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

type DestinationPostgresSSHKeyAuthentication 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 DestinationPostgresSchemasTunnelMethod `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 (d DestinationPostgresSSHKeyAuthentication) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(d, "", false)
}

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

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

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

func (o *DestinationPostgresSSHKeyAuthentication) GetTunnelMethod() DestinationPostgresSchemasTunnelMethod {
	return DestinationPostgresSchemasTunnelMethodSSHKeyAuth
}

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

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

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

const (
	DestinationPostgresTunnelMethodNoTunnel DestinationPostgresTunnelMethod = "NO_TUNNEL"
)

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

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

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

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

func (o *DestinationPostgresNoTunnel) GetTunnelMethod() DestinationPostgresTunnelMethod {
	return DestinationPostgresTunnelMethodNoTunnel
}

type DestinationPostgresSSHTunnelMethodType string

const (
	DestinationPostgresSSHTunnelMethodTypeDestinationPostgresNoTunnel               DestinationPostgresSSHTunnelMethodType = "destination-postgres_No Tunnel"
	DestinationPostgresSSHTunnelMethodTypeDestinationPostgresSSHKeyAuthentication   DestinationPostgresSSHTunnelMethodType = "destination-postgres_SSH Key Authentication"
	DestinationPostgresSSHTunnelMethodTypeDestinationPostgresPasswordAuthentication DestinationPostgresSSHTunnelMethodType = "destination-postgres_Password Authentication"
)

// DestinationPostgresSSHTunnelMethod - Whether to initiate an SSH tunnel before connecting to the database, and if so, which kind of authentication to use.
type DestinationPostgresSSHTunnelMethod struct {
	DestinationPostgresNoTunnel               *DestinationPostgresNoTunnel               `queryParam:"inline"`
	DestinationPostgresSSHKeyAuthentication   *DestinationPostgresSSHKeyAuthentication   `queryParam:"inline"`
	DestinationPostgresPasswordAuthentication *DestinationPostgresPasswordAuthentication `queryParam:"inline"`

	Type DestinationPostgresSSHTunnelMethodType
}

func CreateDestinationPostgresSSHTunnelMethodDestinationPostgresNoTunnel(destinationPostgresNoTunnel DestinationPostgresNoTunnel) DestinationPostgresSSHTunnelMethod {
	typ := DestinationPostgresSSHTunnelMethodTypeDestinationPostgresNoTunnel

	return DestinationPostgresSSHTunnelMethod{
		DestinationPostgresNoTunnel: &destinationPostgresNoTunnel,
		Type:                        typ,
	}
}

func CreateDestinationPostgresSSHTunnelMethodDestinationPostgresSSHKeyAuthentication(destinationPostgresSSHKeyAuthentication DestinationPostgresSSHKeyAuthentication) DestinationPostgresSSHTunnelMethod {
	typ := DestinationPostgresSSHTunnelMethodTypeDestinationPostgresSSHKeyAuthentication

	return DestinationPostgresSSHTunnelMethod{
		DestinationPostgresSSHKeyAuthentication: &destinationPostgresSSHKeyAuthentication,
		Type:                                    typ,
	}
}

func CreateDestinationPostgresSSHTunnelMethodDestinationPostgresPasswordAuthentication(destinationPostgresPasswordAuthentication DestinationPostgresPasswordAuthentication) DestinationPostgresSSHTunnelMethod {
	typ := DestinationPostgresSSHTunnelMethodTypeDestinationPostgresPasswordAuthentication

	return DestinationPostgresSSHTunnelMethod{
		DestinationPostgresPasswordAuthentication: &destinationPostgresPasswordAuthentication,
		Type: typ,
	}
}

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

	var destinationPostgresNoTunnel DestinationPostgresNoTunnel = DestinationPostgresNoTunnel{}
	if err := utils.UnmarshalJSON(data, &destinationPostgresNoTunnel, "", true, true); err == nil {
		u.DestinationPostgresNoTunnel = &destinationPostgresNoTunnel
		u.Type = DestinationPostgresSSHTunnelMethodTypeDestinationPostgresNoTunnel
		return nil
	}

	var destinationPostgresSSHKeyAuthentication DestinationPostgresSSHKeyAuthentication = DestinationPostgresSSHKeyAuthentication{}
	if err := utils.UnmarshalJSON(data, &destinationPostgresSSHKeyAuthentication, "", true, true); err == nil {
		u.DestinationPostgresSSHKeyAuthentication = &destinationPostgresSSHKeyAuthentication
		u.Type = DestinationPostgresSSHTunnelMethodTypeDestinationPostgresSSHKeyAuthentication
		return nil
	}

	var destinationPostgresPasswordAuthentication DestinationPostgresPasswordAuthentication = DestinationPostgresPasswordAuthentication{}
	if err := utils.UnmarshalJSON(data, &destinationPostgresPasswordAuthentication, "", true, true); err == nil {
		u.DestinationPostgresPasswordAuthentication = &destinationPostgresPasswordAuthentication
		u.Type = DestinationPostgresSSHTunnelMethodTypeDestinationPostgresPasswordAuthentication
		return nil
	}

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

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

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

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

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

type DestinationPostgresPostgres string

const (
	DestinationPostgresPostgresPostgres DestinationPostgresPostgres = "postgres"
)

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

type DestinationPostgres struct {
	// Name of the database.
	Database string `json:"database"`
	// Disable Writing Final Tables. WARNING! The data format in _airbyte_data is likely stable but there are no guarantees that other metadata columns will remain the same in future versions
	DisableTypeDedupe *bool `default:"false" json:"disable_type_dedupe"`
	// Drop tables with CASCADE. WARNING! This will delete all data in all dependent objects (views, etc.). Use with caution. This option is intended for usecases which can easily rebuild the dependent objects.
	DropCascade *bool `default:"false" json:"drop_cascade"`
	// 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"`
	// Password associated with the username.
	Password *string `json:"password,omitempty"`
	// Port of the database.
	Port *int64 `default:"5432" json:"port"`
	// The schema to write raw tables into
	RawDataSchema *string `json:"raw_data_schema,omitempty"`
	// The default schema tables are written to if the source does not specify a namespace. The usual value for this field is "public".
	Schema *string `default:"public" json:"schema"`
	// Encrypt data using SSL. When activating SSL, please select one of the connection modes.
	Ssl *bool `default:"false" json:"ssl"`
	// SSL connection modes.
	//  <b>disable</b> - Chose this mode to disable encryption of communication between Airbyte and destination database
	//  <b>allow</b> - Chose this mode to enable encryption only when required by the source database
	//  <b>prefer</b> - Chose this mode to allow unencrypted connection only if the source database does not support encryption
	//  <b>require</b> - Chose this mode to always require encryption. If the source database server does not support encryption, connection will fail
	//   <b>verify-ca</b> - Chose this mode to always require encryption and to verify that the source database server has a valid SSL certificate
	//   <b>verify-full</b> - This is the most secure mode. Chose this mode to always require encryption and to verify the identity of the source database server
	//  See more information - <a href="https://jdbc.postgresql.org/documentation/head/ssl-client.html"> in the docs</a>.
	SslMode *DestinationPostgresSSLModes `json:"ssl_mode,omitempty"`
	// Whether to initiate an SSH tunnel before connecting to the database, and if so, which kind of authentication to use.
	TunnelMethod *DestinationPostgresSSHTunnelMethod `json:"tunnel_method,omitempty"`
	// Create numeric columns as unconstrained DECIMAL instead of NUMBER(38, 9). This will allow increased precision in numeric values. (this is disabled by default for backwards compatibility, but is recommended to enable)
	UnconstrainedNumber *bool `default:"false" json:"unconstrained_number"`
	// Username to use to access the database.
	Username        string                      `json:"username"`
	destinationType DestinationPostgresPostgres `const:"postgres" json:"destinationType"`
}

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

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

func (o *DestinationPostgres) GetDatabase() string {
	if o == nil {
		return ""
	}
	return o.Database
}

func (o *DestinationPostgres) GetDisableTypeDedupe() *bool {
	if o == nil {
		return nil
	}
	return o.DisableTypeDedupe
}

func (o *DestinationPostgres) GetDropCascade() *bool {
	if o == nil {
		return nil
	}
	return o.DropCascade
}

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

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

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

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

func (o *DestinationPostgres) GetRawDataSchema() *string {
	if o == nil {
		return nil
	}
	return o.RawDataSchema
}

func (o *DestinationPostgres) GetSchema() *string {
	if o == nil {
		return nil
	}
	return o.Schema
}

func (o *DestinationPostgres) GetSsl() *bool {
	if o == nil {
		return nil
	}
	return o.Ssl
}

func (o *DestinationPostgres) GetSslMode() *DestinationPostgresSSLModes {
	if o == nil {
		return nil
	}
	return o.SslMode
}

func (o *DestinationPostgres) GetTunnelMethod() *DestinationPostgresSSHTunnelMethod {
	if o == nil {
		return nil
	}
	return o.TunnelMethod
}

func (o *DestinationPostgres) GetUnconstrainedNumber() *bool {
	if o == nil {
		return nil
	}
	return o.UnconstrainedNumber
}

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

func (o *DestinationPostgres) GetDestinationType() DestinationPostgresPostgres {
	return DestinationPostgresPostgresPostgres
}
