package com.tencent.qian.webview.prewarm

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.tencent.qian.webview.TencentQianWebViewPrewarmer
import com.tencent.qian.webview.model.PrewarmConfig
import com.tencent.qian.webview.model.PrewarmEnvironment
import com.tencent.qian.webview.model.PrewarmLevel
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith

/**
 * 预热纯逻辑单测：去重单调性、version 重置、环境映射、错配反查、配置默认值。
 * 对应 spec.md webview-prewarm 的多条 Scenario。
 */
@RunWith(AndroidJUnit4::class)
class PrewarmTest {

    // ────────── PrewarmDedup ──────────

    @Test fun dedup_minimal_runsOnce() {
        val d = PrewarmDedup()
        assertTrue(d.shouldRun(PrewarmLevel.MINIMAL, ""))
        d.markDone(PrewarmLevel.MINIMAL, "")
        assertFalse(d.shouldRun(PrewarmLevel.MINIMAL, ""))
    }

    @Test fun dedup_sameLevel_isDeduped() {
        val d = PrewarmDedup()
        assertTrue(d.shouldRun(PrewarmLevel.LIGHT, "single-sign"))
        d.markDone(PrewarmLevel.LIGHT, "single-sign")
        assertFalse(d.shouldRun(PrewarmLevel.LIGHT, "single-sign"))
    }

    @Test fun dedup_upgrade_runsIncrement() {
        val d = PrewarmDedup()
        d.markDone(PrewarmLevel.LIGHT, "single-sign")
        assertTrue(d.shouldRun(PrewarmLevel.HEAVY, "single-sign"))
        d.markDone(PrewarmLevel.HEAVY, "single-sign")
        assertFalse(d.shouldRun(PrewarmLevel.HEAVY, "single-sign"))
    }

    @Test fun dedup_downgrade_isIgnored() {
        val d = PrewarmDedup()
        d.markDone(PrewarmLevel.HEAVY, "single-sign")
        assertFalse(d.shouldRun(PrewarmLevel.LIGHT, "single-sign"))
    }

    @Test fun dedup_differentBizType_isIndependent() {
        val d = PrewarmDedup()
        d.markDone(PrewarmLevel.HEAVY, "single-sign")
        assertTrue(d.shouldRun(PrewarmLevel.LIGHT, "batch-sign"))
    }

    @Test fun dedup_reset_clearsAll() {
        val d = PrewarmDedup()
        d.markDone(PrewarmLevel.HEAVY, "single-sign")
        d.markDone(PrewarmLevel.MINIMAL, "")
        d.reset()
        assertTrue(d.shouldRun(PrewarmLevel.HEAVY, "single-sign"))
        assertTrue(d.shouldRun(PrewarmLevel.MINIMAL, ""))
    }

    // 档位增量补做：任意档执行后 DNS 已做过 → 后续 MINIMAL 应 no-op。
    @Test fun dedup_directLight_marksMinimalDone() {
        val d = PrewarmDedup()
        d.markDone(PrewarmLevel.LIGHT, "single-sign")
        assertFalse(d.shouldRun(PrewarmLevel.MINIMAL, ""))
    }

    @Test fun dedup_directHeavy_marksMinimalDone() {
        val d = PrewarmDedup()
        d.markDone(PrewarmLevel.HEAVY, "single-sign")
        assertFalse(d.shouldRun(PrewarmLevel.MINIMAL, ""))
    }

    // ────────── 环境映射 ──────────

    @Test fun manifestUrl_mapping() {
        assertEquals(
            "https://res.ess.tencent.cn/cdn/h5-std/warmup-manifest.json",
            PrewarmEnvironment.manifestUrlOf(PrewarmEnvironment.PROD)
        )
        assertEquals(
            "https://res.ess.tencent.cn/cdn/h5-std-beta/warmup-manifest.json",
            PrewarmEnvironment.manifestUrlOf(PrewarmEnvironment.BETA)
        )
        assertEquals(
            "https://res.ess.tencent.cn/cdn/h5-std-dev/warmup-manifest.json",
            PrewarmEnvironment.manifestUrlOf(PrewarmEnvironment.TEST)
        )
    }

    // ────────── 错配反查 ──────────

    @Test fun environmentOfUrl_known() {
        assertEquals(PrewarmEnvironment.PROD, PrewarmEnvironment.environmentOfUrl("https://quick.qian.tencent.com/sign"))
        assertEquals(PrewarmEnvironment.BETA, PrewarmEnvironment.environmentOfUrl("https://quick.beta.qian.tencent.cn/x"))
        assertEquals(PrewarmEnvironment.TEST, PrewarmEnvironment.environmentOfUrl("https://quick.test.qian.tencent.cn/x"))
    }

    @Test fun environmentOfUrl_nonQuickDomain_isNull() {
        // 非 quick 域名 → null → open() 不告警
        assertNull(PrewarmEnvironment.environmentOfUrl("https://sign.customer.com/flow"))
        assertNull(PrewarmEnvironment.environmentOfUrl(null))
    }

    // ────────── manifest 解析 ──────────

    @Test fun manifest_parse_extractsBizTypes() {
        val json = """
            {"version":"1.0","hosts":["https://quick.qian.tencent.com"],
             "bizTypes":{"single-sign":{"warmupUrl":"https://quick.qian.tencent.com/warmup.html?bizType=single-sign",
             "assets":["https://res/a.js","https://res/b.css"]}}}
        """.trimIndent()
        val m = WarmupManifest.parse(json)
        assertNotNull(m)
        assertEquals("1.0", m!!.version)
        assertEquals(1, m.hosts.size)
        assertEquals(2, m.bizTypes["single-sign"]!!.assets.size)
    }

    @Test fun manifest_parse_invalidReturnsNull() {
        assertNull(WarmupManifest.parse("not-json"))
    }

    // ────────── 配置默认值 ──────────

    @Test fun config_defaults() {
        val c = PrewarmConfig.DEFAULT
        assertEquals(PrewarmEnvironment.PROD, c.environment)
        assertNull(c.manifestUrl)
        assertEquals(1, c.poolSize)
        assertTrue(c.enablePool)
        assertNull(c.preferredLanguage)
        // UA 字段默认值（与 TencentQianWebViewConfig 对齐）
        assertTrue(c.injectUserAgent)
        assertEquals("", c.userAgentExtra)
    }

    // ────────── 语言偏好 appendLang（L4 转发） ──────────

    @Test fun appendLang_withExistingQuery_usesAmpersand() {
        assertEquals(
            "https://quick.qian.tencent.com/warmup.html?bizType=single-sign&lang=en-US",
            TencentQianWebViewPrewarmer.appendLang(
                "https://quick.qian.tencent.com/warmup.html?bizType=single-sign", "en-US"
            )
        )
    }

    @Test fun appendLang_withoutQuery_usesQuestionMark() {
        assertEquals(
            "https://quick.qian.tencent.com/warmup.html?lang=zh-CN",
            TencentQianWebViewPrewarmer.appendLang("https://quick.qian.tencent.com/warmup.html", "zh-CN")
        )
    }

    @Test fun appendLang_emptyOrNull_returnsUrlUnchanged() {
        val url = "https://quick.qian.tencent.com/warmup.html?bizType=x"
        assertEquals(url, TencentQianWebViewPrewarmer.appendLang(url, null))
        assertEquals(url, TencentQianWebViewPrewarmer.appendLang(url, ""))
    }
}
