package com.correx.apps.server.memory

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.io.TempDir
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.createDirectories
import kotlin.io.path.writeText
import org.junit.jupiter.api.Test

class RepoMapIndexerTest {

    @Test
    fun `indexes source files with top-level symbols, ranks recent highest, prunes ignores`(@TempDir root: Path) {
        root.resolve("Old.kt").writeText("class Old\nfun helper() {}\n")
        Thread.sleep(10)
        root.resolve("New.kt").writeText("interface New\nobject Thing\n")

        // Pruned directory must not appear.
        root.resolve("build").createDirectories()
        root.resolve("build/Generated.kt").writeText("class Generated\n")

        // Non-source file must be ignored.
        root.resolve("README.md").writeText("# hi\n")

        val entries = RepoMapIndexer(maxDepth = 4, ignoreGlobs = listOf("build")).index(root)

        val paths = entries.map { it.path }
        assertTrue(paths.contains("New.kt"))
        assertTrue(paths.contains("Old.kt"))
        assertFalse(paths.any { it.contains("build") }, "ignored dir leaked: $paths")
        assertFalse(paths.contains("README.md"), "non-source file leaked")

        // Most-recently-modified ranks first.
        assertEquals("New.kt", entries.first().path)

        val newEntry = entries.first { it.path == "New.kt" }
        assertTrue(newEntry.symbols.containsAll(listOf("New", "Thing")))
        assertTrue(entries.first { it.path == "Old.kt" }.symbols.contains("Old"))
    }

    @Test
    fun `empty or missing root yields empty map`(@TempDir root: Path) {
        assertTrue(RepoMapIndexer().index(root).isEmpty())
        assertTrue(RepoMapIndexer().index(root.resolve("does-not-exist")).isEmpty())
    }

    @Test
    fun `maxDepth bounds recursion`(@TempDir root: Path) {
        root.resolve("a/b/c").createDirectories()
        root.resolve("Top.kt").writeText("class Top\n")
        root.resolve("a/b/c/Deep.kt").writeText("class Deep\n")

        val shallow = RepoMapIndexer(maxDepth = 1).index(root).map { it.path }
        assertTrue(shallow.contains("Top.kt"))
        assertFalse(shallow.any { it.contains("Deep") }, "depth cap breached: $shallow")
    }
}
