package com.agent.management.engine;

import org.junit.jupiter.api.Test;

import java.util.Set;

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

class WorkflowScopeResolverTest {

    private DagResolver.ResolvedDag createDag() {
        DagResolver.ResolvedDag dag = new DagResolver.ResolvedDag();
        dag.getLevels().add(java.util.List.of("A", "B"));
        dag.getLevels().add(java.util.List.of("C"));
        dag.getLevels().add(java.util.List.of("D"));

        // A -> C, B -> C, C -> D
        dag.getOutgoingEdges().put("A", java.util.List.of(new DagResolver.EdgeInfo("A", "C", "output")));
        dag.getOutgoingEdges().put("B", java.util.List.of(new DagResolver.EdgeInfo("B", "C", "output")));
        dag.getOutgoingEdges().put("C", java.util.List.of(new DagResolver.EdgeInfo("C", "D", "output")));
        dag.getOutgoingEdges().put("D", java.util.List.of());

        dag.getIncomingEdges().put("A", java.util.List.of());
        dag.getIncomingEdges().put("B", java.util.List.of());
        dag.getIncomingEdges().put("C", java.util.List.of(
                new DagResolver.EdgeInfo("A", "C", "output"),
                new DagResolver.EdgeInfo("B", "C", "output")));
        dag.getIncomingEdges().put("D", java.util.List.of(new DagResolver.EdgeInfo("C", "D", "output")));
        return dag;
    }

    @Test
    void staticReachableIncludesAllPredecessors() {
        DagResolver.ResolvedDag dag = createDag();
        assertThat(WorkflowScopeResolver.getReachablePredecessors("D", dag))
                .containsExactlyInAnyOrder("C", "B", "A");
        assertThat(WorkflowScopeResolver.getReachablePredecessors("C", dag))
                .containsExactlyInAnyOrder("A", "B");
        assertThat(WorkflowScopeResolver.getReachablePredecessors("A", dag)).isEmpty();
    }

    @Test
    void dynamicReachableFiltersByActiveEdges() {
        DagResolver.ResolvedDag dag = createDag();
        Set<String> active = Set.of(
                WorkflowScopeResolver.activeEdgeKey("A", "output", "C"),
                WorkflowScopeResolver.activeEdgeKey("C", "output", "D")
        );
        assertThat(WorkflowScopeResolver.getReachablePredecessors("D", dag, active))
                .containsExactlyInAnyOrder("C", "A");
    }

    @Test
    void activeEdgeKeyNormalizesNullHandle() {
        assertThat(WorkflowScopeResolver.activeEdgeKey("A", null, "B")).isEqualTo("A-output-B");
        assertThat(WorkflowScopeResolver.activeEdgeKey("A", "branch-1", "B")).isEqualTo("A-branch-1-B");
    }
}
