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

const (
	SourceHarvestSchemasAuthTypeToken SourceHarvestSchemasAuthType = "Token"
)

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

type SourceHarvestAuthenticateWithPersonalAccessToken struct {
	// Log into Harvest and then create new <a href="https://id.getharvest.com/developers"> personal access token</a>.
	APIToken             string                        `json:"api_token"`
	authType             *SourceHarvestSchemasAuthType `const:"Token" json:"auth_type,omitempty"`
	AdditionalProperties any                           `additionalProperties:"true" json:"-"`
}

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

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

func (o *SourceHarvestAuthenticateWithPersonalAccessToken) GetAPIToken() string {
	if o == nil {
		return ""
	}
	return o.APIToken
}

func (o *SourceHarvestAuthenticateWithPersonalAccessToken) GetAuthType() *SourceHarvestSchemasAuthType {
	return SourceHarvestSchemasAuthTypeToken.ToPointer()
}

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

type SourceHarvestAuthType string

const (
	SourceHarvestAuthTypeClient SourceHarvestAuthType = "Client"
)

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

type AuthenticateViaHarvestOAuth struct {
	authType *SourceHarvestAuthType `const:"Client" json:"auth_type,omitempty"`
	// The Client ID of your Harvest developer application.
	ClientID string `json:"client_id"`
	// The Client Secret of your Harvest developer application.
	ClientSecret string `json:"client_secret"`
	// Refresh Token to renew the expired Access Token.
	RefreshToken         string `json:"refresh_token"`
	AdditionalProperties any    `additionalProperties:"true" json:"-"`
}

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

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

func (o *AuthenticateViaHarvestOAuth) GetAuthType() *SourceHarvestAuthType {
	return SourceHarvestAuthTypeClient.ToPointer()
}

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

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

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

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

type SourceHarvestAuthenticationMechanismType string

const (
	SourceHarvestAuthenticationMechanismTypeAuthenticateViaHarvestOAuth                      SourceHarvestAuthenticationMechanismType = "Authenticate via Harvest (OAuth)"
	SourceHarvestAuthenticationMechanismTypeSourceHarvestAuthenticateWithPersonalAccessToken SourceHarvestAuthenticationMechanismType = "source-harvest_Authenticate with Personal Access Token"
)

// SourceHarvestAuthenticationMechanism - Choose how to authenticate to Harvest.
type SourceHarvestAuthenticationMechanism struct {
	AuthenticateViaHarvestOAuth                      *AuthenticateViaHarvestOAuth                      `queryParam:"inline"`
	SourceHarvestAuthenticateWithPersonalAccessToken *SourceHarvestAuthenticateWithPersonalAccessToken `queryParam:"inline"`

	Type SourceHarvestAuthenticationMechanismType
}

func CreateSourceHarvestAuthenticationMechanismAuthenticateViaHarvestOAuth(authenticateViaHarvestOAuth AuthenticateViaHarvestOAuth) SourceHarvestAuthenticationMechanism {
	typ := SourceHarvestAuthenticationMechanismTypeAuthenticateViaHarvestOAuth

	return SourceHarvestAuthenticationMechanism{
		AuthenticateViaHarvestOAuth: &authenticateViaHarvestOAuth,
		Type:                        typ,
	}
}

func CreateSourceHarvestAuthenticationMechanismSourceHarvestAuthenticateWithPersonalAccessToken(sourceHarvestAuthenticateWithPersonalAccessToken SourceHarvestAuthenticateWithPersonalAccessToken) SourceHarvestAuthenticationMechanism {
	typ := SourceHarvestAuthenticationMechanismTypeSourceHarvestAuthenticateWithPersonalAccessToken

	return SourceHarvestAuthenticationMechanism{
		SourceHarvestAuthenticateWithPersonalAccessToken: &sourceHarvestAuthenticateWithPersonalAccessToken,
		Type: typ,
	}
}

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

	var sourceHarvestAuthenticateWithPersonalAccessToken SourceHarvestAuthenticateWithPersonalAccessToken = SourceHarvestAuthenticateWithPersonalAccessToken{}
	if err := utils.UnmarshalJSON(data, &sourceHarvestAuthenticateWithPersonalAccessToken, "", true, true); err == nil {
		u.SourceHarvestAuthenticateWithPersonalAccessToken = &sourceHarvestAuthenticateWithPersonalAccessToken
		u.Type = SourceHarvestAuthenticationMechanismTypeSourceHarvestAuthenticateWithPersonalAccessToken
		return nil
	}

	var authenticateViaHarvestOAuth AuthenticateViaHarvestOAuth = AuthenticateViaHarvestOAuth{}
	if err := utils.UnmarshalJSON(data, &authenticateViaHarvestOAuth, "", true, true); err == nil {
		u.AuthenticateViaHarvestOAuth = &authenticateViaHarvestOAuth
		u.Type = SourceHarvestAuthenticationMechanismTypeAuthenticateViaHarvestOAuth
		return nil
	}

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

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

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

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

type Harvest string

const (
	HarvestHarvest Harvest = "harvest"
)

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

type SourceHarvest struct {
	// Harvest account ID. Required for all Harvest requests in pair with Personal Access Token
	AccountID string `json:"account_id"`
	// Choose how to authenticate to Harvest.
	Credentials *SourceHarvestAuthenticationMechanism `json:"credentials,omitempty"`
	// UTC date and time in the format 2017-01-25T00:00:00Z. Any data before this date will not be replicated.
	ReplicationStartDate time.Time `json:"replication_start_date"`
	sourceType           Harvest   `const:"harvest" json:"sourceType"`
}

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

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

func (o *SourceHarvest) GetAccountID() string {
	if o == nil {
		return ""
	}
	return o.AccountID
}

func (o *SourceHarvest) GetCredentials() *SourceHarvestAuthenticationMechanism {
	if o == nil {
		return nil
	}
	return o.Credentials
}

func (o *SourceHarvest) GetReplicationStartDate() time.Time {
	if o == nil {
		return time.Time{}
	}
	return o.ReplicationStartDate
}

func (o *SourceHarvest) GetSourceType() Harvest {
	return HarvestHarvest
}
