package cn.learningpad.oraltrainer.sdk

import android.net.Uri
import javax.net.ssl.SSLException

/**
 * Runs one blocking request against [baseUrl]. When [OralTrainerSdkConfig.allowHttpFallback]
 * is enabled and the HTTPS attempt fails with a TLS error (broken certificates or
 * misconfigured TLS termination at the gateway), retries the same request over plain HTTP.
 * This is intended for private deployments; production should fix the TLS edge instead.
 */
internal class HttpFallback private constructor(
    private val allowFallback: Boolean,
) {
    fun <T> execute(baseUrl: String, block: (String) -> T): T {
        try {
            return block(baseUrl)
        } catch (error: Throwable) {
            if (!allowFallback || !isTlsFailure(error)) {
                throw error
            }
            val uri = Uri.parse(baseUrl)
            if (uri.scheme != "https") {
                throw error
            }
            val httpUrl = uri.buildUpon().scheme("http").build().toString()
            return block(httpUrl)
        }
    }

    private fun isTlsFailure(error: Throwable): Boolean {
        var current: Throwable? = error
        while (current != null) {
            val message = current.message.orEmpty()
            if (current is SSLException || message.contains("SSL", ignoreCase = true)) {
                return true
            }
            current = current.cause
        }
        return false
    }

    companion object {
        fun forConfig(config: OralTrainerSdkConfig): HttpFallback {
            return HttpFallback(config.allowHttpFallback)
        }
    }
}
