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

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

const (
	SourceClickhouseSchemasTunnelMethodSSHPasswordAuth SourceClickhouseSchemasTunnelMethod = "SSH_PASSWORD_AUTH"
)

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

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

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

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

func (o *PasswordAuthentication) GetTunnelMethod() SourceClickhouseSchemasTunnelMethod {
	return SourceClickhouseSchemasTunnelMethodSSHPasswordAuth
}

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

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

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

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

const (
	SourceClickhouseTunnelMethodSSHKeyAuth SourceClickhouseTunnelMethod = "SSH_KEY_AUTH"
)

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

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

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

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

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

func (o *SSHKeyAuthentication) GetTunnelMethod() SourceClickhouseTunnelMethod {
	return SourceClickhouseTunnelMethodSSHKeyAuth
}

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

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

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

const (
	TunnelMethodNoTunnel TunnelMethod = "NO_TUNNEL"
)

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

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

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

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

func (o *NoTunnel) GetTunnelMethod() TunnelMethod {
	return TunnelMethodNoTunnel
}

type SSHTunnelMethodType string

const (
	SSHTunnelMethodTypeNoTunnel               SSHTunnelMethodType = "No Tunnel"
	SSHTunnelMethodTypeSSHKeyAuthentication   SSHTunnelMethodType = "SSH Key Authentication"
	SSHTunnelMethodTypePasswordAuthentication SSHTunnelMethodType = "Password Authentication"
)

// SSHTunnelMethod - Whether to initiate an SSH tunnel before connecting to the database, and if so, which kind of authentication to use.
type SSHTunnelMethod struct {
	NoTunnel               *NoTunnel               `queryParam:"inline"`
	SSHKeyAuthentication   *SSHKeyAuthentication   `queryParam:"inline"`
	PasswordAuthentication *PasswordAuthentication `queryParam:"inline"`

	Type SSHTunnelMethodType
}

func CreateSSHTunnelMethodNoTunnel(noTunnel NoTunnel) SSHTunnelMethod {
	typ := SSHTunnelMethodTypeNoTunnel

	return SSHTunnelMethod{
		NoTunnel: &noTunnel,
		Type:     typ,
	}
}

func CreateSSHTunnelMethodSSHKeyAuthentication(sshKeyAuthentication SSHKeyAuthentication) SSHTunnelMethod {
	typ := SSHTunnelMethodTypeSSHKeyAuthentication

	return SSHTunnelMethod{
		SSHKeyAuthentication: &sshKeyAuthentication,
		Type:                 typ,
	}
}

func CreateSSHTunnelMethodPasswordAuthentication(passwordAuthentication PasswordAuthentication) SSHTunnelMethod {
	typ := SSHTunnelMethodTypePasswordAuthentication

	return SSHTunnelMethod{
		PasswordAuthentication: &passwordAuthentication,
		Type:                   typ,
	}
}

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

	var noTunnel NoTunnel = NoTunnel{}
	if err := utils.UnmarshalJSON(data, &noTunnel, "", true, true); err == nil {
		u.NoTunnel = &noTunnel
		u.Type = SSHTunnelMethodTypeNoTunnel
		return nil
	}

	var sshKeyAuthentication SSHKeyAuthentication = SSHKeyAuthentication{}
	if err := utils.UnmarshalJSON(data, &sshKeyAuthentication, "", true, true); err == nil {
		u.SSHKeyAuthentication = &sshKeyAuthentication
		u.Type = SSHTunnelMethodTypeSSHKeyAuthentication
		return nil
	}

	var passwordAuthentication PasswordAuthentication = PasswordAuthentication{}
	if err := utils.UnmarshalJSON(data, &passwordAuthentication, "", true, true); err == nil {
		u.PasswordAuthentication = &passwordAuthentication
		u.Type = SSHTunnelMethodTypePasswordAuthentication
		return nil
	}

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

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

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

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

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

type Clickhouse string

const (
	ClickhouseClickhouse Clickhouse = "clickhouse"
)

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

type SourceClickhouse struct {
	// The name of the database.
	Database string `json:"database"`
	// The host endpoint of the Clickhouse cluster.
	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 '&'. (Eg. key1=value1&key2=value2&key3=value3). For more information read about <a href="https://jdbc.postgresql.org/documentation/head/connect.html">JDBC URL parameters</a>.
	JdbcURLParams *string `json:"jdbc_url_params,omitempty"`
	// The password associated with this username.
	Password *string `json:"password,omitempty"`
	// The port of the database.
	Port *int64 `default:"8123" json:"port"`
	// Encrypt data using SSL.
	Ssl *bool `default:"true" json:"ssl"`
	// Whether to initiate an SSH tunnel before connecting to the database, and if so, which kind of authentication to use.
	TunnelMethod *SSHTunnelMethod `json:"tunnel_method,omitempty"`
	// The username which is used to access the database.
	Username   string     `json:"username"`
	sourceType Clickhouse `const:"clickhouse" json:"sourceType"`
}

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

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

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

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

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

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

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

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

func (o *SourceClickhouse) GetTunnelMethod() *SSHTunnelMethod {
	if o == nil {
		return nil
	}
	return o.TunnelMethod
}

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

func (o *SourceClickhouse) GetSourceType() Clickhouse {
	return ClickhouseClickhouse
}
