package click.kamil.springstatemachineexporter.analysis.resolver;

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.Set;

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

class SiblingDependencyResolverTest {

    @Test
    void shouldResolveGradleSiblingsTransitively(@TempDir Path tempDir) throws IOException {
        // Create root project
        Path rootDir = tempDir.resolve("my-root-project");
        Files.createDirectories(rootDir);
        Files.writeString(rootDir.resolve("settings.gradle"), "include 'module-a', 'module-b', 'module-c'");

        // Create module A (depends on B)
        Path moduleA = rootDir.resolve("module-a");
        Files.createDirectories(moduleA);
        Files.writeString(moduleA.resolve("build.gradle"), "dependencies { implementation project(':module-b') }");

        // Create module B (depends on C)
        Path moduleB = rootDir.resolve("module-b");
        Files.createDirectories(moduleB);
        Files.writeString(moduleB.resolve("build.gradle"), "dependencies { implementation project(':module-c') }");

        // Create module C (no deps)
        Path moduleC = rootDir.resolve("module-c");
        Files.createDirectories(moduleC);
        Files.writeString(moduleC.resolve("build.gradle"), "");

        SiblingDependencyResolver resolver = new SiblingDependencyResolver();
        
        // When we resolve from A, it should transitively find B and C
        Set<Path> siblings = resolver.resolveSiblings(moduleA);

        assertThat(siblings).containsExactlyInAnyOrder(moduleB.normalize(), moduleC.normalize());
    }

    @Test
    void shouldResolveMavenSiblingsTransitively(@TempDir Path tempDir) throws IOException {
        // Create root project
        Path rootDir = tempDir.resolve("my-maven-root");
        Files.createDirectories(rootDir);
        Files.writeString(rootDir.resolve("pom.xml"), "<project><groupId>com.acme</groupId><artifactId>root</artifactId></project>");
        // Create a dummy .git so findMavenRoot knows where to stop
        Files.createDirectories(rootDir.resolve(".git"));

        // Create module A (depends on B)
        Path moduleA = rootDir.resolve("module-a");
        Files.createDirectories(moduleA);
        Files.writeString(moduleA.resolve("pom.xml"), "<project><groupId>com.acme</groupId><artifactId>module-a</artifactId><dependencies><dependency><groupId>com.acme</groupId><artifactId>module-b</artifactId><version>1.0</version></dependency></dependencies></project>");

        // Create module B (depends on C)
        Path moduleB = rootDir.resolve("module-b");
        Files.createDirectories(moduleB);
        Files.writeString(moduleB.resolve("pom.xml"), "<project><groupId>com.acme</groupId><artifactId>module-b</artifactId><dependencies><dependency><groupId>com.acme</groupId><artifactId>module-c</artifactId><version>1.0</version></dependency></dependencies></project>");

        // Create module C (no deps)
        Path moduleC = rootDir.resolve("module-c");
        Files.createDirectories(moduleC);
        Files.writeString(moduleC.resolve("pom.xml"), "<project><groupId>com.acme</groupId><artifactId>module-c</artifactId></project>");

        SiblingDependencyResolver resolver = new SiblingDependencyResolver();
        
        // When we resolve from A, it should transitively find B and C and the parent rootDir
        Set<Path> siblings = resolver.resolveSiblings(moduleA);

        assertThat(siblings).containsExactlyInAnyOrder(moduleB.normalize(), moduleC.normalize(), rootDir.normalize());
    }

    @Test
    void shouldResolveMavenModulesFromAggregator(@TempDir Path tempDir) throws IOException {
        // Create root project
        Path rootDir = tempDir.resolve("my-aggregator-root");
        Files.createDirectories(rootDir);
        Files.writeString(rootDir.resolve("pom.xml"), "<project><groupId>com.acme</groupId><artifactId>root</artifactId><modules><module>service-x</module><module>service-y</module></modules></project>");
        Files.createDirectories(rootDir.resolve(".git"));

        // Create service X
        Path serviceX = rootDir.resolve("service-x");
        Files.createDirectories(serviceX);
        Files.writeString(serviceX.resolve("pom.xml"), "<project><artifactId>service-x</artifactId></project>");

        // Create service Y
        Path serviceY = rootDir.resolve("service-y");
        Files.createDirectories(serviceY);
        Files.writeString(serviceY.resolve("pom.xml"), "<project><artifactId>service-y</artifactId></project>");

        SiblingDependencyResolver resolver = new SiblingDependencyResolver();
        
        // Resolving from rootDir should pick up the <module> tags and resolve service-x and service-y
        Set<Path> siblings = resolver.resolveSiblings(rootDir);

        assertThat(siblings).containsExactlyInAnyOrder(serviceX.normalize(), serviceY.normalize());
    }
}
