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

const (
	DestinationFireboltSchemasMethodS3 DestinationFireboltSchemasMethod = "S3"
)

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

type ExternalTableViaS3 struct {
	// AWS access key granting read and write access to S3.
	AwsKeyID string `json:"aws_key_id"`
	// Corresponding secret part of the AWS Key
	AwsKeySecret string                           `json:"aws_key_secret"`
	method       DestinationFireboltSchemasMethod `const:"S3" json:"method"`
	// The name of the S3 bucket.
	S3Bucket string `json:"s3_bucket"`
	// Region name of the S3 bucket.
	S3Region string `json:"s3_region"`
}

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

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

func (o *ExternalTableViaS3) GetAwsKeyID() string {
	if o == nil {
		return ""
	}
	return o.AwsKeyID
}

func (o *ExternalTableViaS3) GetAwsKeySecret() string {
	if o == nil {
		return ""
	}
	return o.AwsKeySecret
}

func (o *ExternalTableViaS3) GetMethod() DestinationFireboltSchemasMethod {
	return DestinationFireboltSchemasMethodS3
}

func (o *ExternalTableViaS3) GetS3Bucket() string {
	if o == nil {
		return ""
	}
	return o.S3Bucket
}

func (o *ExternalTableViaS3) GetS3Region() string {
	if o == nil {
		return ""
	}
	return o.S3Region
}

type DestinationFireboltMethod string

const (
	DestinationFireboltMethodSQL DestinationFireboltMethod = "SQL"
)

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

type SQLInserts struct {
	method DestinationFireboltMethod `const:"SQL" json:"method"`
}

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

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

func (o *SQLInserts) GetMethod() DestinationFireboltMethod {
	return DestinationFireboltMethodSQL
}

type DestinationFireboltLoadingMethodType string

const (
	DestinationFireboltLoadingMethodTypeSQLInserts         DestinationFireboltLoadingMethodType = "SQL Inserts"
	DestinationFireboltLoadingMethodTypeExternalTableViaS3 DestinationFireboltLoadingMethodType = "External Table via S3"
)

// DestinationFireboltLoadingMethod - Loading method used to select the way data will be uploaded to Firebolt
type DestinationFireboltLoadingMethod struct {
	SQLInserts         *SQLInserts         `queryParam:"inline"`
	ExternalTableViaS3 *ExternalTableViaS3 `queryParam:"inline"`

	Type DestinationFireboltLoadingMethodType
}

func CreateDestinationFireboltLoadingMethodSQLInserts(sqlInserts SQLInserts) DestinationFireboltLoadingMethod {
	typ := DestinationFireboltLoadingMethodTypeSQLInserts

	return DestinationFireboltLoadingMethod{
		SQLInserts: &sqlInserts,
		Type:       typ,
	}
}

func CreateDestinationFireboltLoadingMethodExternalTableViaS3(externalTableViaS3 ExternalTableViaS3) DestinationFireboltLoadingMethod {
	typ := DestinationFireboltLoadingMethodTypeExternalTableViaS3

	return DestinationFireboltLoadingMethod{
		ExternalTableViaS3: &externalTableViaS3,
		Type:               typ,
	}
}

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

	var sqlInserts SQLInserts = SQLInserts{}
	if err := utils.UnmarshalJSON(data, &sqlInserts, "", true, true); err == nil {
		u.SQLInserts = &sqlInserts
		u.Type = DestinationFireboltLoadingMethodTypeSQLInserts
		return nil
	}

	var externalTableViaS3 ExternalTableViaS3 = ExternalTableViaS3{}
	if err := utils.UnmarshalJSON(data, &externalTableViaS3, "", true, true); err == nil {
		u.ExternalTableViaS3 = &externalTableViaS3
		u.Type = DestinationFireboltLoadingMethodTypeExternalTableViaS3
		return nil
	}

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

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

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

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

type DestinationFireboltFirebolt string

const (
	DestinationFireboltFireboltFirebolt DestinationFireboltFirebolt = "firebolt"
)

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

type DestinationFirebolt struct {
	// Firebolt account to login.
	Account string `json:"account"`
	// Firebolt service account ID.
	ClientID string `json:"client_id"`
	// Firebolt secret, corresponding to the service account ID.
	ClientSecret string `json:"client_secret"`
	// The database to connect to.
	Database string `json:"database"`
	// Engine name to connect to.
	Engine string `json:"engine"`
	// The host name of your Firebolt database.
	Host *string `json:"host,omitempty"`
	// Loading method used to select the way data will be uploaded to Firebolt
	LoadingMethod   *DestinationFireboltLoadingMethod `json:"loading_method,omitempty"`
	destinationType DestinationFireboltFirebolt       `const:"firebolt" json:"destinationType"`
}

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

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

func (o *DestinationFirebolt) GetAccount() string {
	if o == nil {
		return ""
	}
	return o.Account
}

func (o *DestinationFirebolt) GetClientID() string {
	if o == nil {
		return ""
	}
	return o.ClientID
}

func (o *DestinationFirebolt) GetClientSecret() string {
	if o == nil {
		return ""
	}
	return o.ClientSecret
}

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

func (o *DestinationFirebolt) GetEngine() string {
	if o == nil {
		return ""
	}
	return o.Engine
}

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

func (o *DestinationFirebolt) GetLoadingMethod() *DestinationFireboltLoadingMethod {
	if o == nil {
		return nil
	}
	return o.LoadingMethod
}

func (o *DestinationFirebolt) GetDestinationType() DestinationFireboltFirebolt {
	return DestinationFireboltFireboltFirebolt
}
