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 org.junit.jupiter.api.io.TempDir;

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

class EventIdSwitchProbeTest {
    @Test
    void probePoly(@TempDir Path tempDir) throws Exception {
        String source = """
                package com.example;
                public class LogisticsController {
                    private LogisticsService service;
                    public void handle(String event) {
                        service.process(event);
                    }
                }
                abstract class AbstractOrderService {
                    public void process(String event) {
                        String resolved = assertSupportedOrderEvent(event);
                        sendEvent(resolved);
                    }
                    protected abstract String assertSupportedOrderEvent(String event);
                    public void sendEvent(String ev) {}
                }
                class LogisticsService extends AbstractOrderService {
                    @Override
                    protected String assertSupportedOrderEvent(String event) {
                        return LogisticsEvent.valueOf(event).name();
                    }
                }
                class ComputerStoreService extends AbstractOrderService {
                    @Override
                    protected String assertSupportedOrderEvent(String event) {
                        return ComputerEvent.valueOf(event).name();
                    }
                }
                enum LogisticsEvent { DELIVERED, RETURNED }
                enum ComputerEvent { SHIPPED, REFUNDED }
                """;
        Files.writeString(tempDir.resolve("OrderConfig.java"), source);
        CodebaseContext context = new CodebaseContext();
        context.setResolveBindings(true);
        context.scan(tempDir);
        HeuristicCallGraphEngine builder = new HeuristicCallGraphEngine(context);
        EntryPoint entryPoint = EntryPoint.builder()
                .className("com.example.LogisticsController")
                .methodName("handle")
                .build();
        TriggerPoint trigger = TriggerPoint.builder()
                .className("com.example.AbstractOrderService")
                .methodName("sendEvent")
                .event("ev")
                .build();
        List<CallChain> chains = builder.findChains(List.of(entryPoint), List.of(trigger));
        System.out.println("CHAINS=" + chains.size());
        for (CallChain c : chains) {
            System.out.println("CHAIN=" + c.getMethodChain());
            System.out.println("EVENT=" + c.getTriggerPoint().getEvent());
            System.out.println("POLY=" + c.getTriggerPoint().getPolymorphicEvents());
            System.out.println("CONSTRAINT=" + c.getTriggerPoint().getConstraint());
        }
    }
}
