// 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"
)

// CacheType - Redis cache type to store data in.
type CacheType string

const (
	CacheTypeHash CacheType = "hash"
)

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

type DestinationRedisSchemasMode string

const (
	DestinationRedisSchemasModeVerifyFull DestinationRedisSchemasMode = "verify-full"
)

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

// DestinationRedisVerifyFull - Verify-full SSL mode.
type DestinationRedisVerifyFull 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. If you do not add it - the password will be generated automatically.
	ClientKeyPassword *string                      `json:"client_key_password,omitempty"`
	mode              *DestinationRedisSchemasMode `const:"verify-full" json:"mode"`
}

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

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

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

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

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

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

func (o *DestinationRedisVerifyFull) GetMode() *DestinationRedisSchemasMode {
	return DestinationRedisSchemasModeVerifyFull.ToPointer()
}

type DestinationRedisMode string

const (
	DestinationRedisModeDisable DestinationRedisMode = "disable"
)

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

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

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

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

func (o *DestinationRedisDisable) GetMode() *DestinationRedisMode {
	return DestinationRedisModeDisable.ToPointer()
}

type DestinationRedisSSLModesType string

const (
	DestinationRedisSSLModesTypeDestinationRedisDisable    DestinationRedisSSLModesType = "destination-redis_disable"
	DestinationRedisSSLModesTypeDestinationRedisVerifyFull DestinationRedisSSLModesType = "destination-redis_verify-full"
)

// DestinationRedisSSLModes - SSL connection modes.
//
//	<li><b>verify-full</b> - This is the most secure mode. Always require encryption and verifies the identity of the source database server
type DestinationRedisSSLModes struct {
	DestinationRedisDisable    *DestinationRedisDisable    `queryParam:"inline"`
	DestinationRedisVerifyFull *DestinationRedisVerifyFull `queryParam:"inline"`

	Type DestinationRedisSSLModesType
}

func CreateDestinationRedisSSLModesDestinationRedisDisable(destinationRedisDisable DestinationRedisDisable) DestinationRedisSSLModes {
	typ := DestinationRedisSSLModesTypeDestinationRedisDisable

	return DestinationRedisSSLModes{
		DestinationRedisDisable: &destinationRedisDisable,
		Type:                    typ,
	}
}

func CreateDestinationRedisSSLModesDestinationRedisVerifyFull(destinationRedisVerifyFull DestinationRedisVerifyFull) DestinationRedisSSLModes {
	typ := DestinationRedisSSLModesTypeDestinationRedisVerifyFull

	return DestinationRedisSSLModes{
		DestinationRedisVerifyFull: &destinationRedisVerifyFull,
		Type:                       typ,
	}
}

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

	var destinationRedisDisable DestinationRedisDisable = DestinationRedisDisable{}
	if err := utils.UnmarshalJSON(data, &destinationRedisDisable, "", true, true); err == nil {
		u.DestinationRedisDisable = &destinationRedisDisable
		u.Type = DestinationRedisSSLModesTypeDestinationRedisDisable
		return nil
	}

	var destinationRedisVerifyFull DestinationRedisVerifyFull = DestinationRedisVerifyFull{}
	if err := utils.UnmarshalJSON(data, &destinationRedisVerifyFull, "", true, true); err == nil {
		u.DestinationRedisVerifyFull = &destinationRedisVerifyFull
		u.Type = DestinationRedisSSLModesTypeDestinationRedisVerifyFull
		return nil
	}

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

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

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

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

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

const (
	DestinationRedisSchemasTunnelMethodTunnelMethodSSHPasswordAuth DestinationRedisSchemasTunnelMethodTunnelMethod = "SSH_PASSWORD_AUTH"
)

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

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

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

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

func (o *DestinationRedisPasswordAuthentication) GetTunnelMethod() DestinationRedisSchemasTunnelMethodTunnelMethod {
	return DestinationRedisSchemasTunnelMethodTunnelMethodSSHPasswordAuth
}

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

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

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

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

const (
	DestinationRedisSchemasTunnelMethodSSHKeyAuth DestinationRedisSchemasTunnelMethod = "SSH_KEY_AUTH"
)

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

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

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

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

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

func (o *DestinationRedisSSHKeyAuthentication) GetTunnelMethod() DestinationRedisSchemasTunnelMethod {
	return DestinationRedisSchemasTunnelMethodSSHKeyAuth
}

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

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

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

const (
	DestinationRedisTunnelMethodNoTunnel DestinationRedisTunnelMethod = "NO_TUNNEL"
)

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

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

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

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

func (o *DestinationRedisNoTunnel) GetTunnelMethod() DestinationRedisTunnelMethod {
	return DestinationRedisTunnelMethodNoTunnel
}

type DestinationRedisSSHTunnelMethodType string

const (
	DestinationRedisSSHTunnelMethodTypeDestinationRedisNoTunnel               DestinationRedisSSHTunnelMethodType = "destination-redis_No Tunnel"
	DestinationRedisSSHTunnelMethodTypeDestinationRedisSSHKeyAuthentication   DestinationRedisSSHTunnelMethodType = "destination-redis_SSH Key Authentication"
	DestinationRedisSSHTunnelMethodTypeDestinationRedisPasswordAuthentication DestinationRedisSSHTunnelMethodType = "destination-redis_Password Authentication"
)

