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

const (
	DestinationMssqlLoadTypeBulk DestinationMssqlLoadType = "BULK"
)

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

// BulkLoad - Configuration details for using the BULK loading mechanism.
type BulkLoad struct {
	// The Azure blob storage account key. Mutually exclusive with a Shared Access Signature
	AzureBlobStorageAccountKey *string `json:"azure_blob_storage_account_key,omitempty"`
	// The name of the Azure Blob Storage account. See: https://learn.microsoft.com/azure/storage/blobs/storage-blobs-introduction#storage-accounts
	AzureBlobStorageAccountName string `json:"azure_blob_storage_account_name"`
	// The name of the Azure Blob Storage container. See: https://learn.microsoft.com/azure/storage/blobs/storage-blobs-introduction#containers
	AzureBlobStorageContainerName string `json:"azure_blob_storage_container_name"`
	// Specifies the external data source name configured in MSSQL, which references the Azure Blob container. See: https://learn.microsoft.com/sql/t-sql/statements/bulk-insert-transact-sql
	BulkLoadDataSource string `json:"bulk_load_data_source"`
	// When enabled, Airbyte will validate all values before loading them into the destination table. This provides stronger data integrity guarantees but may significantly impact performance.
	BulkLoadValidateValuesPreLoad *bool                     `default:"false" json:"bulk_load_validate_values_pre_load"`
	LoadType                      *DestinationMssqlLoadType `default:"BULK" json:"load_type"`
	// A shared access signature (SAS) provides secure delegated access to resources in your storage account. See: https://learn.microsoft.com/azure/storage/common/storage-sas-overview.Mutually exclusive with an account key
	SharedAccessSignature *string `json:"shared_access_signature,omitempty"`
	AdditionalProperties  any     `additionalProperties:"true" json:"-"`
}

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

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

func (o *BulkLoad) GetAzureBlobStorageAccountKey() *string {
	if o == nil {
		return nil
	}
	return o.AzureBlobStorageAccountKey
}

func (o *BulkLoad) GetAzureBlobStorageAccountName() string {
	if o == nil {
		return ""
	}
	return o.AzureBlobStorageAccountName
}

func (o *BulkLoad) GetAzureBlobStorageContainerName() string {
	if o == nil {
		return ""
	}
	return o.AzureBlobStorageContainerName
}

func (o *BulkLoad) GetBulkLoadDataSource() string {
	if o == nil {
		return ""
	}
	return o.BulkLoadDataSource
}

func (o *BulkLoad) GetBulkLoadValidateValuesPreLoad() *bool {
	if o == nil {
		return nil
	}
	return o.BulkLoadValidateValuesPreLoad
}

func (o *BulkLoad) GetLoadType() *DestinationMssqlLoadType {
	if o == nil {
		return nil
	}
	return o.LoadType
}

func (o *BulkLoad) GetSharedAccessSignature() *string {
	if o == nil {
		return nil
	}
	return o.SharedAccessSignature
}

func (o *BulkLoad) GetAdditionalProperties() any {
	if o == nil {
		return nil
	}
	return o.AdditionalProperties
}

type DestinationMssqlSchemasLoadType string

const (
	DestinationMssqlSchemasLoadTypeInsert DestinationMssqlSchemasLoadType = "INSERT"
)

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

// InsertLoad - Configuration details for using the INSERT loading mechanism.
type InsertLoad struct {
	LoadType             *DestinationMssqlSchemasLoadType `default:"INSERT" json:"load_type"`
	AdditionalProperties any                              `additionalProperties:"true" json:"-"`
}

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

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

func (o *InsertLoad) GetLoadType() *DestinationMssqlSchemasLoadType {
	if o == nil {
		return nil
	}
	return o.LoadType
}

func (o *InsertLoad) GetAdditionalProperties() any {
	if o == nil {
		return nil
	}
	return o.AdditionalProperties
}

type LoadTypeType string

const (
	LoadTypeTypeInsertLoad LoadTypeType = "Insert Load"
	LoadTypeTypeBulkLoad   LoadTypeType = "Bulk Load"
)

// LoadType - Specifies the type of load mechanism (e.g., BULK, INSERT) and its associated configuration.
type LoadType struct {
	InsertLoad *InsertLoad `queryParam:"inline"`
	BulkLoad   *BulkLoad   `queryParam:"inline"`

	Type LoadTypeType
}

func CreateLoadTypeInsertLoad(insertLoad InsertLoad) LoadType {
	typ := LoadTypeTypeInsertLoad

	return LoadType{
		InsertLoad: &insertLoad,
		Type:       typ,
	}
}

