"""
Nexa Language — Sandbox Module (Phase 2, v25)
Provides a SandboxedInterpreter that blocks dangerous I/O and FFI when running
untrusted Nexa code. Enable with: nexa run --safe-mode file.nexa
"""
from __future__ import annotations
from .interpreter import Interpreter, NexaRuntimeError
from .builtins import BUILTINS


# Modules that are restricted in safe mode
_FORBIDDEN_SAFE_MODE = {"fs", "db", "ffi", "serve", "env", "sys", "http", "task"}

# Safe wrappers that replace dangerous builtins in sandboxed mode
class _ReadOnlyFS:
    """Read-only file system — blocks all write operations in safe mode."""
    def read(self, path: str) -> str:
        return open(path, encoding="utf-8").read()
    def read_lines(self, path: str):
        with open(path, encoding="utf-8") as f:
            return [l.rstrip("\n") for l in f]
    def exists(self, path: str) -> bool:
        import os
        return os.path.exists(path)
    def list_dir(self, path: str = "."):
        import os
        return os.listdir(path)
    def write(self, *args, **kwargs):
        raise NexaRuntimeError("[SAFE MODE] fs.write() is disabled in --safe-mode")
    def delete(self, *args, **kwargs):
        raise NexaRuntimeError("[SAFE MODE] fs.delete() is disabled in --safe-mode")
    def append(self, *args, **kwargs):
        raise NexaRuntimeError("[SAFE MODE] fs.append() is disabled in --safe-mode")
    def move(self, *args, **kwargs):
        raise NexaRuntimeError("[SAFE MODE] fs.move() is disabled in --safe-mode")
    def copy(self, *args, **kwargs):
        raise NexaRuntimeError("[SAFE MODE] fs.copy() is disabled in --safe-mode")
    def __repr__(self): return "<fs module [read-only, safe mode]>"


class _BlockedModule:
    """Placeholder that raises on any attribute access."""
    def __init__(self, name: str):
        self._name = name
    def __getattr__(self, item):
        raise NexaRuntimeError(
            f"[SAFE MODE] Module '{self._name}' is disabled. "
            f"Run without --safe-mode to enable it."
        )
    def __repr__(self): return f"<{self._name} module [blocked, safe mode]>"


class SandboxedInterpreter(Interpreter):
    """
    Interpreter subclass that restricts dangerous module access.
    Activated via: nexa run --safe-mode your_file.nexa
    """
    def __init__(self, debug=False, source_dir="."):
        super().__init__(debug=debug, source_dir=source_dir)
        self._apply_sandbox()

    def _apply_sandbox(self):
        """Replace dangerous builtins with sandboxed alternatives."""
        # Read-only FS
        self.global_env.set("fs", _ReadOnlyFS())
        # Block other dangerous modules
        for mod in _FORBIDDEN_SAFE_MODE - {"fs"}:
            if mod in BUILTINS:
                self.global_env.set(mod, _BlockedModule(mod))
        print("  🔒 Nexa running in --safe-mode: I/O modules are restricted.")

    def _exec_ImportStatement(self, node, env):
        """Block imports of forbidden modules in safe mode."""
        if node.module in _FORBIDDEN_SAFE_MODE and not node.is_file:
            raise NexaRuntimeError(
                f"[SAFE MODE] Cannot import '{node.module}' — disabled in safe mode."
            )
        super()._exec_ImportStatement(node, env)