// DestinationRedisSSHTunnelMethod - Whether to initiate an SSH tunnel before connecting to the database, and if so, which kind of authentication to use.
type DestinationRedisSSHTunnelMethod struct {
	DestinationRedisNoTunnel               *DestinationRedisNoTunnel               `queryParam:"inline"`
	DestinationRedisSSHKeyAuthentication   *DestinationRedisSSHKeyAuthentication   `queryParam:"inline"`
	DestinationRedisPasswordAuthentication *DestinationRedisPasswordAuthentication `queryParam:"inline"`

	Type DestinationRedisSSHTunnelMethodType
}

func CreateDestinationRedisSSHTunnelMethodDestinationRedisNoTunnel(destinationRedisNoTunnel DestinationRedisNoTunnel) DestinationRedisSSHTunnelMethod {
	typ := DestinationRedisSSHTunnelMethodTypeDestinationRedisNoTunnel

	return DestinationRedisSSHTunnelMethod{
		DestinationRedisNoTunnel: &destinationRedisNoTunnel,
		Type:                     typ,
	}
}

func CreateDestinationRedisSSHTunnelMethodDestinationRedisSSHKeyAuthentication(destinationRedisSSHKeyAuthentication DestinationRedisSSHKeyAuthentication) DestinationRedisSSHTunnelMethod {
	typ := DestinationRedisSSHTunnelMethodTypeDestinationRedisSSHKeyAuthentication

	return DestinationRedisSSHTunnelMethod{
		DestinationRedisSSHKeyAuthentication: &destinationRedisSSHKeyAuthentication,
		Type:                                 typ,
	}
}

func CreateDestinationRedisSSHTunnelMethodDestinationRedisPasswordAuthentication(destinationRedisPasswordAuthentication DestinationRedisPasswordAuthentication) DestinationRedisSSHTunnelMethod {
	typ := DestinationRedisSSHTunnelMethodTypeDestinationRedisPasswordAuthentication

	return DestinationRedisSSHTunnelMethod{
		DestinationRedisPasswordAuthentication: &destinationRedisPasswordAuthentication,
		Type:                                   typ,
	}
}

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

	var destinationRedisNoTunnel DestinationRedisNoTunnel = DestinationRedisNoTunnel{}
	if err := utils.UnmarshalJSON(data, &destinationRedisNoTunnel, "", true, true); err == nil {
		u.DestinationRedisNoTunnel = &destinationRedisNoTunnel
		u.Type = DestinationRedisSSHTunnelMethodTypeDestinationRedisNoTunnel
		return nil
	}

	var destinationRedisSSHKeyAuthentication DestinationRedisSSHKeyAuthentication = DestinationRedisSSHKeyAuthentication{}
	if err := utils.UnmarshalJSON(data, &destinationRedisSSHKeyAuthentication, "", true, true); err == nil {
		u.DestinationRedisSSHKeyAuthentication = &destinationRedisSSHKeyAuthentication
		u.Type = DestinationRedisSSHTunnelMethodTypeDestinationRedisSSHKeyAuthentication
		return nil
	}

	var destinationRedisPasswordAuthentication DestinationRedisPasswordAuthentication = DestinationRedisPasswordAuthentication{}
	if err := utils.UnmarshalJSON(data, &destinationRedisPasswordAuthentication, "", true, true); err == nil {
		u.DestinationRedisPasswordAuthentication = &destinationRedisPasswordAuthentication
		u.Type = DestinationRedisSSHTunnelMethodTypeDestinationRedisPasswordAuthentication
		return nil
	}

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

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

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

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

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

type Redis string

const (
	RedisRedis Redis = "redis"
)

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

type DestinationRedis struct {
	// Redis cache type to store data in.
	CacheType *CacheType `default:"hash" json:"cache_type"`
	// Redis host to connect to.
	Host string `json:"host"`
	// Password associated with Redis.
	Password *string `json:"password,omitempty"`
	// Port of Redis.
	Port *int64 `default:"6379" json:"port"`
	// Indicates whether SSL encryption protocol will be used to connect to Redis. It is recommended to use SSL connection if possible.
	Ssl *bool `default:"false" json:"ssl"`
	// SSL connection modes.
	//   <li><b>verify-full</b> - This is the most secure mode. Always require encryption and verifies the identity of the source database server
	SslMode *DestinationRedisSSLModes `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 *DestinationRedisSSHTunnelMethod `json:"tunnel_method,omitempty"`
	// Username associated with Redis.
	Username        string `json:"username"`
	destinationType Redis  `const:"redis" json:"destinationType"`
}

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

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

func (o *DestinationRedis) GetCacheType() *CacheType {
	if o == nil {
		return nil
	}
	return o.CacheType
}

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

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

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

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

func (o *DestinationRedis) GetSslMode() *DestinationRedisSSLModes {
	if o == nil {
		return nil
	}
	return o.SslMode
}

func (o *DestinationRedis) GetTunnelMethod() *DestinationRedisSSHTunnelMethod {
	if o == nil {
		return nil
	}
	return o.TunnelMethod
}

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

func (o *DestinationRedis) GetDestinationType() Redis {
	return RedisRedis
}