func CreateLoadTypeBulkLoad(bulkLoad BulkLoad) LoadType {
	typ := LoadTypeTypeBulkLoad

	return LoadType{
		BulkLoad: &bulkLoad,
		Type:     typ,
	}
}

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

	var insertLoad InsertLoad = InsertLoad{}
	if err := utils.UnmarshalJSON(data, &insertLoad, "", true, true); err == nil {
		u.InsertLoad = &insertLoad
		u.Type = LoadTypeTypeInsertLoad
		return nil
	}

	var bulkLoad BulkLoad = BulkLoad{}
	if err := utils.UnmarshalJSON(data, &bulkLoad, "", true, true); err == nil {
		u.BulkLoad = &bulkLoad
		u.Type = LoadTypeTypeBulkLoad
		return nil
	}

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

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

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

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

type DestinationMssqlSchemasName string

const (
	DestinationMssqlSchemasNameEncryptedVerifyCertificate DestinationMssqlSchemasName = "encrypted_verify_certificate"
)

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

// DestinationMssqlEncryptedVerifyCertificate - Verify and use the certificate provided by the server.
type DestinationMssqlEncryptedVerifyCertificate struct {
	// Specifies the host name of the server. The value of this property must match the subject property of the certificate.
	HostNameInCertificate *string                      `json:"hostNameInCertificate,omitempty"`
	Name                  *DestinationMssqlSchemasName `default:"encrypted_verify_certificate" json:"name"`
	// Specifies the name of the trust store.
	TrustStoreName *string `json:"trustStoreName,omitempty"`
	// Specifies the password of the trust store.
	TrustStorePassword   *string `json:"trustStorePassword,omitempty"`
	AdditionalProperties any     `additionalProperties:"true" json:"-"`
}

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

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

func (o *DestinationMssqlEncryptedVerifyCertificate) GetHostNameInCertificate() *string {
	if o == nil {
		return nil
	}
	return o.HostNameInCertificate
}

func (o *DestinationMssqlEncryptedVerifyCertificate) GetName() *DestinationMssqlSchemasName {
	if o == nil {
		return nil
	}
	return o.Name
}

func (o *DestinationMssqlEncryptedVerifyCertificate) GetTrustStoreName() *string {
	if o == nil {
		return nil
	}
	return o.TrustStoreName
}

func (o *DestinationMssqlEncryptedVerifyCertificate) GetTrustStorePassword() *string {
	if o == nil {
		return nil
	}
	return o.TrustStorePassword
}

func (o *DestinationMssqlEncryptedVerifyCertificate) GetAdditionalProperties() any {
	if o == nil {
		return nil
	}
	return o.AdditionalProperties
}

type DestinationMssqlName string

const (
	DestinationMssqlNameEncryptedTrustServerCertificate DestinationMssqlName = "encrypted_trust_server_certificate"
)

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

// DestinationMssqlEncryptedTrustServerCertificate - Use the certificate provided by the server without verification. (For testing purposes only!)
type DestinationMssqlEncryptedTrustServerCertificate struct {
	Name                 *DestinationMssqlName `default:"encrypted_trust_server_certificate" json:"name"`
	AdditionalProperties any                   `additionalProperties:"true" json:"-"`
}

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

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

func (o *DestinationMssqlEncryptedTrustServerCertificate) GetName() *DestinationMssqlName {
	if o == nil {
		return nil
	}
	return o.Name
}

func (o *DestinationMssqlEncryptedTrustServerCertificate) GetAdditionalProperties() any {
	if o == nil {
		return nil
	}
	return o.AdditionalProperties
}

type Name string

const (
	NameUnencrypted Name = "unencrypted"
)

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

// DestinationMssqlUnencrypted - The data transfer will not be encrypted.
type DestinationMssqlUnencrypted struct {
	Name                 *Name `default:"unencrypted" json:"name"`
	AdditionalProperties any   `additionalProperties:"true" json:"-"`
}

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

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

func (o *DestinationMssqlUnencrypted) GetName() *Name {
	if o == nil {
		return nil
	}
	return o.Name
}

func (o *DestinationMssqlUnencrypted) GetAdditionalProperties() any {
	if o == nil {
		return nil
	}
	return o.AdditionalProperties
}

type DestinationMssqlSSLMethodType string

const (
	DestinationMssqlSSLMethodTypeDestinationMssqlUnencrypted                     DestinationMssqlSSLMethodType = "destination-mssql_Unencrypted"
	DestinationMssqlSSLMethodTypeDestinationMssqlEncryptedTrustServerCertificate DestinationMssqlSSLMethodType = "destination-mssql_Encrypted (trust server certificate)"
	DestinationMssqlSSLMethodTypeDestinationMssqlEncryptedVerifyCertificate      DestinationMssqlSSLMethodType = "destination-mssql_Encrypted (verify certificate)"
)

// DestinationMssqlSSLMethod - The encryption method which is used to communicate with the database.
type DestinationMssqlSSLMethod struct {
	DestinationMssqlUnencrypted                     *DestinationMssqlUnencrypted                     `queryParam:"inline"`
	DestinationMssqlEncryptedTrustServerCertificate *DestinationMssqlEncryptedTrustServerCertificate `queryParam:"inline"`
	DestinationMssqlEncryptedVerifyCertificate      *DestinationMssqlEncryptedVerifyCertificate      `queryParam:"inline"`

	Type DestinationMssqlSSLMethodType
}

