﻿import ast
import os
import runpy
import sys
from pathlib import Path

root = Path(sys.argv[1]).resolve()
test = Path(sys.argv[2]).resolve()
lab = Path(sys.argv[3]).resolve()

source = test.read_text(encoding="utf-8-sig")
tree = ast.parse(source)

tests = [
    n.name for n in ast.walk(tree)
    if isinstance(n, ast.FunctionDef)
    and n.name.startswith("test_")
]

print("TESTS_DECLARADOS=", len(tests), flush=True)

if len(tests) < 12:
    raise RuntimeError("SUITE_INCOMPLETA")

allowed = os.path.normcase(str(lab))

def inside_lab(value):
    try:
        if not isinstance(value, (str, bytes, os.PathLike)):
            return False
        p = os.path.normcase(os.path.abspath(os.fsdecode(value)))
        return p == allowed or p.startswith(allowed + os.sep)
    except Exception:
        return False

def audit(event, args):
    prohibited = {
        "subprocess.Popen",
        "os.system",
        "os.startfile",
        "socket.connect",
        "socket.connect_ex",
        "socket.bind",
    }

    if event in prohibited:
        raise PermissionError("EVENTO_BLOQUEADO: " + event)

    if event == "open" and args:
        mode = args[1] if len(args) > 1 else "r"
        flags = args[2] if len(args) > 2 else 0

        writing = (
            isinstance(mode, str)
            and any(ch in mode for ch in "wax+")
        )

        if isinstance(flags, int):
            writing = writing or bool(
                flags & (
                    os.O_WRONLY |
                    os.O_RDWR |
                    os.O_CREAT |
                    os.O_TRUNC |
                    os.O_APPEND
                )
            )

        if writing and not inside_lab(args[0]):
            raise PermissionError("ESCRITURA_FUERA_LAB_BLOQUEADA")

    if event in {
        "os.mkdir", "os.remove", "os.rmdir",
        "os.rename", "os.chmod", "os.utime",
        "os.link", "os.symlink", "os.truncate"
    }:
        paths = args[:2] if event in {
            "os.rename", "os.link", "os.symlink"
        } else args[:1]

        if not all(inside_lab(p) for p in paths):
            raise PermissionError("MUTACION_FUERA_LAB_BLOQUEADA")

sys.addaudithook(audit)

workspace = os.environ.get("OPTIMUS_PROJECTS_DIR", "")

print("PROJECT_ROOT=", root, flush=True)
print("WORKSPACE_ROOT=", workspace, flush=True)
print("AUDIT_GUARD=ACTIVE", flush=True)

sys.path.insert(0, str(root))
sys.argv = [str(test)]

runpy.run_path(str(test), run_name="__main__")
