package repo

import (
	"fmt"
	"sync"
)

var (
	pluginsMu sync.RWMutex
	plugins   = make(map[string]PluginCreateFunc)
)

type PluginCreateFunc func() RepoManager

type PluginConfig interface {
	Get(key string) (any, error)
	Set(key string, value any)
}

type pluginConfig struct {
	config map[string]any
}

func (c *pluginConfig) Get(key string) (any, error) {
	val, exists := c.config[key]
	if !exists {
		return "", fmt.Errorf("key %s not found", key)
	}
	return val, nil
}

func (c *pluginConfig) Set(key string, value any) {
	c.config[key] = value
}

func NewPluginConfig() PluginConfig {
	return &pluginConfig{
		config: make(map[string]any),
	}
}

func RegisterPlugin(name string, fun PluginCreateFunc) {
	pluginsMu.Lock()
	defer pluginsMu.Unlock()

	if fun == nil {
		panic("plugin create func cannot be nil")
	}

	if old, exists := plugins[name]; exists {
		fmt.Printf("WARNING: plugin '%s' already registered (%T), overwriting\n", name, old)
	}

	plugins[name] = fun
}

func GetPlugin(name string) (RepoManager, bool) {
	pluginsMu.RLock()
	defer pluginsMu.RUnlock()

	fun, exists := plugins[name]
	return fun(), exists
}
