package com.correx.infrastructure.tools.filesystem

import com.correx.core.events.events.ToolRequest
import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
import com.correx.core.events.types.ToolInvocationId
import com.correx.core.tools.contract.ToolResult
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.nio.file.Files
import java.util.*

class ListDirToolTest {

    private fun request(path: String? = null, recursive: Boolean? = null) = ToolRequest(
        invocationId = ToolInvocationId(UUID.randomUUID().toString()),
        sessionId = SessionId(UUID.randomUUID().toString()),
        stageId = StageId(UUID.randomUUID().toString()),
        toolName = "list_dir",
        parameters = buildMap {
            path?.let { put("path", it) }
            recursive?.let { put("recursive", it) }
        },
    )

    @Test
    fun `recursive listing prunes gitignored dirs and files`(): Unit = runBlocking {
        val root = Files.createTempDirectory("listdir")
        Files.writeString(root.resolve(".gitignore"), "node_modules\ndist\n*.log\n")
        Files.createDirectories(root.resolve("node_modules/pkg")).also { Files.writeString(it.resolve("x.js"), "x") }
        Files.createDirectories(root.resolve("dist")).also { Files.writeString(it.resolve("bundle.js"), "b") }
        Files.createDirectories(root.resolve("src")).also { Files.writeString(it.resolve("main.ts"), "m") }
        Files.writeString(root.resolve("debug.log"), "noise")
        Files.writeString(root.resolve("package.json"), "{}")

        val tool = ListDirTool(allowedPaths = setOf(root), workingDir = root)
        val out = (tool.execute(request()) as ToolResult.Success).output

        assertTrue(out.contains("src/main.ts"), out)
        assertTrue(out.contains("package.json"), out)
        assertFalse(out.contains("node_modules"), out)   // whole subtree pruned, never descended
        assertFalse(out.contains("dist"), out)
        assertFalse(out.contains("debug.log"), out)
    }

    @Test
    fun `non-recursive lists only immediate children`(): Unit = runBlocking {
        val root = Files.createTempDirectory("listdir")
        Files.createDirectories(root.resolve("src/deep")).also { Files.writeString(it.resolve("f.ts"), "f") }
        val tool = ListDirTool(allowedPaths = setOf(root), workingDir = root)
        val out = (tool.execute(request(recursive = false)) as ToolResult.Success).output
        assertTrue(out.contains("src/"), out)
        assertFalse(out.contains("deep"), out)
    }
}
