package com.correx.apps.server.config

import com.correx.core.config.ConfigHolder
import com.correx.core.config.ConfigLoader
import com.correx.core.config.CorrexConfig
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import java.nio.file.Files
import java.nio.file.Path
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue

class ConfigServiceTest {

    @Test
    fun `apply persists, swaps the holder, and rebuilds`(@TempDir dir: Path) {
        val path = dir.resolve("config.toml")
        val holder = ConfigHolder(CorrexConfig())
        var rebuilt: CorrexConfig? = null
        val svc = ConfigService(holder, path) { rebuilt = it }

        val res = svc.apply(mapOf("project.enabled" to "true", "server.port" to "9000"))

        assertTrue(res is ConfigUpdateResult.Ok)
        assertTrue(holder.get().project.enabled)
        assertEquals(9000, holder.get().server.port)
        assertEquals(holder.get(), rebuilt)
        // Persisted and reloadable to the same config.
        assertEquals(holder.get(), ConfigLoader.loadFrom(path))
        assertTrue("server.port" in (res as ConfigUpdateResult.Ok).restartRequired)
        assertFalse("project.enabled" in res.restartRequired)
    }

    @Test
    fun `invalid patch does not persist or rebuild`(@TempDir dir: Path) {
        val path = dir.resolve("config.toml")
        val holder = ConfigHolder(CorrexConfig())
        var rebuilt = false
        val svc = ConfigService(holder, path) { rebuilt = true }

        val res = svc.apply(mapOf("tui.session_list_limit" to "abc"))

        assertTrue(res is ConfigUpdateResult.Error)
        assertFalse(rebuilt)
        assertFalse(Files.exists(path))
        assertEquals(5, holder.get().tui.sessionListLimit) // unchanged default
    }

    @Test
    fun `snapshot reflects the current held config`(@TempDir dir: Path) {
        val holder = ConfigHolder(CorrexConfig())
        val svc = ConfigService(holder, dir.resolve("config.toml")) {}
        svc.apply(mapOf("tui.session_list_limit" to "11"))
        val snap = svc.snapshot().associate { (f, v) -> f.key to v }
        assertEquals("11", snap["tui.session_list_limit"])
    }
}
