package com.fabledsword.minstrel.player.output.upnp

import okhttp3.HttpUrl

/**
 * RenderingControl service wrapper for hardware-volume routing while a
 * UPnP route is active. GetVolume seeds an in-memory cache; SetVolume
 * is invoked by NowPlayingScreen's volume-key interceptor. Clamps to
 * the UPnP-standard 0..100 range.
 */
class RenderingControlClient(
    private val soap: SoapClient,
    private val controlUrl: HttpUrl,
) {
    suspend fun getVolume(channel: String = "Master"): Int {
        val args = soap.call(
            controlUrl = controlUrl,
            serviceType = SERVICE_TYPE,
            action = "GetVolume",
            args = mapOf("InstanceID" to "0", "Channel" to channel),
        )
        return args["CurrentVolume"]?.toIntOrNull() ?: 0
    }

    suspend fun setVolume(volume: Int, channel: String = "Master") {
        val clamped = volume.coerceIn(VOLUME_MIN, VOLUME_MAX)
        soap.call(
            controlUrl = controlUrl,
            serviceType = SERVICE_TYPE,
            action = "SetVolume",
            args = mapOf(
                "InstanceID" to "0",
                "Channel" to channel,
                "DesiredVolume" to clamped.toString(),
            ),
        )
    }

    private companion object {
        const val SERVICE_TYPE = "urn:schemas-upnp-org:service:RenderingControl:1"
        const val VOLUME_MIN = 0
        const val VOLUME_MAX = 100
    }
}
