package plugins import ( "fmt" "sync" "bugulma/backend/internal/domain" ) // Registry implements the PluginRegistry interface type Registry struct { plugins map[string]Plugin byType map[domain.ResourceType][]Plugin mutex sync.RWMutex } // NewRegistry creates a new plugin registry func NewRegistry() *Registry { return &Registry{ plugins: make(map[string]Plugin), byType: make(map[domain.ResourceType][]Plugin), } } // Register registers a plugin with the registry func (r *Registry) Register(plugin Plugin) error { r.mutex.Lock() defer r.mutex.Unlock() name := plugin.Name() if _, exists := r.plugins[name]; exists { return fmt.Errorf("plugin with name '%s' already registered", name) } r.plugins[name] = plugin resourceType := plugin.ResourceType() r.byType[resourceType] = append(r.byType[resourceType], plugin) return nil } // GetByResourceType returns all plugins for a specific resource type func (r *Registry) GetByResourceType(resourceType domain.ResourceType) []Plugin { r.mutex.RLock() defer r.mutex.RUnlock() plugins, exists := r.byType[resourceType] if !exists { return []Plugin{} } // Return a copy to prevent external modification result := make([]Plugin, len(plugins)) copy(result, plugins) return result } // GetByName returns a plugin by its name func (r *Registry) GetByName(name string) (Plugin, error) { r.mutex.RLock() defer r.mutex.RUnlock() plugin, exists := r.plugins[name] if !exists { return nil, fmt.Errorf("plugin '%s' not found", name) } return plugin, nil } // ListAll returns all registered plugins func (r *Registry) ListAll() []Plugin { r.mutex.RLock() defer r.mutex.RUnlock() result := make([]Plugin, 0, len(r.plugins)) for _, plugin := range r.plugins { result = append(result, plugin) } return result } // GetMetadata returns metadata for a plugin func (r *Registry) GetMetadata(name string) (*PluginMetadata, error) { plugin, err := r.GetByName(name) if err != nil { return nil, err } capabilities := []string{} if plugin.SupportsQualityCheck() { capabilities = append(capabilities, "quality_check") } if plugin.SupportsEconomicCalculation() { capabilities = append(capabilities, "economic_calculation") } if plugin.SupportsTemporalCheck() { capabilities = append(capabilities, "temporal_check") } return &PluginMetadata{ Name: plugin.Name(), ResourceType: string(plugin.ResourceType()), Capabilities: capabilities, Description: fmt.Sprintf("Plugin for %s resource type", plugin.ResourceType()), }, nil }