package providers

import (
	"ai-css/library/modelprovider"
	"ai-css/library/modelprovider/config"
	"ai-css/library/modelprovider/consts"
	"ai-css/library/modelprovider/providers/openai"
	"net"
	"net/http"
	"sync"
	"time"
)

var (
	HttpClientTimeout = 5 * 60 * time.Second

	client *http.Client

	InitClient sync.Once
)

type ProviderFactory func(conf *config.ProviderConfig) (modelprovider.Provider, error)

type Registry struct {
	Providers map[consts.ProviderName]ProviderFactory // name -> Provider
}

func BuildRegistry() *Registry {
	var providers = map[consts.ProviderName]ProviderFactory{
		consts.ProviderOpenAI: func(providerConfig *config.ProviderConfig) (modelprovider.Provider, error) {
			return openai.New(providerConfig, NewHttpClient()), nil
		},
	}
	return &Registry{Providers: providers}
}

func NewHttpClient() *http.Client {
	if client != nil {
		return client
	}
	InitClient.Do(func() {
		var proxyURL = GetRemoteProxy()

		transport := &http.Transport{
			DialContext: (&net.Dialer{
				Timeout:   90 * time.Second,
				KeepAlive: 30 * time.Second,
			}).DialContext,
			ForceAttemptHTTP2:     true,
			MaxIdleConns:          100,
			IdleConnTimeout:       90 * time.Second,
			TLSHandshakeTimeout:   90 * time.Second,
			ExpectContinueTimeout: 1 * time.Second,
		}

		if proxyURL != nil {
			transport.Proxy = http.ProxyURL(proxyURL)
		}

		client = &http.Client{
			Transport: transport,
			Timeout:   HttpClientTimeout,
		}
	})
	return client
}
