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

const (
	DestinationS3DataLakeSchemasCatalogTypeRest DestinationS3DataLakeSchemasCatalogType = "REST"
)

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

// RestCatalog - Configuration details for connecting to a REST catalog.
type RestCatalog struct {
	CatalogType *DestinationS3DataLakeSchemasCatalogType `default:"REST" json:"catalog_type"`
	// The namespace to be used in the Table identifier.
	//            This will ONLY be used if the `Destination Namespace` setting for the connection is set to
	//            `Destination-defined` or `Source-defined`
	Namespace string `json:"namespace"`
	// The base URL of the Rest server used to connect to the Rest catalog.
	ServerURI            string `json:"server_uri"`
	AdditionalProperties any    `additionalProperties:"true" json:"-"`
}

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

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

func (o *RestCatalog) GetCatalogType() *DestinationS3DataLakeSchemasCatalogType {
	if o == nil {
		return nil
	}
	return o.CatalogType
}

func (o *RestCatalog) GetNamespace() string {
	if o == nil {
		return ""
	}
	return o.Namespace
}

func (o *RestCatalog) GetServerURI() string {
	if o == nil {
		return ""
	}
	return o.ServerURI
}

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

type DestinationS3DataLakeCatalogType string

const (
	DestinationS3DataLakeCatalogTypeGlue DestinationS3DataLakeCatalogType = "GLUE"
)

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

// GlueCatalog - Configuration details for connecting to an AWS Glue-based Iceberg catalog.
type GlueCatalog struct {
	CatalogType *DestinationS3DataLakeCatalogType `default:"GLUE" json:"catalog_type"`
	// The Glue database name. This will ONLY be used if the `Destination Namespace` setting for the connection is set to `Destination-defined` or `Source-defined`
	DatabaseName string `json:"database_name"`
	// The AWS Account ID associated with the Glue service used by the Iceberg catalog.
	GlueID string `json:"glue_id"`
	// The ARN of the AWS role to assume. Only usable in Airbyte Cloud.
	RoleArn              *string `json:"role_arn,omitempty"`
	AdditionalProperties any     `additionalProperties:"true" json:"-"`
}

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

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

func (o *GlueCatalog) GetCatalogType() *DestinationS3DataLakeCatalogType {
	if o == nil {
		return nil
	}
	return o.CatalogType
}

func (o *GlueCatalog) GetDatabaseName() string {
	if o == nil {
		return ""
	}
	return o.DatabaseName
}

func (o *GlueCatalog) GetGlueID() string {
	if o == nil {
		return ""
	}
	return o.GlueID
}

func (o *GlueCatalog) GetRoleArn() *string {
	if o == nil {
		return nil
	}
	return o.RoleArn
}

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

type DestinationS3DataLakeSchemasCatalogTypeCatalogType string

const (
	DestinationS3DataLakeSchemasCatalogTypeCatalogTypeNessie DestinationS3DataLakeSchemasCatalogTypeCatalogType = "NESSIE"
)

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

// NessieCatalog - Configuration details for connecting to a Nessie-based Iceberg catalog.
type NessieCatalog struct {
	// Optional token for authentication with the Nessie server.
	AccessToken *string                                             `json:"access_token,omitempty"`
	CatalogType *DestinationS3DataLakeSchemasCatalogTypeCatalogType `default:"NESSIE" json:"catalog_type"`
	// The Nessie namespace to be used in the Table identifier.
	//            This will ONLY be used if the `Destination Namespace` setting for the connection is set to
	//            `Destination-defined` or `Source-defined`
	Namespace string `json:"namespace"`
	// The base URL of the Nessie server used to connect to the Nessie catalog.
	ServerURI            string `json:"server_uri"`
	AdditionalProperties any    `additionalProperties:"true" json:"-"`
}

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

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

func (o *NessieCatalog) GetAccessToken() *string {
	if o == nil {
		return nil
	}
	return o.AccessToken
}

func (o *NessieCatalog) GetCatalogType() *DestinationS3DataLakeSchemasCatalogTypeCatalogType {
	if o == nil {
		return nil
	}
	return o.CatalogType
}

func (o *NessieCatalog) GetNamespace() string {
	if o == nil {
		return ""
	}
	return o.Namespace
}

