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

const (
	SourceGithubOptionTitlePatCredentials SourceGithubOptionTitle = "PAT Credentials"
)

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

type SourceGithubPersonalAccessToken struct {
	optionTitle *SourceGithubOptionTitle `const:"PAT Credentials" json:"option_title,omitempty"`
	// Log into GitHub and then generate a <a href="https://github.com/settings/tokens">personal access token</a>. To load balance your API quota consumption across multiple API tokens, input multiple tokens separated with ","
	PersonalAccessToken string `json:"personal_access_token"`
}

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

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

func (o *SourceGithubPersonalAccessToken) GetOptionTitle() *SourceGithubOptionTitle {
	return SourceGithubOptionTitlePatCredentials.ToPointer()
}

func (o *SourceGithubPersonalAccessToken) GetPersonalAccessToken() string {
	if o == nil {
		return ""
	}
	return o.PersonalAccessToken
}

type OptionTitle string

const (
	OptionTitleOAuthCredentials OptionTitle = "OAuth Credentials"
)

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

type OAuth struct {
	// OAuth access token
	AccessToken string `json:"access_token"`
	// OAuth Client Id
	ClientID *string `json:"client_id,omitempty"`
	// OAuth Client secret
	ClientSecret *string      `json:"client_secret,omitempty"`
	optionTitle  *OptionTitle `const:"OAuth Credentials" json:"option_title,omitempty"`
}

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

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

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

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

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

func (o *OAuth) GetOptionTitle() *OptionTitle {
	return OptionTitleOAuthCredentials.ToPointer()
}

type SourceGithubAuthenticationType string

const (
	SourceGithubAuthenticationTypeOAuth                           SourceGithubAuthenticationType = "OAuth"
	SourceGithubAuthenticationTypeSourceGithubPersonalAccessToken SourceGithubAuthenticationType = "source-github_Personal Access Token"
)

// SourceGithubAuthentication - Choose how to authenticate to GitHub
type SourceGithubAuthentication struct {
	OAuth                           *OAuth                           `queryParam:"inline"`
	SourceGithubPersonalAccessToken *SourceGithubPersonalAccessToken `queryParam:"inline"`

	Type SourceGithubAuthenticationType
}

func CreateSourceGithubAuthenticationOAuth(oAuth OAuth) SourceGithubAuthentication {
	typ := SourceGithubAuthenticationTypeOAuth

	return SourceGithubAuthentication{
		OAuth: &oAuth,
		Type:  typ,
	}
}

func CreateSourceGithubAuthenticationSourceGithubPersonalAccessToken(sourceGithubPersonalAccessToken SourceGithubPersonalAccessToken) SourceGithubAuthentication {
	typ := SourceGithubAuthenticationTypeSourceGithubPersonalAccessToken

	return SourceGithubAuthentication{
		SourceGithubPersonalAccessToken: &sourceGithubPersonalAccessToken,
		Type:                            typ,
	}
}

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

	var sourceGithubPersonalAccessToken SourceGithubPersonalAccessToken = SourceGithubPersonalAccessToken{}
	if err := utils.UnmarshalJSON(data, &sourceGithubPersonalAccessToken, "", true, true); err == nil {
		u.SourceGithubPersonalAccessToken = &sourceGithubPersonalAccessToken
		u.Type = SourceGithubAuthenticationTypeSourceGithubPersonalAccessToken
		return nil
	}

	var oAuth OAuth = OAuth{}
	if err := utils.UnmarshalJSON(data, &oAuth, "", true, true); err == nil {
		u.OAuth = &oAuth
		u.Type = SourceGithubAuthenticationTypeOAuth
		return nil
	}

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

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

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

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

type Github string

const (
	GithubGithub Github = "github"
)

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

type SourceGithub struct {
	// Please enter your basic URL from self-hosted GitHub instance or leave it empty to use GitHub.
	APIURL *string `default:"https://api.github.com/" json:"api_url"`
	// List of GitHub repository branches to pull commits for, e.g. `airbytehq/airbyte/master`. If no branches are specified for a repository, the default branch will be pulled.
	Branches []string `json:"branches,omitempty"`
	// Choose how to authenticate to GitHub
	Credentials SourceGithubAuthentication `json:"credentials"`
	// Max Waiting Time for rate limit. Set higher value to wait till rate limits will be resetted to continue sync
	MaxWaitingTime *int64 `default:"10" json:"max_waiting_time"`
	// List of GitHub organizations/repositories, e.g. `airbytehq/airbyte` for single repository, `airbytehq/*` for get all repositories from organization and `airbytehq/a* for matching multiple repositories by pattern.
	Repositories []string `json:"repositories"`
	// The date from which you'd like to replicate data from GitHub in the format YYYY-MM-DDT00:00:00Z. If the date is not set, all data will be replicated.  For the streams which support this configuration, only data generated on or after the start date will be replicated. This field doesn't apply to all streams, see the <a href="https://docs.airbyte.com/integrations/sources/github">docs</a> for more info
	StartDate  *time.Time `json:"start_date,omitempty"`
	sourceType Github     `const:"github" json:"sourceType"`
}

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

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

func (o *SourceGithub) GetAPIURL() *string {
	if o == nil {
		return nil
	}
	return o.APIURL
}

func (o *SourceGithub) GetBranches() []string {
	if o == nil {
		return nil
	}
	return o.Branches
}

func (o *SourceGithub) GetCredentials() SourceGithubAuthentication {
	if o == nil {
		return SourceGithubAuthentication{}
	}
	return o.Credentials
}

func (o *SourceGithub) GetMaxWaitingTime() *int64 {
	if o == nil {
		return nil
	}
	return o.MaxWaitingTime
}

func (o *SourceGithub) GetRepositories() []string {
	if o == nil {
		return []string{}
	}
	return o.Repositories
}

func (o *SourceGithub) GetStartDate() *time.Time {
	if o == nil {
		return nil
	}
	return o.StartDate
}

func (o *SourceGithub) GetSourceType() Github {
	return GithubGithub
}
