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.ast.common.CodebaseContext;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

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

public class OverloadedConstructorBugTest {

    @Test
    void shouldResolveEventThroughOverloadedConstructors() throws IOException {
        String source = """
                package com.example;

                public class MyController {
                    private StateMachine machine;
                    
                    public void process() {
                        // Creating command via 1-arg constructor
                        MyCommand command = new MyCommand(TransitionEnum.STATE_Z);
                        machine.fire(command.getEvent());
                    }
                }
                
                class MyCommand {
                    private final TransitionEnum event;
                    private final String metadata;
                    
                    // 1-arg constructor calls 2-arg constructor using this(...)
                    public MyCommand(TransitionEnum event) {
                        this(event, "default_metadata");
                    }
                    
                    // 2-arg constructor assigns the field
                    public MyCommand(TransitionEnum event, String metadata) {
                        this.event = event;
                        this.metadata = metadata;
                    }
                    
                    public TransitionEnum getEvent() {
                        return event;
                    }
                }
                
                class StateMachine {
                    public void fire(TransitionEnum event) {}
                }
                
                enum TransitionEnum { STATE_X, STATE_Y, STATE_Z }
                """;

        Path tempDir = Files.createTempDirectory("callgraph_test_constructor");
        Files.writeString(tempDir.resolve("Config.java"), source);

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

        HeuristicCallGraphEngine engine = new HeuristicCallGraphEngine(context);

        EntryPoint entryPoint = EntryPoint.builder()
                .className("com.example.MyController")
                .methodName("process")
                .build();

        TriggerPoint trigger = TriggerPoint.builder()
                .className("com.example.StateMachine")
                .methodName("fire")
                .event("event")
                .build();

        List<CallChain> chains = engine.findChains(List.of(entryPoint), List.of(trigger));
        assertThat(chains).hasSize(1);
        System.out.println("Poly events from overloaded constructor: " + chains.get(0).getTriggerPoint().getPolymorphicEvents());
        
        // It SHOULD resolve to STATE_Z by following the 'this(...)' call in the constructor
        assertThat(chains.get(0).getTriggerPoint().getPolymorphicEvents()).containsExactly("TransitionEnum.STATE_Z");
    }
}