func (o *NessieCatalog) GetServerURI() string {
	if o == nil {
		return ""
	}
	return o.ServerURI
}

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

type CatalogTypeType string

const (
	CatalogTypeTypeNessieCatalog CatalogTypeType = "Nessie Catalog"
	CatalogTypeTypeGlueCatalog   CatalogTypeType = "Glue Catalog"
	CatalogTypeTypeRestCatalog   CatalogTypeType = "Rest Catalog"
)

// CatalogType - Specifies the type of Iceberg catalog (e.g., NESSIE, GLUE, REST) and its associated configuration.
type CatalogType struct {
	NessieCatalog *NessieCatalog `queryParam:"inline"`
	GlueCatalog   *GlueCatalog   `queryParam:"inline"`
	RestCatalog   *RestCatalog   `queryParam:"inline"`

	Type CatalogTypeType
}

func CreateCatalogTypeNessieCatalog(nessieCatalog NessieCatalog) CatalogType {
	typ := CatalogTypeTypeNessieCatalog

	return CatalogType{
		NessieCatalog: &nessieCatalog,
		Type:          typ,
	}
}

func CreateCatalogTypeGlueCatalog(glueCatalog GlueCatalog) CatalogType {
	typ := CatalogTypeTypeGlueCatalog

	return CatalogType{
		GlueCatalog: &glueCatalog,
		Type:        typ,
	}
}

func CreateCatalogTypeRestCatalog(restCatalog RestCatalog) CatalogType {
	typ := CatalogTypeTypeRestCatalog

	return CatalogType{
		RestCatalog: &restCatalog,
		Type:        typ,
	}
}

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

	var restCatalog RestCatalog = RestCatalog{}
	if err := utils.UnmarshalJSON(data, &restCatalog, "", true, true); err == nil {
		u.RestCatalog = &restCatalog
		u.Type = CatalogTypeTypeRestCatalog
		return nil
	}

	var nessieCatalog NessieCatalog = NessieCatalog{}
	if err := utils.UnmarshalJSON(data, &nessieCatalog, "", true, true); err == nil {
		u.NessieCatalog = &nessieCatalog
		u.Type = CatalogTypeTypeNessieCatalog
		return nil
	}

	var glueCatalog GlueCatalog = GlueCatalog{}
	if err := utils.UnmarshalJSON(data, &glueCatalog, "", true, true); err == nil {
		u.GlueCatalog = &glueCatalog
		u.Type = CatalogTypeTypeGlueCatalog
		return nil
	}

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

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

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

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

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

// DestinationS3DataLakeS3BucketRegion - The region of the S3 bucket. See <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions">here</a> for all region codes.
type DestinationS3DataLakeS3BucketRegion string

