package click.kamil.springstatemachineexporter.analysis.service;

import click.kamil.springstatemachineexporter.analysis.model.CallChain;
import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
import click.kamil.springstatemachineexporter.analysis.spring.InjectionPointAnalyzer;
import click.kamil.springstatemachineexporter.analysis.spring.SpringBeanRegistry;
import click.kamil.springstatemachineexporter.analysis.spring.SpringContextScanner;
import click.kamil.springstatemachineexporter.analysis.spring.SpringDependencyResolver;
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Set;

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

class ComplexMultiModuleCancelJmsTest {

    private CodebaseContext context;
    private JdtCallGraphEngine engine;

    @BeforeEach
    void setUp() throws IOException {
        Path projectRoot = Path.of("../state_machines/complex_multi_module_sm").toAbsolutePath().normalize();

        context = new CodebaseContext();
        context.setProjectRoot(projectRoot);
        context.setSourcepath(List.of(
                projectRoot.resolve("domain/src/main/java").toString(),
                projectRoot.resolve("service/src/main/java").toString(),
                projectRoot.resolve("web/src/main/java").toString()));
        context.setClasspath(ToolingClasspath.currentJvmJarEntries());
        context.setResolveBindings(true);
        context.scan(Set.of(projectRoot), Collections.emptySet());

        SpringBeanRegistry registry = new SpringBeanRegistry();
        SpringContextScanner scanner = new SpringContextScanner(registry);
        for (var cu : context.getCompilationUnits()) {
            cu.accept(scanner);
        }
        InjectionPointAnalyzer injectionAnalyzer = new InjectionPointAnalyzer(new SpringDependencyResolver(registry));
        engine = new JdtCallGraphEngine(context, injectionAnalyzer);
    }

    @Test
    void shouldResolveCancelEventFromJmsSupplierLambda() {
        EntryPoint entryPoint = EntryPoint.builder()
                .className("click.kamil.web.JmsOrderListener")
                .methodName("receiveCancelCommand")
                .build();

        TriggerPoint trigger = TriggerPoint.builder()
                .className("click.kamil.service.StateMachineServiceImpl")
                .methodName("sendMessageWithProvider")
                .event("eventProvider")
                .build();

        List<CallChain> chains = engine.findChains(List.of(entryPoint), List.of(trigger));
        assertThat(chains).hasSize(1);
        assertThat(chains.get(0).getTriggerPoint().getPolymorphicEvents())
                .contains("OrderEvent.CANCEL");
    }
}
