"""
Empirical Adversarial Stress Test Suite for Milestone M4 (Challenger M4 1):
1. Zero-Heap Allocation & Zero GC Pressure:
   - 5,000 rapid player movements with updatePlayerVision(x, y, 8) in Node.js runtime.
   - Verified 0 GC collections via PerformanceObserver gc event tracking.
   - Verified 0 memory leaks across 5,000 discrete tile-crossing updates.
2. Bit-Packing Compression:
   - Round-trip serialization/deserialization across 10,800 tiles (120x90).
   - Raw binary buffer is exactly 1,354 bytes (<= 1,354 bytes).
   - Base64 encoded string is exactly 1,808 characters (< 2.0 KB).
   - 100% bit-exact restoration across all bit patterns (Zeroes, Ones, Checkerboard,
     Sparse 1%, Dense 99%, Byte Boundaries, Pseudo-random, Prime Strides).
3. Rapid Zone Transition:
   - State isolation across rapid zone hopping and procedural seed mutations.
   - Verification that vision decay does not demote out-of-bounds coordinates from prior zones.
   - Safe rejection of corrupted/mismatched storage payloads.
"""

from __future__ import annotations
import base64
import json
import math
from pathlib import Path
import struct
import subprocess
import pytest

ROOT = Path(__file__).resolve().parent.parent.parent
CHALLENGER_NODE_SCRIPT = ROOT / "tests" / "unit" / "test_challenger_m4_empirical.js"
WAR_FOG_JS = ROOT / "client" / "webapp" / "js" / "ui" / "war_fog.js"


class TestNodeEmpiricalStressHarness:
    """Executes the full Node.js empirical stress harness."""

    def test_run_node_stress_harness(self):
        """Runs test_challenger_m4_empirical.js with --expose-gc and asserts all 19 tests pass."""
        proc = subprocess.run(
            ["node", "--expose-gc", str(CHALLENGER_NODE_SCRIPT)],
            capture_output=True,
            text=True,
            cwd=str(ROOT),
            check=False,
        )
        assert proc.returncode == 0, f"Stress harness failed:\nSTDOUT:\n{proc.stdout}\nSTDERR:\n{proc.stderr}"
        assert "19/19 PASSED, 0 FAILED" in proc.stdout
        assert "GC events: 0" in proc.stdout