const (
	DestinationS3DataLakeS3BucketRegionUnknown      DestinationS3DataLakeS3BucketRegion = ""
	DestinationS3DataLakeS3BucketRegionAfSouth1     DestinationS3DataLakeS3BucketRegion = "af-south-1"
	DestinationS3DataLakeS3BucketRegionApEast1      DestinationS3DataLakeS3BucketRegion = "ap-east-1"
	DestinationS3DataLakeS3BucketRegionApNortheast1 DestinationS3DataLakeS3BucketRegion = "ap-northeast-1"
	DestinationS3DataLakeS3BucketRegionApNortheast2 DestinationS3DataLakeS3BucketRegion = "ap-northeast-2"
	DestinationS3DataLakeS3BucketRegionApNortheast3 DestinationS3DataLakeS3BucketRegion = "ap-northeast-3"
	DestinationS3DataLakeS3BucketRegionApSouth1     DestinationS3DataLakeS3BucketRegion = "ap-south-1"
	DestinationS3DataLakeS3BucketRegionApSouth2     DestinationS3DataLakeS3BucketRegion = "ap-south-2"
	DestinationS3DataLakeS3BucketRegionApSoutheast1 DestinationS3DataLakeS3BucketRegion = "ap-southeast-1"
	DestinationS3DataLakeS3BucketRegionApSoutheast2 DestinationS3DataLakeS3BucketRegion = "ap-southeast-2"
	DestinationS3DataLakeS3BucketRegionApSoutheast3 DestinationS3DataLakeS3BucketRegion = "ap-southeast-3"
	DestinationS3DataLakeS3BucketRegionApSoutheast4 DestinationS3DataLakeS3BucketRegion = "ap-southeast-4"
	DestinationS3DataLakeS3BucketRegionCaCentral1   DestinationS3DataLakeS3BucketRegion = "ca-central-1"
	DestinationS3DataLakeS3BucketRegionCaWest1      DestinationS3DataLakeS3BucketRegion = "ca-west-1"
	DestinationS3DataLakeS3BucketRegionCnNorth1     DestinationS3DataLakeS3BucketRegion = "cn-north-1"
	DestinationS3DataLakeS3BucketRegionCnNorthwest1 DestinationS3DataLakeS3BucketRegion = "cn-northwest-1"
	DestinationS3DataLakeS3BucketRegionEuCentral1   DestinationS3DataLakeS3BucketRegion = "eu-central-1"
	DestinationS3DataLakeS3BucketRegionEuCentral2   DestinationS3DataLakeS3BucketRegion = "eu-central-2"
	DestinationS3DataLakeS3BucketRegionEuNorth1     DestinationS3DataLakeS3BucketRegion = "eu-north-1"
	DestinationS3DataLakeS3BucketRegionEuSouth1     DestinationS3DataLakeS3BucketRegion = "eu-south-1"
	DestinationS3DataLakeS3BucketRegionEuSouth2     DestinationS3DataLakeS3BucketRegion = "eu-south-2"
	DestinationS3DataLakeS3BucketRegionEuWest1      DestinationS3DataLakeS3BucketRegion = "eu-west-1"
	DestinationS3DataLakeS3BucketRegionEuWest2      DestinationS3DataLakeS3BucketRegion = "eu-west-2"
	DestinationS3DataLakeS3BucketRegionEuWest3      DestinationS3DataLakeS3BucketRegion = "eu-west-3"
	DestinationS3DataLakeS3BucketRegionIlCentral1   DestinationS3DataLakeS3BucketRegion = "il-central-1"
	DestinationS3DataLakeS3BucketRegionMeCentral1   DestinationS3DataLakeS3BucketRegion = "me-central-1"
	DestinationS3DataLakeS3BucketRegionMeSouth1     DestinationS3DataLakeS3BucketRegion = "me-south-1"
	DestinationS3DataLakeS3BucketRegionSaEast1      DestinationS3DataLakeS3BucketRegion = "sa-east-1"
	DestinationS3DataLakeS3BucketRegionUsEast1      DestinationS3DataLakeS3BucketRegion = "us-east-1"
	DestinationS3DataLakeS3BucketRegionUsEast2      DestinationS3DataLakeS3BucketRegion = "us-east-2"
	DestinationS3DataLakeS3BucketRegionUsGovEast1   DestinationS3DataLakeS3BucketRegion = "us-gov-east-1"
	DestinationS3DataLakeS3BucketRegionUsGovWest1   DestinationS3DataLakeS3BucketRegion = "us-gov-west-1"
	DestinationS3DataLakeS3BucketRegionUsWest1      DestinationS3DataLakeS3BucketRegion = "us-west-1"
	DestinationS3DataLakeS3BucketRegionUsWest2      DestinationS3DataLakeS3BucketRegion = "us-west-2"
)

func (e DestinationS3DataLakeS3BucketRegion) ToPointer() *DestinationS3DataLakeS3BucketRegion {
	return &e
}
func (e *DestinationS3DataLakeS3BucketRegion) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	switch v {
	case "":
		fallthrough
	case "af-south-1":
		fallthrough
	case "ap-east-1":
		fallthrough
	case "ap-northeast-1":
		fallthrough
	case "ap-northeast-2":
		fallthrough
	case "ap-northeast-3":
		fallthrough
	case "ap-south-1":
		fallthrough
	case "ap-south-2":
		fallthrough
	case "ap-southeast-1":
		fallthrough
	case "ap-southeast-2":
		fallthrough
	case "ap-southeast-3":
		fallthrough
	case "ap-southeast-4":
		fallthrough
	case "ca-central-1":
		fallthrough
	case "ca-west-1":
		fallthrough
	case "cn-north-1":
		fallthrough
	case "cn-northwest-1":
		fallthrough
	case "eu-central-1":
		fallthrough
	case "eu-central-2":
		fallthrough
	case "eu-north-1":
		fallthrough
	case "eu-south-1":
		fallthrough
	case "eu-south-2":
		fallthrough
	case "eu-west-1":
		fallthrough
	case "eu-west-2":
		fallthrough
	case "eu-west-3":
		fallthrough
	case "il-central-1":
		fallthrough
	case "me-central-1":
		fallthrough
	case "me-south-1":
		fallthrough
	case "sa-east-1":
		fallthrough
	case "us-east-1":
		fallthrough
	case "us-east-2":
		fallthrough
	case "us-gov-east-1":
		fallthrough
	case "us-gov-west-1":
		fallthrough
	case "us-west-1":
		fallthrough
	case "us-west-2":
		*e = DestinationS3DataLakeS3BucketRegion(v)
		return nil
	default:
		return fmt.Errorf("invalid value for DestinationS3DataLakeS3BucketRegion: %v", v)
	}
}

