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

import at.procon.eventhub.processing.eventprocessing.partition.RuntimeEventPartitioningStrategy;
import java.util.List;
import java.util.Set;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

class RuntimeProcessingPlanRegistryTest {

    @Test
    void resolvesPlansByPrimaryKeyAndAlias() {
        RuntimeProcessingPlanRegistry registry = new RuntimeProcessingPlanRegistry(List.of(new TestPlan("plan-a", Set.of("legacy-a"))));

        assertThat(registry.require("plan-a").processingPlanKey()).isEqualTo("plan-a");
        assertThat(registry.require("legacy-a").processingPlanKey()).isEqualTo("plan-a");
        assertThat(registry.planDescriptors()).hasSize(1);
        assertThat(registry.planDescriptors().get(0).aliases()).contains("legacy-a");
    }

    @Test
    void rejectsDuplicatePlanKeys() {
        assertThatThrownBy(() -> new RuntimeProcessingPlanRegistry(List.of(
                new TestPlan("plan-a", Set.of()),
                new TestPlan("plan-a", Set.of())
        )))
                .isInstanceOf(IllegalStateException.class)
                .hasMessageContaining("Duplicate runtime processingPlanKey");
    }

    @Test
    void rejectsDuplicateAliasesPointingToDifferentPlans() {
        assertThatThrownBy(() -> new RuntimeProcessingPlanRegistry(List.of(
                new TestPlan("plan-a", Set.of("alias")),
                new TestPlan("plan-b", Set.of("alias"))
        )))
                .isInstanceOf(IllegalStateException.class)
                .hasMessageContaining("Duplicate runtime processing plan alias/key");
    }

    private record TestPlan(String key, Set<String> aliases) implements RuntimeProcessingPlan {

        @Override
        public String processingPlanKey() {
            return key;
        }

        @Override
        public RuntimeEventPartitioningStrategy defaultPartitioningStrategy() {
            return RuntimeEventPartitioningStrategy.DRIVER;
        }

        @Override
        public RuntimeProcessingExecutionResultDto execute(RuntimeProcessingExecutionApiRequest request) {
            throw new UnsupportedOperationException("not needed");
        }
    }
}
