package connector_oauth

import (
	"encoding/json"
	"strings"
	"time"
)

type pendingTokenSet struct {
	AccessToken  string   `json:"access_token"`
	RefreshToken string   `json:"refresh_token,omitempty"`
	TokenType    string   `json:"token_type,omitempty"`
	Scopes       []string `json:"scopes,omitempty"`
	ExpiresAt    *string  `json:"expires_at,omitempty"`
}

func marshalPendingTokenSet(tokens TokenSet) ([]byte, error) {
	pending := pendingTokenSet{
		AccessToken: tokens.AccessToken, RefreshToken: tokens.RefreshToken,
		TokenType: strings.TrimSpace(tokens.TokenType), Scopes: normalizeScopes(tokens.Scopes),
	}
	if tokens.ExpiresAt != nil {
		value := tokens.ExpiresAt.UTC().Format("2006-01-02T15:04:05.999999999Z07:00")
		pending.ExpiresAt = &value
	}
	return json.Marshal(pending)
}

func unmarshalPendingTokenSet(payload []byte) (TokenSet, error) {
	var pending pendingTokenSet
	if err := json.Unmarshal(payload, &pending); err != nil {
		return TokenSet{}, ErrCiphertextInvalid
	}
	tokens := TokenSet{
		AccessToken: pending.AccessToken, RefreshToken: pending.RefreshToken,
		TokenType: pending.TokenType, Scopes: normalizeScopes(pending.Scopes),
	}
	if pending.ExpiresAt != nil {
		expiresAt, err := time.Parse("2006-01-02T15:04:05.999999999Z07:00", *pending.ExpiresAt)
		if err != nil {
			return TokenSet{}, ErrCiphertextInvalid
		}
		tokens.ExpiresAt = &expiresAt
	}
	if err := validateTokenSet(tokens); err != nil {
		return TokenSet{}, ErrCiphertextInvalid
	}
	return tokens, nil
}
