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

const (
	SourceHarvestUpdateSchemasAuthTypeToken SourceHarvestUpdateSchemasAuthType = "Token"
)

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

type SourceHarvestUpdateAuthenticateWithPersonalAccessToken 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             *SourceHarvestUpdateSchemasAuthType `const:"Token" json:"auth_type,omitempty"`
	AdditionalProperties any                                 `additionalProperties:"true" json:"-"`
}

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

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

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

func (o *SourceHarvestUpdateAuthenticateWithPersonalAccessToken) GetAuthType() *SourceHarvestUpdateSchemasAuthType {
	return SourceHarvestUpdateSchemasAuthTypeToken.ToPointer()
}

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

type SourceHarvestUpdateAuthType string

const (
	SourceHarvestUpdateAuthTypeClient SourceHarvestUpdateAuthType = "Client"
)

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

type SourceHarvestUpdateAuthenticateViaHarvestOAuth struct {
	authType *SourceHarvestUpdateAuthType `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 (s SourceHarvestUpdateAuthenticateViaHarvestOAuth) MarshalJSON() ([]byte, error) {
	return utils.MarshalJSON(s, "", false)
}

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

func (o *SourceHarvestUpdateAuthenticateViaHarvestOAuth) GetAuthType() *SourceHarvestUpdateAuthType {
	return SourceHarvestUpdateAuthTypeClient.ToPointer()
}

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

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

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

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

type SourceHarvestUpdateAuthenticationMechanismType string

const (
	SourceHarvestUpdateAuthenticationMechanismTypeSourceHarvestUpdateAuthenticateViaHarvestOAuth         SourceHarvestUpdateAuthenticationMechanismType = "source-harvest-update_Authenticate via Harvest (OAuth)"
	SourceHarvestUpdateAuthenticationMechanismTypeSourceHarvestUpdateAuthenticateWithPersonalAccessToken SourceHarvestUpdateAuthenticationMechanismType = "source-harvest-update_Authenticate with Personal Access Token"
)

// SourceHarvestUpdateAuthenticationMechanism - Choose how to authenticate to Harvest.
type SourceHarvestUpdateAuthenticationMechanism struct {
	SourceHarvestUpdateAuthenticateViaHarvestOAuth         *SourceHarvestUpdateAuthenticateViaHarvestOAuth         `queryParam:"inline"`
	SourceHarvestUpdateAuthenticateWithPersonalAccessToken *SourceHarvestUpdateAuthenticateWithPersonalAccessToken `queryParam:"inline"`

	Type SourceHarvestUpdateAuthenticationMechanismType
}

func CreateSourceHarvestUpdateAuthenticationMechanismSourceHarvestUpdateAuthenticateViaHarvestOAuth(sourceHarvestUpdateAuthenticateViaHarvestOAuth SourceHarvestUpdateAuthenticateViaHarvestOAuth) SourceHarvestUpdateAuthenticationMechanism {
	typ := SourceHarvestUpdateAuthenticationMechanismTypeSourceHarvestUpdateAuthenticateViaHarvestOAuth

	return SourceHarvestUpdateAuthenticationMechanism{
		SourceHarvestUpdateAuthenticateViaHarvestOAuth: &sourceHarvestUpdateAuthenticateViaHarvestOAuth,
		Type: typ,
	}
}

func CreateSourceHarvestUpdateAuthenticationMechanismSourceHarvestUpdateAuthenticateWithPersonalAccessToken(sourceHarvestUpdateAuthenticateWithPersonalAccessToken SourceHarvestUpdateAuthenticateWithPersonalAccessToken) SourceHarvestUpdateAuthenticationMechanism {
	typ := SourceHarvestUpdateAuthenticationMechanismTypeSourceHarvestUpdateAuthenticateWithPersonalAccessToken

	return SourceHarvestUpdateAuthenticationMechanism{
		SourceHarvestUpdateAuthenticateWithPersonalAccessToken: &sourceHarvestUpdateAuthenticateWithPersonalAccessToken,
		Type: typ,
	}
}

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

	var sourceHarvestUpdateAuthenticateWithPersonalAccessToken SourceHarvestUpdateAuthenticateWithPersonalAccessToken = SourceHarvestUpdateAuthenticateWithPersonalAccessToken{}
	if err := utils.UnmarshalJSON(data, &sourceHarvestUpdateAuthenticateWithPersonalAccessToken, "", true, true); err == nil {
		u.SourceHarvestUpdateAuthenticateWithPersonalAccessToken = &sourceHarvestUpdateAuthenticateWithPersonalAccessToken
		u.Type = SourceHarvestUpdateAuthenticationMechanismTypeSourceHarvestUpdateAuthenticateWithPersonalAccessToken
		return nil
	}

	var sourceHarvestUpdateAuthenticateViaHarvestOAuth SourceHarvestUpdateAuthenticateViaHarvestOAuth = SourceHarvestUpdateAuthenticateViaHarvestOAuth{}
	if err := utils.UnmarshalJSON(data, &sourceHarvestUpdateAuthenticateViaHarvestOAuth, "", true, true); err == nil {
		u.SourceHarvestUpdateAuthenticateViaHarvestOAuth = &sourceHarvestUpdateAuthenticateViaHarvestOAuth
		u.Type = SourceHarvestUpdateAuthenticationMechanismTypeSourceHarvestUpdateAuthenticateViaHarvestOAuth
		return nil
	}

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

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

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

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

type SourceHarvestUpdate 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 *SourceHarvestUpdateAuthenticationMechanism `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"`
}

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

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

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

func (o *SourceHarvestUpdate) GetCredentials() *SourceHarvestUpdateAuthenticationMechanism {
	if o == nil {
		return nil
	}
	return o.Credentials
}

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