"""AutoPOE2 - Master Invariants Specifications & SSoT Matrix (2026).
==================================================================
Domain: Sư đoàn 4: lead_qa_governance (Quản trị chất lượng & Bất biến).
Đặc tả định lượng Single Source of Truth cho 19 Bất biến Kiến trúc (AGENTS.md Mục 8).
"""

from __future__ import annotations

import enum
from dataclasses import dataclass, field
from datetime import datetime
from typing import List


class InvariantStatus(str, enum.Enum):
    """Trạng thái kiểm định của từng bất biến kiến trúc."""
    PASSED = "PASSED"
    WARNING = "WARNING"
    BLOCKED = "BLOCKED"


@dataclass
class InvariantSpec:
    """Đặc tả định lượng của 1 Bất biến Kiến trúc."""
    code: str
    name: str
    monitored_module: str
    rule_summary: str
    weight: float
    is_critical: bool = True


@dataclass
class InvariantAuditResult:
    """Kết quả kiểm định định lượng của 1 Bất biến."""
    code: str
    name: str
    status: InvariantStatus
    monitored_module: str
    evidence: str
    metric_value: str
    duration_ms: float
    timestamp: str = field(default_factory=lambda: datetime.now().isoformat())


@dataclass
class MasterInvariantsAuditReport:
    """Báo cáo kiểm định toàn diện 19 Bất biến Kiến trúc."""
    is_cleared_for_autonomous: bool
    total_invariants: int
    passed_count: int
    warning_count: int
    blocked_count: int
    autonomy_readiness_score: float
    total_duration_ms: float
    results: List[InvariantAuditResult] = field(default_factory=list)
    timestamp: str = field(default_factory=lambda: datetime.now().isoformat())
    summary: str = ""


