package ca.ksamad.encore.mpd

import ca.ksamad.encore.mpd.model.MpdSong
import ca.ksamad.encore.mpd.model.MpdStatistics
import ca.ksamad.encore.mpd.model.MpdStatus
import org.junit.Assert.assertNotNull
import org.junit.Assume.assumeTrue
import org.junit.Test

/**
 * A *live* smoke test against a real MPD server. It is skipped unless `MPD_HOST` is set, so the
 * ordinary (and Nix) build never touches the network:
 * ```
 * MPD_HOST=192.168.1.50 MPD_PORT=6600 [MPD_PASSWORD=secret] \
 *   ./gradlew testDebugUnitTest --tests '*MpdServerIntegrationTest' --rerun-tasks
 * ```
 *
 * It connects, runs `status` / `currentsong` / `stats`, and prints the parsed models so you can
 * eyeball that the protocol layer really talks to your server.
 */
class MpdServerIntegrationTest {
    private val host = System.getenv("MPD_HOST")
    private val port = System.getenv("MPD_PORT")?.toIntOrNull() ?: MpdConnection.DEFAULT_PORT
    private val password = System.getenv("MPD_PASSWORD")

    @Test
    fun connectsAndReadsLiveState() {
        assumeTrue("set MPD_HOST to run the live MPD smoke test", host != null)
        val host = host!!

        println("=== MPD integration smoke test: $host:$port ===")
        MpdConnection.connect(host, port, readTimeoutMs = 5_000).use { conn ->
            println("greeting: protocol version ${conn.protocolVersion}")
            assertNotNull(conn.protocolVersion)

            if (password != null) {
                conn.execute(MpdCommands.password(password))
                println("authenticated with password")
            }

            val status = MpdStatus.from(conn.execute(MpdCommands.status()).toMap())
            println("status  : $status")

            val song = MpdSong.from(conn.execute(MpdCommands.currentSong()).toMap())
            println(
                "current : ${song?.let { "${it.artist} — ${it.title} (${it.uri})" } ?: "<nothing playing>"}"
            )

            val stats = MpdStatistics.from(conn.execute(MpdCommands.stats()).toMap())
            println(
                "stats   : ${stats.songs} songs, ${stats.albums} albums, ${stats.artists} artists"
            )

            // Prove the raw commands list works too — a good connectivity sanity check.
            val commands = conn.execute(MpdProtocol.command("commands")).getAll("command")
            println("server exposes ${commands.size} commands")
        }
        println("=== OK ===")
    }
}
