"""Test against fingerprint-scan.com and CreepJS.

Tests the specific headless detection signals flagged by the community:
- noTaskbar, noContentIndex, noContactsManager, noDownlinkMax
- Bot risk score (fingerprint-scan.com)
- Headless/stealth percentages (CreepJS)
- Full CreepJS signal breakdown (likeHeadless, headless, stealth)

Usage:
    python examples/fingerprint_scan_test.py
    python examples/fingerprint_scan_test.py --proxy http://10.50.96.5:8888
    python examples/fingerprint_scan_test.py --headless
"""

import sys
import time

from cloakbrowser import launch_context

HEADLESS = "--headless" in sys.argv
PROXY = None
for i, arg in enumerate(sys.argv):
    if arg == "--proxy" and i + 1 < len(sys.argv):
        PROXY = sys.argv[i + 1]


def test_fingerprint_scan(page):
    """fingerprint-scan.com — bot risk score + headless detection signals."""
    print("=== fingerprint-scan.com ===")
    page.goto("https://fingerprint-scan.com/", wait_until="domcontentloaded", timeout=30000)
    time.sleep(20)  # Castle.js needs time to compute score

    # Check bot risk score
    score = page.evaluate(
        'document.getElementById("fingerprintScore")?.textContent || "Score not rendered"'
    )
    print(f"Bot Risk Score: {score}")

    # Check headless detection signals
    apis = page.evaluate("""() => ({
        noTaskbar: screen.height === screen.availHeight,
        taskbarSize: screen.height - screen.availHeight,
        noContentIndex: typeof window.ContentIndex === "undefined",
        noContactsManager: !("contacts" in navigator),
        noDownlinkMax: !("downlinkMax" in (navigator.connection || {})),
        downlinkMax: navigator.connection?.downlinkMax ?? null,
        timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
        webdriver: navigator.webdriver,
        isPlaywright: "__pwInitScripts" in window || "__playwright__binding__" in window,
        webgpu: typeof navigator.gpu !== "undefined" ? "available" : "NOT_AVAILABLE",
        scrollbarWidth: (() => { const d = document.createElement("div"); d.style.cssText = "overflow:scroll;width:100px;height:100px;position:absolute;top:-999px"; document.body.appendChild(d); const w = d.offsetWidth - d.clientWidth; d.remove(); return w; })()
    })""")

    print("\nHeadless detection signals:")
    headless_fails = 0
    for k, v in apis.items():
        is_fail = k.startswith("no") and v is True
        if is_fail:
            headless_fails += 1
        flag = "FAIL" if is_fail else ""
        print(f"  {k}: {v}  {flag}")

    # Extract bot test results from page
    bot_tests = page.evaluate("""() => {
        const text = document.body.innerText;
        const tests = {};
        for (const key of ['WebDriver', 'Is Selenium Chrome', 'CDP Check', 'Is Playwright']) {
            const match = text.match(new RegExp(key + '\\\\s+(true|false)'));
            if (match) tests[key] = match[1];
        }
        return tests;
    }""")
    print("\nBot Detection Tests:")
    for k, v in bot_tests.items():
        status = "PASS" if v == "false" else "FAIL"
        print(f"  {k}: {v}  [{status}]")

    page.screenshot(path="/results/fingerprint-scan.png", full_page=True)
    print("\nScreenshot: /results/fingerprint-scan.png")

    return {
        "score": score,
        "headless_fails": headless_fails,
        "apis": apis,
        "bot_tests": bot_tests,
    }


