package click.kamil.springstatemachineexporter.analysis.service;

import click.kamil.springstatemachineexporter.analysis.model.CallEdge;
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
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.List;
import java.util.Map;

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

class PathBindingExpressionResolverMultiFileTest {

    @Test
    void ctorInjectedMapperAcrossPackagesResolvesUnderBindings(@TempDir Path tempDir) throws Exception {
        Path web = tempDir.resolve("web");
        Path dispatch = tempDir.resolve("dispatch");
        Files.createDirectories(web);
        Files.createDirectories(dispatch);
        Files.writeString(web.resolve("CommandGateway.java"), """
            package com.example.web;
            import com.example.dispatch.StringCommandMapper;
            import com.example.dispatch.DomainCommand;
            public class CommandGateway {
                private final StringCommandMapper stringCommandMapper;
                public CommandGateway(StringCommandMapper stringCommandMapper) {
                    this.stringCommandMapper = stringCommandMapper;
                }
                public void executeViaMapper(String commandKey) {
                    DomainCommand command = stringCommandMapper.fromString(commandKey);
                }
            }
            """);
        Files.writeString(dispatch.resolve("StringCommandMapper.java"), """
            package com.example.dispatch;
            public class StringCommandMapper {
                public DomainCommand fromString(String commandKey) {
                    return switch (commandKey) {
                        case "order.pay" -> DomainCommand.ORDER_PAY;
                        case "order.ship" -> DomainCommand.ORDER_SHIP;
                        default -> throw new IllegalArgumentException(commandKey);
                    };
                }
            }
            """);
        Files.writeString(dispatch.resolve("DomainCommand.java"), """
            package com.example.dispatch;
            public enum DomainCommand { ORDER_PAY, ORDER_SHIP }
            """);

        CodebaseContext context = new CodebaseContext();
        context.setResolveBindings(true);
        context.scan(tempDir);
        VariableTracer vt = new VariableTracer(context, context.getConstantResolver());
        vt.setTypeResolver(new TypeResolver(context));
        PathBindingExpressionResolver resolver =
                new PathBindingExpressionResolver(context, vt, context.getConstantResolver());

        String resolved = resolver.resolveMethodCallFromSource(
                "com.example.web.CommandGateway.executeViaMapper",
                "command",
                Map.of("commandKey", "order.pay"));
        assertThat(resolved).isEqualTo("DomainCommand.ORDER_PAY");

        String traced = vt.traceLocalVariable(
                "com.example.web.CommandGateway.executeViaMapper",
                "command",
                Map.of("commandKey", "order.pay"));
        assertThat(traced).isEqualTo("DomainCommand.ORDER_PAY");
    }
}
