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

type SourceAirtableAuthMethod string

const (
	SourceAirtableAuthMethodAPIKey SourceAirtableAuthMethod = "api_key"
)

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

type PersonalAccessToken struct {
	// The Personal Access Token for the Airtable account. See the <a href="https://airtable.com/developers/web/guides/personal-access-tokens">Support Guide</a> for more information on how to obtain this token.
	APIKey     string                    `json:"api_key"`
	authMethod *SourceAirtableAuthMethod `const:"api_key" json:"auth_method,omitempty"`
}

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

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

func (o *PersonalAccessToken) GetAPIKey() string {
	if o == nil {
		return ""
	}
	return o.APIKey
}

func (o *PersonalAccessToken) GetAuthMethod() *SourceAirtableAuthMethod {
	return SourceAirtableAuthMethodAPIKey.ToPointer()
}

type SourceAirtableSchemasAuthMethod string

const (
	SourceAirtableSchemasAuthMethodOauth20 SourceAirtableSchemasAuthMethod = "oauth2.0"
)

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

type SourceAirtableOAuth20 struct {
	// Access Token for making authenticated requests.
	AccessToken *string                          `json:"access_token,omitempty"`
	authMethod  *SourceAirtableSchemasAuthMethod `const:"oauth2.0" json:"auth_method,omitempty"`
	// The client ID of the Airtable developer application.
	ClientID string `json:"client_id"`
	// The client secret of the Airtable developer application.
	ClientSecret string `json:"client_secret"`
	// The key to refresh the expired access token.
	RefreshToken string `json:"refresh_token"`
	// The date-time when the access token should be refreshed.
	TokenExpiryDate *time.Time `json:"token_expiry_date,omitempty"`
}

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

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

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

func (o *SourceAirtableOAuth20) GetAuthMethod() *SourceAirtableSchemasAuthMethod {
	return SourceAirtableSchemasAuthMethodOauth20.ToPointer()
}

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

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

func (o *SourceAirtableOAuth20) GetRefreshToken() string {
	if o == nil {
		return ""
	}
	return o.RefreshToken
}

func (o *SourceAirtableOAuth20) GetTokenExpiryDate() *time.Time {
	if o == nil {
		return nil
	}
	return o.TokenExpiryDate
}

type AuthenticationUnionType string

const (
	AuthenticationUnionTypeSourceAirtableOAuth20 AuthenticationUnionType = "source-airtable_OAuth2.0"
	AuthenticationUnionTypePersonalAccessToken   AuthenticationUnionType = "Personal Access Token"
)

type Authentication struct {
	SourceAirtableOAuth20 *SourceAirtableOAuth20 `queryParam:"inline"`
	PersonalAccessToken   *PersonalAccessToken   `queryParam:"inline"`

	Type AuthenticationUnionType
}

func CreateAuthenticationSourceAirtableOAuth20(sourceAirtableOAuth20 SourceAirtableOAuth20) Authentication {
	typ := AuthenticationUnionTypeSourceAirtableOAuth20

	return Authentication{
		SourceAirtableOAuth20: &sourceAirtableOAuth20,
		Type:                  typ,
	}
}

func CreateAuthenticationPersonalAccessToken(personalAccessToken PersonalAccessToken) Authentication {
	typ := AuthenticationUnionTypePersonalAccessToken

	return Authentication{
		PersonalAccessToken: &personalAccessToken,
		Type:                typ,
	}
}

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

	var personalAccessToken PersonalAccessToken = PersonalAccessToken{}
	if err := utils.UnmarshalJSON(data, &personalAccessToken, "", true, true); err == nil {
		u.PersonalAccessToken = &personalAccessToken
		u.Type = AuthenticationUnionTypePersonalAccessToken
		return nil
	}

	var sourceAirtableOAuth20 SourceAirtableOAuth20 = SourceAirtableOAuth20{}
	if err := utils.UnmarshalJSON(data, &sourceAirtableOAuth20, "", true, true); err == nil {
		u.SourceAirtableOAuth20 = &sourceAirtableOAuth20
		u.Type = AuthenticationUnionTypeSourceAirtableOAuth20
		return nil
	}

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

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

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

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

type Airtable string

const (
	AirtableAirtable Airtable = "airtable"
)

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

type SourceAirtable struct {
	Credentials *Authentication `json:"credentials,omitempty"`
	sourceType  *Airtable       `const:"airtable" json:"sourceType,omitempty"`
}

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

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

func (o *SourceAirtable) GetCredentials() *Authentication {
	if o == nil {
		return nil
	}
	return o.Credentials
}

func (o *SourceAirtable) GetSourceType() *Airtable {
	return AirtableAirtable.ToPointer()
}
