package at.procon.eventhub.processing.eventprocessing.module;

import at.procon.eventhub.processing.eventprocessing.plan.RuntimeProcessingModuleDescriptorDto;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Component;

@Component
public class RuntimeProcessingModuleRegistry {

    private final Map<String, RuntimeProcessingModule> modulesByKey;

    public RuntimeProcessingModuleRegistry(List<RuntimeProcessingModule> modules) {
        LinkedHashMap<String, RuntimeProcessingModule> byKey = new LinkedHashMap<>();
        if (modules != null) {
            for (RuntimeProcessingModule module : modules) {
                if (module == null || module.moduleKey() == null || module.moduleKey().isBlank()) {
                    continue;
                }
                RuntimeProcessingModule previous = byKey.putIfAbsent(module.moduleKey(), module);
                if (previous != null) {
                    throw new IllegalStateException("Duplicate runtime processing module key: " + module.moduleKey());
                }
            }
        }
        this.modulesByKey = Map.copyOf(byKey);
    }

    public Collection<RuntimeProcessingModule> modules() {
        return modulesByKey.values();
    }

    public List<RuntimeProcessingModuleDescriptorDto> descriptors() {
        return modulesByKey.values().stream()
                .map(RuntimeProcessingModule::descriptor)
                .toList();
    }

    public RuntimeProcessingModule require(String moduleKey) {
        RuntimeProcessingModule module = modulesByKey.get(moduleKey);
        if (module == null) {
            throw new IllegalArgumentException("Unknown runtime processing module: " + moduleKey);
        }
        return module;
    }
}
