#!/usr/bin/env python3
import json
import subprocess
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer


HOST = "0.0.0.0"
PORT = 8081


def run_command(cmd: list[str]) -> subprocess.CompletedProcess[str]:
    return subprocess.run(cmd, capture_output=True, text=True)


def tcp_probe(namespace: str, host: str, port: int) -> bool:
    cmd = [
        "/usr/sbin/ip",
        "netns",
        "exec",
        namespace,
        "timeout",
        "2",
        "bash",
        "-lc",
        f"exec 3<>/dev/tcp/{host}/{port}",
    ]
    return run_command(cmd).returncode == 0


class Handler(BaseHTTPRequestHandler):
    def _read_json(self) -> dict:
        length = int(self.headers.get("Content-Length", "0"))
        raw = self.rfile.read(length) if length else b"{}"
        return json.loads(raw.decode("utf-8"))

    def _send_json(self, payload: dict, status: int = 200) -> None:
        body = json.dumps(payload).encode("utf-8")
        self.send_response(status)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def do_GET(self) -> None:
        if self.path == "/health":
            self._send_json({"ok": True})
            return

        if self.path == "/iptables/report":
            prerouting = run_command(["/usr/sbin/iptables-legacy", "-t", "nat", "-S", "PREROUTING"])
            forward = run_command(["/usr/sbin/iptables-legacy", "-S", "FORWARD"])
            self._send_json({
                "prerouting": prerouting.stdout,
                "forward": forward.stdout,
                "stderr": prerouting.stderr + forward.stderr,
            })
            return

        self._send_json({"error": "not found"}, status=404)

    def do_POST(self) -> None:
        data = self._read_json()

        if self.path == "/probe/tcp":
            namespace = str(data["namespace"])
            host = str(data["host"])
            port = int(data["port"])
            self._send_json({"ok": tcp_probe(namespace, host, port)})
            return

        self._send_json({"error": "not found"}, status=404)

    def log_message(self, format: str, *args) -> None:
        return


if __name__ == "__main__":
    ThreadingHTTPServer((HOST, PORT), Handler).serve_forever()