class TestBitPackingCompressionMathematicalProof:
    """Verifies mathematical guarantees of bit-packing compression across 10,800 tiles (120x90)."""

    W = 120
    H = 90
    TOTAL_TILES = 120 * 90  # 10,800

    def test_raw_size_and_base64_budget_120x90(self):
        """10,800 tiles must pack into exactly 1,354 raw bytes and < 2.0 KB Base64."""
        header_bytes = 4  # 2 bytes width + 2 bytes height
        data_bytes = math.ceil(self.TOTAL_TILES / 8)  # 10,800 / 8 = 1,350
        raw_size = header_bytes + data_bytes
        assert raw_size <= 1354, f"Raw size {raw_size} exceeds 1,354 bytes"
        assert raw_size == 1354

        # Base64 string length = 4 * ceil(n / 3)
        base64_length = 4 * math.ceil(raw_size / 3)  # 4 * ceil(1354 / 3) = 4 * 452 = 1,808
        base64_kb = base64_length / 1024.0
        assert base64_kb < 2.0, f"Base64 size {base64_kb:.3f} KB exceeds 2.0 KB budget"
        assert base64_length == 1808

    @pytest.mark.parametrize("pattern_kind", [
        "all_zeroes",
        "all_ones",
        "checkerboard",
        "byte_boundaries",
        "sparse_1pct",
        "dense_99pct",
        "pseudorandom",
    ])
    def test_python_cross_validation_bit_exact(self, pattern_kind: str):
        """Cross-validates bit-exact pack and unpack in pure Python mirroring war_fog.js."""
        # 1. Synthesize tile grid
        grid = bytearray(self.TOTAL_TILES)
        if pattern_kind == "all_zeroes":
            pass
        elif pattern_kind == "all_ones":
            grid = bytearray([1] * self.TOTAL_TILES)
        elif pattern_kind == "checkerboard":
            grid = bytearray([(1 if i % 2 == 0 else 0) for i in range(self.TOTAL_TILES)])
        elif pattern_kind == "byte_boundaries":
            for idx in [0, 7, 8, 15, self.TOTAL_TILES - 8, self.TOTAL_TILES - 1]:
                grid[idx] = 1
        elif pattern_kind == "sparse_1pct":
            for i in range(self.TOTAL_TILES):
                if (i * 37 + 11) % 100 == 0:
                    grid[i] = 2
        elif pattern_kind == "dense_99pct":
            grid = bytearray([1] * self.TOTAL_TILES)
            for i in range(self.TOTAL_TILES):
                if (i * 37 + 11) % 100 == 0:
                    grid[i] = 0
        elif pattern_kind == "pseudorandom":
            s = 123456789
            for i in range(self.TOTAL_TILES):
                s = (s * 1103515245 + 12345) & 0x7FFFFFFF
                grid[i] = (s & 1)

        # 2. Pack bits (4 bytes header + bitmask)
        packed_bytes = bytearray(4 + math.ceil(self.TOTAL_TILES / 8))
        packed_bytes[0] = self.W & 0xFF
        packed_bytes[1] = (self.W >> 8) & 0xFF
        packed_bytes[2] = self.H & 0xFF
        packed_bytes[3] = (self.H >> 8) & 0xFF

        for i in range(self.TOTAL_TILES):
            if grid[i] > 0:
                packed_bytes[4 + (i >> 3)] |= (1 << (i & 7))

        assert len(packed_bytes) == 1354
        b64 = base64.b64encode(packed_bytes).decode("ascii")
        assert len(b64) == 1808

        # 3. Unpack bits
        decoded = base64.b64decode(b64)
        w, h = struct.unpack_from("<HH", decoded, 0)
        assert w == self.W and h == self.H

        restored_explored = bytearray(self.TOTAL_TILES)
        data_len = min(len(decoded) - 4, math.ceil(self.TOTAL_TILES / 8))
        for byte_idx in range(data_len):
            b = decoded[4 + byte_idx]
            if b == 0:
                continue
            base = byte_idx << 3
            for bit in range(8):
                idx = base + bit
                if idx < self.TOTAL_TILES and (b & (1 << bit)) != 0:
                    restored_explored[idx] = 1

        # 4. Verify 100% bit-exact restoration
        for i in range(self.TOTAL_TILES):
            orig_explored = 1 if grid[i] > 0 else 0
            rest_explored = restored_explored[i]
            assert orig_explored == rest_explored, f"Bit mismatch at index {i}"


class TestZoneTransitionStateIsolation:
    """Verifies storage key namespacing and zero-leakage during zone transitions."""

    def test_storage_key_isolation(self):
        """Verifies getStorageKey formatting in war_fog.js."""
        wf = WAR_FOG_JS.read_text(encoding="utf-8")
        assert "STORAGE_PREFIX = 'fe_fog_'" in wf or 'STORAGE_PREFIX = "fe_fog_"' in wf
        assert "`${STORAGE_PREFIX}${zoneId}_${seed}`" in wf

    def test_dimensions_guard_in_unpack(self):
        """Unpack must abort if width/height mismatch."""
        wf = WAR_FOG_JS.read_text(encoding="utf-8")
        assert "if (w !== expectedW || h !== expectedH) return false;" in wf

    def test_last_vis_reset_on_init(self):
        """initFog must reset lastVisX and lastVisY to prevent cross-zone decay corruption."""
        wf = WAR_FOG_JS.read_text(encoding="utf-8")
        assert "lastVisX = -9999; lastVisY = -9999;" in wf
