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

import at.procon.eventhub.processing.eventprocessing.dto.RuntimeEventPartitioningApiRequest;
import at.procon.eventhub.processing.eventprocessing.partition.RuntimeEventPartitioningStrategy;
import java.util.List;
import java.util.Set;

public interface RuntimeProcessingPlan {

    String processingPlanKey();

    default Set<String> aliases() {
        return Set.of();
    }

    RuntimeEventPartitioningStrategy defaultPartitioningStrategy();

    default String displayName() {
        return processingPlanKey();
    }

    default String description() {
        return "";
    }

    default List<RuntimeEventPartitioningStrategy> supportedPartitioningStrategies() {
        RuntimeEventPartitioningStrategy defaultStrategy = defaultPartitioningStrategy();
        return defaultStrategy == null ? List.of() : List.of(defaultStrategy);
    }

    default List<RuntimeProcessingModuleDescriptorDto> modules() {
        return List.of();
    }

    default Set<String> requiredParameters() {
        return Set.of();
    }

    default Set<String> optionalParameters() {
        return Set.of();
    }

    RuntimeProcessingExecutionResultDto execute(RuntimeProcessingExecutionApiRequest request);

    default void validatePartitioning(RuntimeEventPartitioningApiRequest partitioning) {
        RuntimeEventPartitioningStrategy requested = partitioning == null || partitioning.strategy() == null
                ? defaultPartitioningStrategy()
                : partitioning.strategy();
        if (requested != null && !supportedPartitioningStrategies().contains(requested)) {
            throw new IllegalArgumentException("Processing plan " + processingPlanKey()
                    + " does not support partitioning strategy " + requested
                    + ". Supported: " + supportedPartitioningStrategies());
        }
    }
}
