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

const (
	SourceElasticsearchSchemasMethodBasic SourceElasticsearchSchemasMethod = "basic"
)

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

// UsernamePassword - Basic auth header with a username and password
type UsernamePassword struct {
	method SourceElasticsearchSchemasMethod `const:"basic" json:"method"`
	// Basic auth password to access a secure Elasticsearch server
	Password string `json:"password"`
	// Basic auth username to access a secure Elasticsearch server
	Username             string `json:"username"`
	AdditionalProperties any    `additionalProperties:"true" json:"-"`
}

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

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

func (o *UsernamePassword) GetMethod() SourceElasticsearchSchemasMethod {
	return SourceElasticsearchSchemasMethodBasic
}

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

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

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

type SourceElasticsearchMethod string

const (
	SourceElasticsearchMethodSecret SourceElasticsearchMethod = "secret"
)

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

// APIKeySecret - Use a api key and secret combination to authenticate
type APIKeySecret struct {
	// The Key ID to used when accessing an enterprise Elasticsearch instance.
	APIKeyID string `json:"apiKeyId"`
	// The secret associated with the API Key ID.
	APIKeySecret         string                    `json:"apiKeySecret"`
	method               SourceElasticsearchMethod `const:"secret" json:"method"`
	AdditionalProperties any                       `additionalProperties:"true" json:"-"`
}

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

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

func (o *APIKeySecret) GetAPIKeyID() string {
	if o == nil {
		return ""
	}
	return o.APIKeyID
}

func (o *APIKeySecret) GetAPIKeySecret() string {
	if o == nil {
		return ""
	}
	return o.APIKeySecret
}

func (o *APIKeySecret) GetMethod() SourceElasticsearchMethod {
	return SourceElasticsearchMethodSecret
}

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

type Method string

const (
	MethodNone Method = "none"
)

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

// None - No authentication will be used
type None struct {
	method               Method `const:"none" json:"method"`
	AdditionalProperties any    `additionalProperties:"true" json:"-"`
}

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

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

func (o *None) GetMethod() Method {
	return MethodNone
}

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

type SourceElasticsearchAuthenticationMethodType string

const (
	SourceElasticsearchAuthenticationMethodTypeNone             SourceElasticsearchAuthenticationMethodType = "None"
	SourceElasticsearchAuthenticationMethodTypeAPIKeySecret     SourceElasticsearchAuthenticationMethodType = "Api Key/Secret"
	SourceElasticsearchAuthenticationMethodTypeUsernamePassword SourceElasticsearchAuthenticationMethodType = "Username/Password"
)

// SourceElasticsearchAuthenticationMethod - The type of authentication to be used
type SourceElasticsearchAuthenticationMethod struct {
	None             *None             `queryParam:"inline"`
	APIKeySecret     *APIKeySecret     `queryParam:"inline"`
	UsernamePassword *UsernamePassword `queryParam:"inline"`

	Type SourceElasticsearchAuthenticationMethodType
}

func CreateSourceElasticsearchAuthenticationMethodNone(none None) SourceElasticsearchAuthenticationMethod {
	typ := SourceElasticsearchAuthenticationMethodTypeNone

	return SourceElasticsearchAuthenticationMethod{
		None: &none,
		Type: typ,
	}
}

func CreateSourceElasticsearchAuthenticationMethodAPIKeySecret(apiKeySecret APIKeySecret) SourceElasticsearchAuthenticationMethod {
	typ := SourceElasticsearchAuthenticationMethodTypeAPIKeySecret

	return SourceElasticsearchAuthenticationMethod{
		APIKeySecret: &apiKeySecret,
		Type:         typ,
	}
}

func CreateSourceElasticsearchAuthenticationMethodUsernamePassword(usernamePassword UsernamePassword) SourceElasticsearchAuthenticationMethod {
	typ := SourceElasticsearchAuthenticationMethodTypeUsernamePassword

	return SourceElasticsearchAuthenticationMethod{
		UsernamePassword: &usernamePassword,
		Type:             typ,
	}
}

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

	var none None = None{}
	if err := utils.UnmarshalJSON(data, &none, "", true, true); err == nil {
		u.None = &none
		u.Type = SourceElasticsearchAuthenticationMethodTypeNone
		return nil
	}

	var apiKeySecret APIKeySecret = APIKeySecret{}
	if err := utils.UnmarshalJSON(data, &apiKeySecret, "", true, true); err == nil {
		u.APIKeySecret = &apiKeySecret
		u.Type = SourceElasticsearchAuthenticationMethodTypeAPIKeySecret
		return nil
	}

	var usernamePassword UsernamePassword = UsernamePassword{}
	if err := utils.UnmarshalJSON(data, &usernamePassword, "", true, true); err == nil {
		u.UsernamePassword = &usernamePassword
		u.Type = SourceElasticsearchAuthenticationMethodTypeUsernamePassword
		return nil
	}

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

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

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

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

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

type Elasticsearch string

const (
	ElasticsearchElasticsearch Elasticsearch = "elasticsearch"
)

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

type SourceElasticsearch struct {
	// The type of authentication to be used
	AuthenticationMethod *SourceElasticsearchAuthenticationMethod `json:"authenticationMethod,omitempty"`
	// The full url of the Elasticsearch server
	Endpoint   string        `json:"endpoint"`
	sourceType Elasticsearch `const:"elasticsearch" json:"sourceType"`
}

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

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

func (o *SourceElasticsearch) GetAuthenticationMethod() *SourceElasticsearchAuthenticationMethod {
	if o == nil {
		return nil
	}
	return o.AuthenticationMethod
}

func (o *SourceElasticsearch) GetEndpoint() string {
	if o == nil {
		return ""
	}
	return o.Endpoint
}

func (o *SourceElasticsearch) GetSourceType() Elasticsearch {
	return ElasticsearchElasticsearch
}
