package handler

import (
	"context"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/errors"
)

const (
	AWSAccountProvider = "aws_account_provider"
	GCPAccountProvider = "gcp_account_provider"
)

type AccountHandler interface {
	GetAccountProvider(accountProvider string) (AccountProvider, error)
	GetAllAccountProviders() ([]AccountProvider, error)
}

var globalAccountHandler AccountHandler

func init() {
	globalAccountHandler = &AccountHandlerImpl{}
}

func SetAccountHandler(accountHandler AccountHandler) {
	// Unittest Only
	globalAccountHandler = accountHandler
}

func GetAccountHandler() AccountHandler {
	return globalAccountHandler
}

type AccountProvider interface {
	ResolveToken(token *string) (*string, error)
	GetTokenFromRedirect(c *gin.Context) (*string, error)
	ProcessTenantSubscribeChange(ctx context.Context, processor ProcessTenantSubsribeChangeFunc) error
}

type AccountHandlerImpl struct {
}

const (
	SubscribeStatusSubsribed    = "subsribed"
	SubscribeStatusUnsubscribed = "unsubscribed"
)

type SubscribeChange struct {
	AccountProvider string
	AccountCode     string
	SubscribeStatus string
}

func (*AccountHandlerImpl) GetAccountProvider(accountProvider string) (AccountProvider, error) {
	if accountProvider == AWSAccountProvider {
		return &awsAccountProviderImpl{}, nil
	}
	if accountProvider == GCPAccountProvider {
		return &gcpAccountProviderImpl{}, nil
	}
	return nil, errors.New("invalid third party account provider")
}

func (*AccountHandlerImpl) GetAllAccountProviders() ([]AccountProvider, error) {
	return []AccountProvider{
		&awsAccountProviderImpl{},
		&gcpAccountProviderImpl{},
	}, nil
}

type ProcessTenantSubsribeChangeFunc func(context.Context, SubscribeChange) (bool, error)
