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

import at.procon.eventhub.processing.eventprocessing.plan.RuntimeProcessingExecutionApiRequest;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;

@Service
public class RuntimeProcessingPipelineExecutor {

    private final RuntimeProcessingModuleRegistry moduleRegistry;

    public RuntimeProcessingPipelineExecutor(RuntimeProcessingModuleRegistry moduleRegistry) {
        this.moduleRegistry = moduleRegistry;
    }

    public Map<String, RuntimeProcessingModuleResult> execute(
            RuntimeProcessingExecutionApiRequest request,
            List<String> moduleKeys,
            RuntimeProcessingModuleContext initialContext
    ) {
        LinkedHashMap<String, RuntimeProcessingModuleResult> results = new LinkedHashMap<>();
        RuntimeProcessingModuleContext context = initialContext == null
                ? new RuntimeProcessingModuleContext(request, List.of(), Map.of(), Map.of())
                : initialContext;
        for (String moduleKey : moduleKeys == null ? List.<String>of() : moduleKeys) {
            if (moduleKey == null || moduleKey.isBlank()) {
                continue;
            }
            RuntimeProcessingModule module = moduleRegistry.require(moduleKey.trim());
            RuntimeProcessingModuleResult result = module.execute(context);
            results.put(module.moduleKey(), result);
            context = new RuntimeProcessingModuleContext(
                    request,
                    context.events(),
                    context.attributes(),
                    results
            );
            if (result.status() == RuntimeProcessingModuleStatus.FAILED) {
                break;
            }
        }
        return Map.copyOf(results);
    }
}
