"""Unit tests for the obfuscation detector."""
from __future__ import annotations

from pyguard.detectors.obfuscation import analyze_obfuscation
from pyguard.models import Severity


def _analyze(source: str) -> list:
    return analyze_obfuscation("testpkg", "1.0.0", "test.py", source)


def test_exec_base64_is_critical():
    source = "exec(base64.b64decode('aGVsbG8='))"
    findings = _analyze(source)
    assert any(f.severity == Severity.CRITICAL for f in findings)


def test_exec_compile_is_critical():
    source = "exec(compile(code, '<string>', 'exec'))"
    findings = _analyze(source)
    assert any(f.severity == Severity.CRITICAL for f in findings)


def test_dynamic_import_flagged():
    source = "__import__('os').system('id')"
    findings = _analyze(source)
    assert any("import" in f.title.lower() for f in findings)


def test_marshal_loads_is_critical():
    source = "import marshal\nmarshal.loads(payload)"
    findings = _analyze(source)
    assert any(f.severity == Severity.CRITICAL for f in findings)


def test_clean_code_no_findings():
    source = "def add(a, b):\n    return a + b\n"
    findings = _analyze(source)
    assert findings == []


def test_high_entropy_flagged():
    # Simulate a high-entropy obfuscated payload (90+ unique character distribution)
    # Uses printable ASCII spread across many distinct chars to exceed the 5.2-bit threshold
    high_ent = "3$Kp!mZ@rQ#nVj&wT*dX%hL^yU(cB)eA_sI+oF=gR~P|bM<N>kH?lG{O}0Wx1Y2C"
    # Pad to exceed minimum line length (80 chars) and get high entropy
    source = 'x = "' + (high_ent * 2) + '"\n'
    findings = _analyze(source)
    assert any("entropy" in f.title.lower() for f in findings)
