package ca.ksamad.encore.mpd

/**
 * Pure, connection-independent helpers for speaking the MPD text protocol: argument quoting and
 * command-string assembly. Kept separate from [MpdConnection] so it can be unit-tested without any
 * I/O.
 */
object MpdProtocol {
    /** Every server greeting starts with this, followed by the protocol version. */
    const val GREETING_PREFIX = "OK MPD "

    /** Success terminator for a command's response. */
    const val OK = "OK"

    /** Per-command terminator inside a `command_list_ok_begin` list. */
    const val LIST_OK = "list_OK"

    /**
     * Quote a single command argument. MPD's tokenizer treats a bare token as ending at the next
     * whitespace, so any argument is wrapped in double quotes with embedded `"` and `\`
     * backslash-escaped. Always quoting (even numbers and empty strings) is accepted by the server
     * and keeps callers from having to reason about which values are "safe".
     */
    fun quote(arg: String): String {
        val sb = StringBuilder(arg.length + 2)
        sb.append('"')
        for (c in arg) {
            if (c == '"' || c == '\\') sb.append('\\')
            sb.append(c)
        }
        sb.append('"')
        return sb.toString()
    }

    /**
     * Assemble a full command line (without the trailing newline) from a command name and its
     * arguments. The name is emitted verbatim; every argument is [quote]d.
     */
    fun command(
        name: String,
        vararg args: String,
    ): String {
        if (args.isEmpty()) return name
        return buildString {
            append(name)
            for (a in args) {
                append(' ')
                append(quote(a))
            }
        }
    }
}
