"""静态守卫与隔离器的单测（守卫纯逻辑无依赖；隔离器测无 Docker 时的降级）。"""

import asyncio

from sundynix_mcp_py.interpreter import CodeInterpreter
from sundynix_mcp_py.sandbox import SecureSandbox


def test_guard_allows_safe_code():
    g = SecureSandbox()
    for code in [
        "x = sum(range(10))\nprint(x)",
        "import math, json\nprint(math.sqrt(2))",
        "import re\nprint(re.findall(r'\\d+', 'a1b2'))",
    ]:
        ok, reason = g.static_guard(code)
        assert ok, f"安全代码被误拒: {code} → {reason}"


def test_guard_blocks_dangerous_imports():
    g = SecureSandbox()
    for code in [
        "import os\nos.listdir('/')",
        "import subprocess",
        "from socket import socket",
        "import ctypes",
        "import pickle",
        "import requests",
    ]:
        ok, reason = g.static_guard(code)
        assert not ok, f"危险导入未拦: {code}"
        assert "禁止导入" in reason


def test_guard_blocks_dangerous_calls():
    g = SecureSandbox()
    for code in ["eval('1+1')", "exec('x=1')", "__import__('os')", "open('/etc/passwd')"]:
        ok, reason = g.static_guard(code)
        assert not ok and "禁止调用" in reason, f"危险调用未拦: {code}"


def test_guard_blocks_escape_attrs():
    g = SecureSandbox()
    ok, reason = g.static_guard("().__class__.__subclasses__()")
    assert not ok and "禁止访问属性" in reason
    ok2, _ = g.static_guard("(lambda: 0).__globals__")
    assert not ok2


def test_guard_rejects_syntax_error():
    g = SecureSandbox()
    ok, reason = g.static_guard("def f(:\n  pass")
    assert not ok and "语法错误" in reason


def test_interpreter_degrades_without_docker():
    ci = CodeInterpreter()
    if ci.available():
        return  # 本机有 Docker：跳过降级断言（执行路径走集成验证）
    r = asyncio.run(ci.execute("print(1)"))
    assert r["degraded"] is True and r["ok"] is False