func CreateDestinationMssqlSSLMethodDestinationMssqlUnencrypted(destinationMssqlUnencrypted DestinationMssqlUnencrypted) DestinationMssqlSSLMethod {
	typ := DestinationMssqlSSLMethodTypeDestinationMssqlUnencrypted

	return DestinationMssqlSSLMethod{
		DestinationMssqlUnencrypted: &destinationMssqlUnencrypted,
		Type:                        typ,
	}
}

func CreateDestinationMssqlSSLMethodDestinationMssqlEncryptedTrustServerCertificate(destinationMssqlEncryptedTrustServerCertificate DestinationMssqlEncryptedTrustServerCertificate) DestinationMssqlSSLMethod {
	typ := DestinationMssqlSSLMethodTypeDestinationMssqlEncryptedTrustServerCertificate

	return DestinationMssqlSSLMethod{
		DestinationMssqlEncryptedTrustServerCertificate: &destinationMssqlEncryptedTrustServerCertificate,
		Type: typ,
	}
}

func CreateDestinationMssqlSSLMethodDestinationMssqlEncryptedVerifyCertificate(destinationMssqlEncryptedVerifyCertificate DestinationMssqlEncryptedVerifyCertificate) DestinationMssqlSSLMethod {
	typ := DestinationMssqlSSLMethodTypeDestinationMssqlEncryptedVerifyCertificate

	return DestinationMssqlSSLMethod{
		DestinationMssqlEncryptedVerifyCertificate: &destinationMssqlEncryptedVerifyCertificate,
		Type: typ,
	}
}

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

	var destinationMssqlUnencrypted DestinationMssqlUnencrypted = DestinationMssqlUnencrypted{}
	if err := utils.UnmarshalJSON(data, &destinationMssqlUnencrypted, "", true, true); err == nil {
		u.DestinationMssqlUnencrypted = &destinationMssqlUnencrypted
		u.Type = DestinationMssqlSSLMethodTypeDestinationMssqlUnencrypted
		return nil
	}

	var destinationMssqlEncryptedTrustServerCertificate DestinationMssqlEncryptedTrustServerCertificate = DestinationMssqlEncryptedTrustServerCertificate{}
	if err := utils.UnmarshalJSON(data, &destinationMssqlEncryptedTrustServerCertificate, "", true, true); err == nil {
		u.DestinationMssqlEncryptedTrustServerCertificate = &destinationMssqlEncryptedTrustServerCertificate
		u.Type = DestinationMssqlSSLMethodTypeDestinationMssqlEncryptedTrustServerCertificate
		return nil
	}

	var destinationMssqlEncryptedVerifyCertificate DestinationMssqlEncryptedVerifyCertificate = DestinationMssqlEncryptedVerifyCertificate{}
	if err := utils.UnmarshalJSON(data, &destinationMssqlEncryptedVerifyCertificate, "", true, true); err == nil {
		u.DestinationMssqlEncryptedVerifyCertificate = &destinationMssqlEncryptedVerifyCertificate
		u.Type = DestinationMssqlSSLMethodTypeDestinationMssqlEncryptedVerifyCertificate
		return nil
	}

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

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

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

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

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

type DestinationMssqlMssql string

const (
	DestinationMssqlMssqlMssql DestinationMssqlMssql = "mssql"
)

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

type DestinationMssql struct {
	// The name of the MSSQL database.
	Database string `json:"database"`
	// The host name of the MSSQL 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"`
	// Specifies the type of load mechanism (e.g., BULK, INSERT) and its associated configuration.
	LoadType LoadType `json:"load_type"`
	// The password associated with this username.
	Password *string `json:"password,omitempty"`
	// The port of the MSSQL database.
	Port int64 `json:"port"`
	// 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"`
	// The encryption method which is used to communicate with the database.
	SslMethod DestinationMssqlSSLMethod `json:"ssl_method"`
	// The username which is used to access the database.
	User            string                `json:"user"`
	destinationType DestinationMssqlMssql `const:"mssql" json:"destinationType"`
}

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

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

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

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

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

func (o *DestinationMssql) GetLoadType() LoadType {
	if o == nil {
		return LoadType{}
	}
	return o.LoadType
}

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

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

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

func (o *DestinationMssql) GetSslMethod() DestinationMssqlSSLMethod {
	if o == nil {
		return DestinationMssqlSSLMethod{}
	}
	return o.SslMethod
}

func (o *DestinationMssql) GetUser() string {
	if o == nil {
		return ""
	}
	return o.User
}

func (o *DestinationMssql) GetDestinationType() DestinationMssqlMssql {
	return DestinationMssqlMssqlMssql
}
