package click.kamil.springstatemachineexporter.analysis;

import click.kamil.springstatemachineexporter.analysis.resolver.ConstantResolver;
import click.kamil.springstatemachineexporter.analysis.resolver.PropertyResolver;
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.IOException;
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;

public class AnalysisFoundationTest {

    @Test
    void testPropertyResolver(@TempDir Path tempDir) throws IOException {
        Files.writeString(tempDir.resolve("application.properties"), "app.event=SUBMIT\napp.path=/api/v1");
        
        PropertyResolver resolver = new PropertyResolver();
        Map<String, String> props = resolver.resolveProperties(tempDir);
        
        assertThat(props).containsEntry("app.event", "SUBMIT");
        assertThat(props).containsEntry("app.path", "/api/v1");
    }

    @Test
    void testConstantResolverManualFallback(@TempDir Path tempDir) throws IOException {
        // Create a class with a constant
        Path constDir = tempDir.resolve("com/example");
        Files.createDirectories(constDir);
        Files.writeString(constDir.resolve("Events.java"), 
            "package com.example;\n" +
            "public class Events {\n" +
            "    public static final String SUBMIT = \"SUBMIT_EVENT\";\n" +
            "}");

        // Create a class that uses the constant
        Files.writeString(constDir.resolve("Usage.java"), 
            "package com.example;\n" +
            "public class Usage {\n" +
            "    String e = Events.SUBMIT;\n" +
            "}");

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

        TypeDeclaration usageTd = context.getTypeDeclaration("com.example.Usage");
        FieldDeclaration field = usageTd.getFields()[0];
        VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0);
        Expression initializer = fragment.getInitializer();

        ConstantResolver resolver = new ConstantResolver();
        String value = resolver.resolve(initializer, context);

        assertThat(value).isEqualTo("SUBMIT_EVENT");
    }

    @Test
    void testPropertyResolverWithProfiles(@TempDir Path tempDir) throws IOException {
        Files.writeString(tempDir.resolve("application.properties"), "app.event=BASE");
        Files.writeString(tempDir.resolve("application-prod.properties"), "app.event=PROD");
        
        PropertyResolver resolver = new PropertyResolver();
        
        // 1. Base only
        Map<String, String> baseProps = resolver.resolveProperties(tempDir);
        assertThat(baseProps).containsEntry("app.event", "BASE");

        // 2. With prod profile
        resolver.setActiveProfiles(List.of("prod"));
        Map<String, String> prodProps = resolver.resolveProperties(tempDir);
        assertThat(prodProps).containsEntry("app.event", "PROD");
    }
}