type S3DataLake string

const (
	S3DataLakeS3DataLake S3DataLake = "s3-data-lake"
)

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

// DestinationS3DataLake - Defines the configurations required to connect to an Iceberg catalog, including warehouse location, main branch name, and catalog type specifics.
type DestinationS3DataLake struct {
	// The AWS Access Key ID with permissions for S3 and Glue operations.
	AccessKeyID *string `json:"access_key_id,omitempty"`
	// Specifies the type of Iceberg catalog (e.g., NESSIE, GLUE, REST) and its associated configuration.
	CatalogType CatalogType `json:"catalog_type"`
	// The primary or default branch name in the catalog. Most query engines will use "main" by default. See <a href="https://iceberg.apache.org/docs/latest/branching/">Iceberg documentation</a> for more information.
	MainBranchName *string `default:"main" json:"main_branch_name"`
	// The name of the S3 bucket that will host the Iceberg data.
	S3BucketName string `json:"s3_bucket_name"`
	// The region of the S3 bucket. See <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions">here</a> for all region codes.
	S3BucketRegion DestinationS3DataLakeS3BucketRegion `json:"s3_bucket_region"`
	// Your S3 endpoint url. Read more <a href="https://docs.aws.amazon.com/general/latest/gr/s3.html#:~:text=Service%20endpoints-,Amazon%20S3%20endpoints,-When%20you%20use">here</a>
	S3Endpoint *string `json:"s3_endpoint,omitempty"`
	// The AWS Secret Access Key paired with the Access Key ID for AWS authentication.
	SecretAccessKey *string `json:"secret_access_key,omitempty"`
	// The root location of the data warehouse used by the Iceberg catalog. Typically includes a bucket name and path within that bucket. For AWS Glue and Nessie, must include the storage protocol (such as "s3://" for Amazon S3).
	WarehouseLocation string     `json:"warehouse_location"`
	destinationType   S3DataLake `const:"s3-data-lake" json:"destinationType"`
}

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

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

func (o *DestinationS3DataLake) GetAccessKeyID() *string {
	if o == nil {
		return nil
	}
	return o.AccessKeyID
}

func (o *DestinationS3DataLake) GetCatalogType() CatalogType {
	if o == nil {
		return CatalogType{}
	}
	return o.CatalogType
}

func (o *DestinationS3DataLake) GetMainBranchName() *string {
	if o == nil {
		return nil
	}
	return o.MainBranchName
}

func (o *DestinationS3DataLake) GetS3BucketName() string {
	if o == nil {
		return ""
	}
	return o.S3BucketName
}

func (o *DestinationS3DataLake) GetS3BucketRegion() DestinationS3DataLakeS3BucketRegion {
	if o == nil {
		return DestinationS3DataLakeS3BucketRegion("")
	}
	return o.S3BucketRegion
}

func (o *DestinationS3DataLake) GetS3Endpoint() *string {
	if o == nil {
		return nil
	}
	return o.S3Endpoint
}

func (o *DestinationS3DataLake) GetSecretAccessKey() *string {
	if o == nil {
		return nil
	}
	return o.SecretAccessKey
}

func (o *DestinationS3DataLake) GetWarehouseLocation() string {
	if o == nil {
		return ""
	}
	return o.WarehouseLocation
}

func (o *DestinationS3DataLake) GetDestinationType() S3DataLake {
	return S3DataLakeS3DataLake
}
