package xyz.cottongin.radio247.audio

import okhttp3.OkHttpClient
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
import java.io.InputStream
import java.time.Duration

class ConnectionFailed(message: String, cause: Throwable? = null) : Exception(message, cause)

data class StreamInfo(
    val bitrate: Int?,
    val ssl: Boolean,
    val contentType: String?,
    val sampleRate: Int? = null,
    val channelCount: Int? = null
)

class StreamConnection(private val url: String) {
    private val client = OkHttpClient.Builder()
        .protocols(listOf(Protocol.HTTP_1_1))
        .readTimeout(Duration.ofSeconds(30))
        .build()

    var metaint: Int? = null
        private set
    var inputStream: InputStream? = null
        private set
    var streamInfo: StreamInfo? = null
        private set
    private var response: Response? = null

    fun open() {
        val request = Request.Builder()
            .url(url)
            .header("Icy-MetaData", "1")
            .header("User-Agent", "Radio247/1.0")
            .build()

        try {
            val resp = client.newCall(request).execute()
            if (!resp.isSuccessful) {
                resp.close()
                throw ConnectionFailed("HTTP ${resp.code}")
            }
            response = resp
            metaint = resp.header("icy-metaint")?.toIntOrNull()
            streamInfo = StreamInfo(
                bitrate = resp.header("icy-br")?.toIntOrNull(),
                ssl = url.startsWith("https", ignoreCase = true),
                contentType = resp.header("Content-Type")
            )
            inputStream = resp.body?.byteStream()
                ?: throw ConnectionFailed("Empty response body")
        } catch (e: IOException) {
            throw ConnectionFailed("Network error", e)
        }
    }

    fun close() {
        try {
            inputStream?.close()
        } catch (_: IOException) {}
        try {
            response?.close()
        } catch (_: IOException) {}
        response = null
        inputStream = null
        metaint = null
        streamInfo = null
    }
}