# ============================================================================
# DANH MỤC 20 BẤT BIẾN KIẾN TRÚC CHUẨN MỰC (SSoT 2026 - AGENTS.md Mục 8)
# ============================================================================
MASTER_20_INVARIANTS_SPECS: List[InvariantSpec] = [
    InvariantSpec(
        code="INV-INPUT-ABS-MOUSE",
        name="Absolute Mouse UI & Target Movement",
        monitored_module="MapDeviceHandler, NpcInteractionHandler, LootController",
        rule_summary="Mọi click UI/target dùng tọa độ tuyệt đối (MoveMouseSmooth). MoveMouse(rx,ry) chỉ nhận delta Bézier.",
        weight=4.5,
    ),
    InvariantSpec(
        code="INV-WASD-NO-BLIND-LMB",
        name="WASD Proximity Before Entity Click",
        monitored_module="OpenDevice, EnterPortal, LootController",
        rule_summary="Chế độ WASD: LMB là skill khi click đất. Cấm click mù xuống đất/chân nhân vật. Áp sát <= 18u rồi Click LMB có chủ đích.",
        weight=5.5,
    ),
    InvariantSpec(
        code="INV-KEY-NO-F-FOR-INTERACT",
        name="F Key Reserved For Skill 8",
        monitored_module="QuestNavigator, NpcInteractionHandler, MapDeviceHandler, coordinator",
        rule_summary="TUYỆT ĐỐI CẤM gửi phím F để tương tác. Phím F là Skill 8 của người chơi; tương tác 100% bằng Click LMB có chủ đích.",
        weight=5.5,
    ),
    InvariantSpec(
        code="INV-KEY-NO-U-FOR-MAP-DEVICE",
        name="No U Key At Hideout Map Device",
        monitored_module="autonomous_mapping_coordinator.py, TownQuestEngine",
        rule_summary="Cấm phím U tại Hideout Map Device. Phím U chỉ mở World Map xem-only của campaign; mở Map Device phải tương tác vật lý trực tiếp.",
        weight=4.5,
    ),
    InvariantSpec(
        code="INV-WASD-MIN-DWELL",
        name="WASD Key Minimum Dwell Time",
        monitored_module="QuestNavigator::SendDirection, MapDeviceHandler approach",
        rule_summary="Dwell di chuyển WASD >= 300ms (ngắn) / >= 1000ms (dài). Cấm micro-tap < 150ms.",
        weight=4.5,
    ),
    InvariantSpec(
        code="INV-F8-MUTES-BRAIN",
        name="F8 Movement Safety Lock Mutes Brain",
        monitored_module="main.cpp, BotBrain",
        rule_summary="allowPhysicalMove == false (F8 PAUSE) -> tắt botBrain.Process, tự động nhả toàn bộ phím WASD.",
        weight=5.5,
    ),
    InvariantSpec(
        code="INV-MAPDEVICE-VERIFY-UI",
        name="Map Device UI OCR & Tray Verification",
        monitored_module="MapDeviceHandler, autonomous_mapping_coordinator.py",
        rule_summary="Cấm advance FSM nếu chưa có tín hiệu UI mở (OCR TRAVERSE / khay Waystone). Timeout -> Failed + backoff 3s.",
        weight=5.5,
    ),
    InvariantSpec(
        code="INV-MAPDEVICE-RETRY-POLL",
        name="Map Device Portal Polling 8000ms",
        monitored_module="MapDeviceHandler",
        rule_summary="WaitForPortals retry polling trong 8000ms, cấm fail-closed vội sau 1 tick 2500ms.",
        weight=4.5,
    ),
    InvariantSpec(
        code="INV-BRAIN-CONFLICT-GATEKEEPER",
        name="Brain Conflict Gatekeeper (Opcode 96)",
        monitored_module="main.cpp, town_quest_engine.cpp",
        rule_summary="C++ Core và TownQuestEngine từ chối Opcode 96 (TRIGGER_WORLD_MAP_TRAVEL) khi ở Hideout hoặc khi MapDevice active.",
        weight=4.5,
    ),
    InvariantSpec(
        code="INV-TERRAIN-ORIGIN",
        name="Authentic Terrain Origin & JPS Calibrator",
        monitored_module="TerrainReader, TerrainGrid, MapDeviceHandler",
        rule_summary="worldOrigin calibrate từ struct địa hình thật. Cấm slide JPS với grid == nullptr.",
        weight=4.5,
    ),
    InvariantSpec(
        code="INV-FSM-SINGLE-OWNER",
        name="Single FSM Lifecycle Owner",
        monitored_module="CharacterFSM, core_shm_bridge.py",
        rule_summary="Một chủ vòng đời duy nhất: C++ CharacterFSM ghi SHM. Python không click song song khi C++ active.",
        weight=5.0,
    ),
    InvariantSpec(
        code="INV-CI-01",
        name="Chaos Inoculation ES Reflex Gating",
        monitored_module="ReflexManager",
        rule_summary="Nhân vật CI (HP 1/1): Không dùng Life Flask; trigger dodge/chicken theo Energy Shield.",
        weight=6.0,
    ),
    InvariantSpec(
        code="INV-MEM-DYNAMIC-XYZ",
        name="Dynamic XYZ 16MB Scanner",
        monitored_module="PlayerFinder",
        rule_summary="Tọa độ XYZ đọc từ con trỏ động PlayerFinder 16MB, từ chối neo tĩnh 0x290 / 0x540.",
        weight=6.0,
    ),
    InvariantSpec(
        code="INV-KEY-PORTAL",
        name="Town Portal Uses Period Key '.'",
        monitored_module="QuestNavigator, UnstuckHandler",
        rule_summary="Mở Town Portal dùng phím '.' (VK_OEM_PERIOD 0xBE), không dùng phím T hay Warcry.",
        weight=4.5,
    ),
    InvariantSpec(
        code="INV-KEY-E-PULSE",
        name="Pulse E With Forward Disabled By Default",
        monitored_module="QuestNavConfig",
        rule_summary="Cờ pulseEWithForward mặc định false, cấm nhấp phím E tự do khi di chuyển.",
        weight=4.5,
    ),
    InvariantSpec(
        code="INV-OCR-MOCK-NO-CALL",
        name="Headless Mock Harness Zero Real OCR Leak",
        monitored_module="vision_ocr.py, ScreenCapturer",
        rule_summary="Headless Mock Harness cấm gọi OCR thật / ScreenCapture desktop gây blocking hoặc rò rỉ cửa sổ. Sử dụng synthetic perception an toàn 100%.",
        weight=4.5,
    ),
    InvariantSpec(
        code="INV-FOCUS-INTERLOCK-HARDWARE-SAFETY",
        name="Two-Factor Hardware Focus Interlock",
        monitored_module="KMBoxNet, NonBlockingActuator, win32_window",
        rule_summary="Chỉ chặn KeyDown/MouseDown khi mất focus. CẤM chặn KeyUp/MouseUp. Tự động ReleaseAllKeys() khi unfocused. Two-factor class & image check.",
        weight=6.0,
    ),
    InvariantSpec(
        code="INV-ATLAS-FARM-NODE",
        name="Special Arena Blacklist Gating",
        monitored_module="vision_ocr.py, autonomous_mapping_coordinator.py, atlas_node_selector.py",
        rule_summary="Tuyệt đối CẤM chọn The Well of Souls, Precursor Tower, The Burning Monolith, hoặc Pinnacle Arenas cho chu trình cày Waystone tự động.",
        weight=4.5,
    ),
    InvariantSpec(
        code="INV-WAYSTONE-ROW1-ONLY",
        name="Waystone Bag Row 1 Slot Reservation",
        monitored_module="optical_inventory_scanner.py, MapDeviceHandler, autonomous_lifecycle.py",
        rule_summary="Chỉ lấy Waystone từ Hàng 1 (Row 1) của túi đồ/Stash để chạy map nhằm chống nhặt nhầm Currency quý hoặc Gear trang bị.",
        weight=4.0,
    ),
    InvariantSpec(
        code="INV-MOTION-INTEGRITY",
        name="Closed-Loop Physical Motion Verification & Hardware Fallback",
        monitored_module="send_wasd_direction, AutonomousMappingCoordinator, UnstuckHandler, win32_input",
        rule_summary="Bắt buộc xác nhận Delta XYZ > 0 (RAM) HOẶC Delta Optical > 15px (Vision) sau mỗi nhịp di chuyển WASD >= 300ms. Nếu Delta = 0, phát hiện nhân vật tê liệt: lập tức raise Anomaly và kích hoạt Hardware Fallback.",
        weight=6.0,
        is_critical=True,
    ),
]

# Tương thích ngược: MASTER_19_INVARIANTS_SPECS trỏ tới danh mục đầy đủ
MASTER_19_INVARIANTS_SPECS: List[InvariantSpec] = MASTER_20_INVARIANTS_SPECS