def test_creepjs(page):
    """abrahamjuliot.github.io/creepjs — comprehensive fingerprint analysis."""
    print("\n=== CreepJS ===")
    page.goto(
        "https://abrahamjuliot.github.io/creepjs/", wait_until="domcontentloaded", timeout=30000
    )
    print("Waiting 30s for CreepJS analysis...")
    time.sleep(30)

    # Extract % scores from page text (matches test-infra/matrix_tests/group3_bot_detection.py)
    scores = page.evaluate("""() => {
        const text = document.body.innerText;
        const likeMatch = text.match(/(\\d+)%\\s*like headless/i);
        const headlessMatch = text.match(/(\\d+)%\\s*headless:/i);
        const stealthMatch = text.match(/(\\d+)%\\s*stealth:/i);
        return {
            likeHeadlessPct: likeMatch ? parseInt(likeMatch[1]) : null,
            headlessPct: headlessMatch ? parseInt(headlessMatch[1]) : null,
            stealthPct: stealthMatch ? parseInt(stealthMatch[1]) : null,
        };
    }""")

    print(f"\nScores:")
    print(f"  like-headless: {scores['likeHeadlessPct']}%  (target: <=30%)")
    print(f"  headless:      {scores['headlessPct']}%  (target: 0%)")
    print(f"  stealth:       {scores['stealthPct']}%  (target: 0%)")

    # Extract full signal breakdown from window.Fingerprint.headless (CreepJS internal object)
    signals = page.evaluate("""() => {
        try {
            const fp = window.Fingerprint;
            if (!fp || !fp.headless) return null;
            return {
                likeHeadless: fp.headless.likeHeadless || null,
                headless: fp.headless.headless || null,
                stealth: fp.headless.stealth || null,
            };
        } catch { return null; }
    }""")

    if signals:
        if signals.get("likeHeadless"):
            print("\nlikeHeadless signals:")
            fails = 0
            for k, v in signals["likeHeadless"].items():
                is_fail = v is True
                if is_fail:
                    fails += 1
                flag = " FAIL" if is_fail else ""
                print(f"  {k}: {v}{flag}")
            print(f"  ({fails} fails)")

        if signals.get("headless"):
            print("\nheadless signals:")
            for k, v in signals["headless"].items():
                flag = " FAIL" if v is True else ""
                print(f"  {k}: {v}{flag}")

        if signals.get("stealth"):
            print("\nstealth signals:")
            for k, v in signals["stealth"].items():
                flag = " FAIL" if v is True else ""
                print(f"  {k}: {v}{flag}")
    else:
        print("\n(window.Fingerprint.headless not available — signals not extracted)")

    # Extract platform estimate
    platform = page.evaluate("""() => {
        try {
            const fp = window.Fingerprint;
            if (!fp || !fp.platformEstimate) return null;
            return fp.platformEstimate;
        } catch { return null; }
    }""")
    if platform:
        print(f"\nPlatform estimate: {platform}")

    passed = (
        scores["headlessPct"] is not None
        and scores["headlessPct"] <= 30
        and scores["stealthPct"] is not None
        and scores["stealthPct"] <= 30
    )
    print(f"\nVerdict: {'PASS' if passed else 'FAIL'} (<=30% headless, <=30% stealth)")

    page.screenshot(path="/results/creepjs.png", full_page=True)
    print("Screenshot: /results/creepjs.png")

    return {**scores, "signals": signals, "platform": platform}


def main():
    print("=" * 60)
    print("CloakBrowser — Fingerprint & Headless Detection Tests")
    print("=" * 60)
    print(f"Mode: {'headless' if HEADLESS else 'headed'}")
    print(f"Proxy: {PROXY or 'none'}")
    print()

    print("Launching stealth browser...", flush=True)
    context = launch_context(
        headless=HEADLESS,
        proxy=PROXY,
        args=[
            "--fingerprint-screen-width=1920",
            "--fingerprint-screen-height=1080",
            "--fingerprint-timezone=Asia/Jerusalem",
        ],
    )
    page = context.new_page()

    try:
        fp_result = test_fingerprint_scan(page)
        creep_result = test_creepjs(page)
    finally:
        context.close()

    # Summary
    print("\n" + "=" * 60)
    print("SUMMARY")
    print("=" * 60)
    print(f"fingerprint-scan.com: {fp_result['score']}")
    print(f"  Headless signal fails: {fp_result['headless_fails']}")
    like = creep_result["likeHeadlessPct"]
    headless = creep_result["headlessPct"]
    stealth = creep_result["stealthPct"]
    print(f"CreepJS: like-headless={like}%, headless={headless}%, stealth={stealth}%")

    # Count CreepJS signal fails
    sigs = creep_result.get("signals")
    if sigs and sigs.get("likeHeadless"):
        fail_names = [k for k, v in sigs["likeHeadless"].items() if v is True]
        if fail_names:
            print(f"  likeHeadless fails: {', '.join(fail_names)}")
    print("=" * 60)

    return 0


if __name__ == "__main__":
    sys.exit(main())
