"""Small credential-free Python execution service for Hermes chat tenants."""

from __future__ import annotations

import json
import os
import resource
import signal
import subprocess
import tempfile
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path

HOST = "0.0.0.0"
PORT = 9080
MAX_REQUEST_BYTES = 160 * 1024
MAX_CODE_BYTES = 128 * 1024
MAX_OUTPUT_BYTES = 100 * 1024
WORKSPACE = Path("/workspace")


def _child_limits() -> None:
    """Apply conservative CPU, memory, process, file, and descriptor limits."""
    os.setsid()
    resource.setrlimit(resource.RLIMIT_CPU, (35, 35))
    resource.setrlimit(resource.RLIMIT_AS, (768 * 1024 * 1024,) * 2)
    resource.setrlimit(resource.RLIMIT_NPROC, (32, 32))
    resource.setrlimit(resource.RLIMIT_FSIZE, (32 * 1024 * 1024,) * 2)
    resource.setrlimit(resource.RLIMIT_NOFILE, (64, 64))


def _execute(code: str) -> dict[str, object]:
    """Run one isolated Python subprocess and return bounded output."""
    with tempfile.NamedTemporaryFile(
        mode="w", suffix=".py", prefix="hermes-", dir="/tmp", delete=False
    ) as script:
        script.write(code)
        script_path = script.name

    env = {
        "HOME": str(WORKSPACE),
        "LANG": "C.UTF-8",
        "LC_ALL": "C.UTF-8",
        "PATH": "/usr/local/bin:/usr/bin:/bin",
        "PYTHONDONTWRITEBYTECODE": "1",
    }
    try:
        process = subprocess.Popen(
            ["python", "-I", "-B", script_path],
            cwd=WORKSPACE,
            env=env,
            stdin=subprocess.DEVNULL,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            preexec_fn=_child_limits,
        )
        try:
            stdout, stderr = process.communicate(timeout=45)
            timed_out = False
        except subprocess.TimeoutExpired:
            timed_out = True
            os.killpg(process.pid, signal.SIGKILL)
            stdout, stderr = process.communicate()
        return {
            "success": process.returncode == 0 and not timed_out,
            "exit_code": process.returncode,
            "timed_out": timed_out,
            "stdout": stdout[:MAX_OUTPUT_BYTES].decode("utf-8", errors="replace"),
            "stderr": stderr[:MAX_OUTPUT_BYTES].decode("utf-8", errors="replace"),
            "output_truncated": (
                len(stdout) > MAX_OUTPUT_BYTES or len(stderr) > MAX_OUTPUT_BYTES
            ),
        }
    finally:
        try:
            os.unlink(script_path)
        except FileNotFoundError:
            pass


class Handler(BaseHTTPRequestHandler):
    """Serve health and bounded Python execution requests."""

    server_version = "HermesChatSandbox/1"

    def log_message(self, format_string: str, *args: object) -> None:
        """Keep normal request logs concise and free of request bodies."""
        print(f"sandbox: {self.address_string()} {format_string % args}", flush=True)

    def _json(self, status: int, payload: dict[str, object]) -> None:
        body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
        self.send_response(status)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(body)))
        self.send_header("X-Content-Type-Options", "nosniff")
        self.end_headers()
        self.wfile.write(body)

    def do_GET(self) -> None:
        """Return a minimal unauthenticated health response."""
        if self.path == "/health":
            self._json(200, {"status": "ok"})
        else:
            self._json(404, {"error": "not found"})

    def do_POST(self) -> None:
        """Validate and execute a Python request from the matching tenant pod."""
        if self.path != "/v1/execute":
            self._json(404, {"error": "not found"})
            return
        try:
            length = int(self.headers.get("Content-Length", "0"))
        except ValueError:
            self._json(400, {"error": "invalid content length"})
            return
        if length <= 0 or length > MAX_REQUEST_BYTES:
            self._json(413, {"error": "request too large"})
            return
        try:
            payload = json.loads(self.rfile.read(length))
        except (json.JSONDecodeError, UnicodeDecodeError):
            self._json(400, {"error": "invalid JSON"})
            return
        code = payload.get("code") if isinstance(payload, dict) else None
        if not isinstance(code, str) or not code.strip():
            self._json(400, {"error": "code is required"})
            return
        if len(code.encode("utf-8")) > MAX_CODE_BYTES:
            self._json(413, {"error": "code exceeds 128 KiB"})
            return
        self._json(200, _execute(code))


if __name__ == "__main__":
    WORKSPACE.mkdir(parents=True, exist_ok=True)
    ThreadingHTTPServer((HOST, PORT), Handler).serve_forever()
