package click.kamil.springstatemachineexporter.ast.common;

import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
import org.eclipse.jdt.core.dom.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.atomic.AtomicReference;

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

class AstUtilsSwitchConstraintTest {

    @Test
    void shouldExtractSwitchCaseConstraintForArrowSwitch(@TempDir Path tempDir) throws Exception {
        String source = """
            package com.example;
            class Demo {
                void dispatch(DomainCommand command) {
                    switch (command) {
                        case ORDER_PAY -> orderPay();
                        case ORDER_SHIP -> orderShip();
                    }
                }
                void orderPay() {}
                void orderShip() {}
            }
            enum DomainCommand { ORDER_PAY, ORDER_SHIP }
            """;
        Files.writeString(tempDir.resolve("Demo.java"), source);

        CodebaseContext context = new CodebaseContext();
        context.setResolveBindings(true);
        context.scan(tempDir);

        AtomicReference<MethodInvocation> orderPayCall = new AtomicReference<>();
        for (CompilationUnit cu : context.getCompilationUnits()) {
            cu.accept(new ASTVisitor() {
                @Override
                public boolean visit(MethodInvocation node) {
                    if ("orderPay".equals(node.getName().getIdentifier())
                            && node.getExpression() == null) {
                        orderPayCall.set(node);
                    }
                    return super.visit(node);
                }
            });
        }

        if (orderPayCall.get() == null) {
            org.junit.jupiter.api.Assertions.fail("orderPay MethodInvocation not found in AST");
        }
        assertThat(AstUtils.findEnclosingSwitchCase(orderPayCall.get())).isNotNull();
        String constraint = AstUtils.findConditionConstraint(orderPayCall.get());
        assertThat(constraint).contains("command == ORDER_PAY");
    }
}
