#!/usr/bin/env python3
"""Static explorer with SPA fallback: unknown paths serve index.html (client router).
API paths (/api/, /explorer-api/) are not rewritten so missing backends still 404 clearly."""
from __future__ import annotations

import argparse
import os
import sys
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import urlparse


def main() -> int:
    p = argparse.ArgumentParser(description="Serve explorer-monorepo/frontend/public with SPA fallback.")
    p.add_argument("port", nargs="?", type=int, default=8080, help="Listen port (default 8080)")
    p.add_argument(
        "--bind",
        default="127.0.0.1",
        help="Bind address (default 127.0.0.1)",
    )
    args = p.parse_args()
    script_dir = os.path.dirname(os.path.abspath(__file__))
    root = os.path.normpath(os.path.join(script_dir, "..", "frontend", "public"))
    if not os.path.isfile(os.path.join(root, "index.html")):
        print(f"ERROR: index.html not found under {root}", file=sys.stderr)
        return 1

    class Handler(SimpleHTTPRequestHandler):
        def __init__(self, *a, **kw):
            super().__init__(*a, directory=root, **kw)

        def do_GET(self) -> None:  # noqa: N802
            path = urlparse(self.path).path
            if path.startswith("/api/") or path.startswith("/explorer-api"):
                return super().do_GET()
            rel = path.lstrip("/")
            if rel.startswith(".."):
                self.send_error(403, "Forbidden")
                return
            fs = os.path.join(root, rel) if rel else root
            if os.path.isfile(fs):
                return super().do_GET()
            self.path = "/index.html"
            return super().do_GET()

    httpd = ThreadingHTTPServer((args.bind, args.port), Handler)
    print(f"Serving SPA explorer: http://{args.bind}:{args.port}/  (root={root})", flush=True)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("\nStopped.", flush=True)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
