#!/usr/bin/env python3
"""Live server for the routing visualiser.

Serves the visualiser HTML (all 36 glyphs precomputed + embedded) AND a
`/api/route` endpoint that routes an arbitrary 5x9 selection on demand using
the SAME `dijkstra_alg.route_chain` the PCB generator uses. This is what
powers the Custom-Shape editor without porting the algorithm to JS.

    python3 route_server.py [port]      # default 7702
"""

import json
import os
import sys
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import urlparse, parse_qs

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, SCRIPT_DIR)

import route_visualizer as rv

PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 7702

# Build the embedded-glyph HTML once at startup.
HTML = rv.render_full_html().encode("utf-8")


def parse_cells(raw):
    surviving = set()
    for tok in raw.split(";"):
        tok = tok.strip()
        if not tok:
            continue
        r, c = tok.split(",")
        surviving.add((int(r), int(c)))
    return surviving


class Handler(BaseHTTPRequestHandler):
    def _send(self, code, ctype, body):
        self.send_response(code)
        self.send_header("Content-Type", ctype)
        self.send_header("Content-Length", str(len(body)))
        self.send_header("Cache-Control", "no-store")
        self.send_header("Access-Control-Allow-Origin", "*")
        self.end_headers()
        self.wfile.write(body)

    def do_GET(self):
        u = urlparse(self.path)
        path = u.path
        if path.endswith("/api/route") or path == "/api/route":
            q = parse_qs(u.query)
            raw = q.get("cells", [""])[0]
            inverted = q.get("inverted", ["0"])[0] == "1"
            try:
                surviving = parse_cells(raw)
                scene = rv.compute_shape(surviving, inverted=inverted)
                self._send(200, "application/json", json.dumps(scene).encode())
            except Exception as e:  # noqa: BLE001 — surface to client for debugging
                self._send(400, "application/json",
                           json.dumps({"error": str(e)}).encode())
            return
        if path in ("/", "") or path.endswith("route_visualizer.html") or path.endswith("/"):
            self._send(200, "text/html; charset=utf-8", HTML)
            return
        self._send(404, "text/plain", b"not found")

    def log_message(self, *args):
        pass  # quiet


def main():
    srv = ThreadingHTTPServer(("0.0.0.0", PORT), Handler)
    print(f"route_server listening on http://0.0.0.0:{PORT}")
    print(f"  HTML  : /route_visualizer.html")
    print(f"  API   : /api/route?cells=r,c;r,c&inverted=0|1")
    srv.serve_forever()


if __name__ == "__main__":
    main()
