package config

import (
	"sync"
	"time"

	"ai-css/library/logger"
)

type ProviderConfig struct {
	baseURL      string
	apiKeys      []string
	BlackApiKeys map[string]struct{}

	apiKeysLock *sync.Mutex
	blackLock   *sync.Mutex
}

func NewProviderConfig(burl string, apiKeys []string) ProviderConfig {
	return ProviderConfig{baseURL: burl, apiKeys: apiKeys, BlackApiKeys: make(map[string]struct{}), apiKeysLock: new(sync.Mutex), blackLock: new(sync.Mutex)}
}

func (p *ProviderConfig) ApikeyIsBlack(apikey string) bool {
	p.blackLock.Lock()
	defer p.blackLock.Unlock()
	_, found := p.BlackApiKeys[apikey]
	return found
}

func (p *ProviderConfig) AddBlackKey(apikey string) {
	p.blackLock.Lock()
	defer p.blackLock.Unlock()
	p.BlackApiKeys[apikey] = struct{}{}
	return
}

func (p *ProviderConfig) GetBaseUrl() string {
	return p.baseURL
}

func (p *ProviderConfig) GetApiKeys() []string {
	p.apiKeysLock.Lock()
	defer p.apiKeysLock.Unlock()

	return p.apiKeys
}

func (p *ProviderConfig) SetApiKeys(keys []string) {
	p.apiKeysLock.Lock()
	defer p.apiKeysLock.Unlock()
	p.apiKeys = keys
	return
}

func (p *ProviderConfig) SetRetryPullConfig(retryFunc func(*ProviderConfig) bool, interval time.Duration) {
	if interval <= 0 {
		logger.Warnf("SetRetryPullConfig interval is invalid %d", interval)
		return
	}
	go startRetryPullConfig(func() bool {
		return retryFunc(p)
	}, interval)
}

func startRetryPullConfig(retryFunc func() bool, interval time.Duration) {
	timer := time.NewTimer(interval)
	defer timer.Stop()

	for {
		<-timer.C

		isFinish := false

		func() {
			defer func() {
				if r := recover(); r != nil {
					logger.Errorf("retry panic: %v", r)
				}
			}()

			isFinish = retryFunc()
		}()

		if isFinish {
			return
		}

		timer.Reset(interval)
	}
}
