package com.correx.infrastructure.inference.llama.cpp

import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class SalvageToolCallsTest {

    @Test
    fun `recovers a tool call emitted as a JSON object in content`() {
        val args = """{\"path\":\"apps/server/src\"}"""
        val content = """{"id":"abc","function":{"name":"file_read","arguments":"$args"}}"""
        val calls = salvageToolCalls(content)
        assertEquals(1, calls.size)
        assertEquals("file_read", calls.first().function.name)
    }

    @Test
    fun `recovers a JSON array of tool calls`() {
        val one = """{"function":{"name":"file_read","arguments":"{}"}}"""
        val two = """{"function":{"name":"ls","arguments":"{}"}}"""
        val calls = salvageToolCalls("[$one,$two]")
        assertEquals(listOf("file_read", "ls"), calls.map { it.function.name })
    }

    @Test
    fun `recovers a truncated tool call with unterminated arguments string`() {
        // Exact shape from session 390983ae: missing closing quote on arguments + trailing braces.
        val content = """{"id":"rcu08","function":{"name":"file_read","arguments":"{\"path\":\"frontend/src/\"}}"""
        val calls = salvageToolCalls(content)
        assertEquals(1, calls.size)
        assertEquals("file_read", calls.first().function.name)
        assertEquals("""{"path":"frontend/src/"}""", calls.first().function.arguments)
    }

    @Test
    fun `leaves a real artifact JSON alone`() {
        val artifact = """{"summary":"add a web ui","requirements":["one","two"]}"""
        assertTrue(salvageToolCalls(artifact).isEmpty())
    }

    @Test
    fun `ignores empty, prose, and null content`() {
        assertTrue(salvageToolCalls(null).isEmpty())
        assertTrue(salvageToolCalls("   ").isEmpty())
        assertTrue(salvageToolCalls("Let me explore the frontend directory.").isEmpty())
    }
}
