package click.kamil.springstatemachineexporter.analysis.resolver;

import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
import org.eclipse.jdt.core.dom.*;
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 static org.assertj.core.api.Assertions.assertThat;

public class StaticImportResolutionTest {

    @Test
    void testSingleStaticImport(@TempDir Path tempDir) throws IOException {
        Path dir = tempDir.resolve("com/example");
        Files.createDirectories(dir);
        Files.writeString(dir.resolve("Constants.java"),
            "package com.example;\n" +
            "public class Constants {\n" +
            "    public static final String A = \"/a\";\n" +
            "}");
        Files.writeString(dir.resolve("Usage.java"),
            "package com.example;\n" +
            "import static com.example.Constants.A;\n" +
            "public class Usage {\n" +
            "    String val = A;\n" +
            "}");

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

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

        ConstantResolver resolver = new ConstantResolver();
        String result = resolver.resolve(fragment.getInitializer(), context);

        assertThat(result).isEqualTo("/a");
    }

    @Test
    void testStarStaticImport(@TempDir Path tempDir) throws IOException {
        Path dir = tempDir.resolve("com/example");
        Files.createDirectories(dir);
        Files.writeString(dir.resolve("Constants.java"),
            "package com.example;\n" +
            "public class Constants {\n" +
            "    public static final String B = \"/b\";\n" +
            "}");
        Files.writeString(dir.resolve("Usage.java"),
            "package com.example;\n" +
            "import static com.example.Constants.*;\n" +
            "public class Usage {\n" +
            "    String val = B;\n" +
            "}");

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

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

        ConstantResolver resolver = new ConstantResolver();
        String result = resolver.resolve(fragment.getInitializer(), context);

        assertThat(result).isEqualTo("/b");
    }

    @Test
    void testPrecedenceLocalOverStaticImport(@TempDir Path tempDir) throws IOException {
        Path dir = tempDir.resolve("com/example");
        Files.createDirectories(dir);
        Files.writeString(dir.resolve("Constants.java"),
            "package com.example;\n" +
            "public class Constants {\n" +
            "    public static final String A = \"imported\";\n" +
            "}");
        Files.writeString(dir.resolve("Usage.java"),
            "package com.example;\n" +
            "import static com.example.Constants.A;\n" +
            "public class Usage {\n" +
            "    public static final String A = \"local\";\n" +
            "    String val = A;\n" +
            "}");

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

        TypeDeclaration td = context.getTypeDeclaration("com.example.Usage");
        FieldDeclaration field = td.getFields()[1]; // val
        VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0);

        ConstantResolver resolver = new ConstantResolver();
        String result = resolver.resolve(fragment.getInitializer(), context);

        assertThat(result).isEqualTo("local");
    }
}
