import XCTest
@testable import TencentQianWebViewSDK

/// 预热纯逻辑单测：去重单调性、version 重置、环境映射、错配反查、Cache-Control 解析、配置默认值。
/// 与 Android / HarmonyOS `PrewarmTest` 同一组用例。
final class PrewarmTests: XCTestCase {

    // MARK: - PrewarmDedup

    func test_dedup_minimal_runsOnce() {
        let d = PrewarmDedup()
        XCTAssertTrue(d.shouldRun(.minimal, bizType: ""))
        d.markDone(.minimal, bizType: "")
        XCTAssertFalse(d.shouldRun(.minimal, bizType: ""))
    }

    func test_dedup_sameLevel_isDeduped() {
        let d = PrewarmDedup()
        XCTAssertTrue(d.shouldRun(.light, bizType: "single-sign"))
        d.markDone(.light, bizType: "single-sign")
        XCTAssertFalse(d.shouldRun(.light, bizType: "single-sign"))
    }

    func test_dedup_upgrade_runsIncrement() {
        let d = PrewarmDedup()
        d.markDone(.light, bizType: "single-sign")
        XCTAssertTrue(d.shouldRun(.heavy, bizType: "single-sign"))
        d.markDone(.heavy, bizType: "single-sign")
        XCTAssertFalse(d.shouldRun(.heavy, bizType: "single-sign"))
    }

    func test_dedup_downgrade_isIgnored() {
        let d = PrewarmDedup()
        d.markDone(.heavy, bizType: "single-sign")
        XCTAssertFalse(d.shouldRun(.light, bizType: "single-sign"))
    }

    func test_dedup_differentBizType_isIndependent() {
        let d = PrewarmDedup()
        d.markDone(.heavy, bizType: "single-sign")
        XCTAssertTrue(d.shouldRun(.light, bizType: "batch-sign"))
    }

    func test_dedup_reset_clearsAll() {
        let d = PrewarmDedup()
        d.markDone(.heavy, bizType: "single-sign")
        d.markDone(.minimal, bizType: "")
        d.reset()
        XCTAssertTrue(d.shouldRun(.heavy, bizType: "single-sign"))
        XCTAssertTrue(d.shouldRun(.minimal, bizType: ""))
    }

    // 档位增量补做：任意档执行后 DNS 已做过 → 后续 .minimal 应 no-op。
    func test_dedup_directLight_marksMinimalDone() {
        let d = PrewarmDedup()
        d.markDone(.light, bizType: "single-sign")
        XCTAssertFalse(d.shouldRun(.minimal, bizType: ""))
    }

    func test_dedup_directHeavy_marksMinimalDone() {
        let d = PrewarmDedup()
        d.markDone(.heavy, bizType: "single-sign")
        XCTAssertFalse(d.shouldRun(.minimal, bizType: ""))
    }

    // MARK: - 环境映射

    func test_manifestUrl_mapping() {
        XCTAssertEqual(PrewarmEnvironment.prod.manifestUrl,
                       "https://res.ess.tencent.cn/cdn/h5-std/warmup-manifest.json")
        XCTAssertEqual(PrewarmEnvironment.beta.manifestUrl,
                       "https://res.ess.tencent.cn/cdn/h5-std-beta/warmup-manifest.json")
        XCTAssertEqual(PrewarmEnvironment.test.manifestUrl,
                       "https://res.ess.tencent.cn/cdn/h5-std-dev/warmup-manifest.json")
    }

    // MARK: - 错配反查

    func test_environmentOfUrl_known() {
        XCTAssertEqual(PrewarmEnvironment.of(url: "https://quick.qian.tencent.com/sign"), .prod)
        XCTAssertEqual(PrewarmEnvironment.of(url: "https://quick.beta.qian.tencent.cn/x"), .beta)
        XCTAssertEqual(PrewarmEnvironment.of(url: "https://quick.test.qian.tencent.cn/x"), .test)
    }

    func test_environmentOfUrl_nonQuickDomain_isNil() {
        // 非 quick 域名 → nil → open() 不告警
        XCTAssertNil(PrewarmEnvironment.of(url: "https://sign.customer.com/flow"))
        XCTAssertNil(PrewarmEnvironment.of(url: nil))
    }

    // MARK: - Cache-Control 解析

    func test_parseMaxAge() {
        XCTAssertEqual(ManifestStore.parseMaxAge("max-age=300"), 300)
        XCTAssertEqual(ManifestStore.parseMaxAge("public, max-age=120, immutable"), 120)
        XCTAssertNil(ManifestStore.parseMaxAge("no-cache"))
        XCTAssertNil(ManifestStore.parseMaxAge(nil))
    }

    // MARK: - manifest 解析

    func test_manifest_parse() {
        let 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"]}}}
        """
        let m = WarmupManifest.parse(Data(json.utf8))
        XCTAssertNotNil(m)
        XCTAssertEqual(m?.version, "1.0")
        XCTAssertEqual(m?.bizTypes["single-sign"]?.assets.count, 2)
    }

    func test_manifest_parse_invalidReturnsNil() {
        XCTAssertNil(WarmupManifest.parse(Data("not-json".utf8)))
    }

    // MARK: - 配置默认值

    func test_config_defaults() {
        let c = PrewarmConfig.default
        XCTAssertEqual(c.environment, .prod)
        XCTAssertNil(c.manifestUrl)
        XCTAssertEqual(c.poolSize, 1)
        XCTAssertTrue(c.enablePool)
        XCTAssertNil(c.preferredLanguage)
        // UA 字段默认值（与 TencentQianWebViewConfig 对齐）
        XCTAssertTrue(c.injectUserAgent)
        XCTAssertEqual(c.userAgentExtra, "")
    }

    // MARK: - 语言偏好 appendLang（L4 转发）

    func test_appendLang_withExistingQuery_usesAmpersand() {
        XCTAssertEqual(
            TencentQianWebViewPrewarmer.appendLang(
                "https://quick.qian.tencent.com/warmup.html?bizType=single-sign", "en-US"),
            "https://quick.qian.tencent.com/warmup.html?bizType=single-sign&lang=en-US")
    }

    func test_appendLang_withoutQuery_usesQuestionMark() {
        XCTAssertEqual(
            TencentQianWebViewPrewarmer.appendLang("https://quick.qian.tencent.com/warmup.html", "zh-CN"),
            "https://quick.qian.tencent.com/warmup.html?lang=zh-CN")
    }

    func test_appendLang_emptyOrNil_returnsUrlUnchanged() {
        let url = "https://quick.qian.tencent.com/warmup.html?bizType=x"
        XCTAssertEqual(TencentQianWebViewPrewarmer.appendLang(url, nil), url)
        XCTAssertEqual(TencentQianWebViewPrewarmer.appendLang(url, ""), url)
    }
}
