// Package agents provides a global registry for agent rule factories.
//
// Each agent package self-registers via init() using Register.
// The launcher retrieves rules via GetRules without importing agent
// packages explicitly (only blank imports are needed).
package devagents

import (
	"sync"

	"github.com/enmanuel/agents/pkg/decision"
)

// RulesFunc is a factory that returns the decision rules for an agent.
type RulesFunc func() []decision.Rule

var (
	registryMu sync.RWMutex
	registry   = make(map[string]RulesFunc)
)

// Register adds a rule factory for the given agent ID.
// Intended to be called from init() in each agent package.
// Panics if the same ID is registered twice (catches copy-paste errors early).
func Register(id string, fn RulesFunc) {
	registryMu.Lock()
	defer registryMu.Unlock()

	if _, exists := registry[id]; exists {
		panic("agents.Register: duplicate agent id: " + id)
	}
	registry[id] = fn
}

// GetRules returns the rule factory for the given agent ID.
// Returns nil if no rules are registered (the agent is command-only).
func GetRules(id string) RulesFunc {
	registryMu.RLock()
	defer registryMu.RUnlock()
	return registry[id]
}

// RegisteredIDs returns a sorted list of all registered agent IDs.
// Useful for debugging and diagnostics.
func RegisteredIDs() []string {
	registryMu.RLock()
	defer registryMu.RUnlock()

	ids := make([]string, 0, len(registry))
	for id := range registry {
		ids = append(ids, id)
	}
	return ids
}

// resetRegistry clears all registrations (for testing only).
func resetRegistry() {
	registryMu.Lock()
	defer registryMu.Unlock()
	registry = make(map[string]RulesFunc)
}
