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

import com.fabledsword.minstrel.player.output.upnp.SoapClient
import okhttp3.HttpUrl
import timber.log.Timber

/**
 * Sonos's proprietary ZoneGroupTopology service. Same SOAP shape as a
 * standard UPnP service, exposed on port 1400 at
 * /ZoneGroupTopology/Control. GetZoneGroupState returns the full
 * network topology as one XML doc wrapped inside a SOAP arg.
 */
class ZoneGroupTopologyClient(
    private val soap: SoapClient,
    private val controlUrl: HttpUrl,
) {
    suspend fun getZoneGroupState(): List<SonosZoneGroup> {
        val args = soap.call(
            controlUrl = controlUrl,
            serviceType = SERVICE_TYPE,
            action = "GetZoneGroupState",
            args = emptyMap(),
        )
        val inner = args["ZoneGroupState"].orEmpty()
        Timber.w(
            "ZGT extracted ZoneGroupState (%d chars): %s",
            inner.length,
            inner.take(ZGT_LOG_TRUNCATE_CHARS),
        )
        return SonosTopology.parse(inner)
    }

    private companion object {
        const val SERVICE_TYPE = "urn:schemas-upnp-org:service:ZoneGroupTopology:1"
        const val ZGT_LOG_TRUNCATE_CHARS = 2048
    }
}
