#!/usr/bin/env python3
"""
Reichert App/assets/data/lg-roadnet.json an: ersetzt die hand-kuratierte
Polyline jeder Kante durch die echte OSRM-Routengeometrie entlang echter
Autobahnen. Die bisherigen Wegpunkte dienen als Stuetzstellen, damit OSRM
den gewuenschten Korridor waehlt (z.B. Brenner statt Mont Blanc).

Nutzt den freien OSRM-Demo-Server (router.project-osrm.org). Nur fuer
Dev-Zeit — die fertige Polyline landet im JSON, die Produktion ruft
OSRM nie auf (DSGVO, Rate-Limit, Verfuegbarkeit).

Aufruf:
    python App/sims/logistik/scripts/enrich-roadnet-osrm.py
"""
import json
import ssl
import urllib.request
import urllib.parse
import time
import sys
from pathlib import Path

# SSL-Cert-Verify aus — Windows-Python findet den CA-Store oft nicht. Das
# ist fuer ein Dev-Tool (einmaliger Run, Ergebnis landet im JSON) akzeptabel.
# Produktiv wird OSRM nie aufgerufen.
SSL_CTX = ssl.create_default_context()
SSL_CTX.check_hostname = False
SSL_CTX.verify_mode = ssl.CERT_NONE

ROADNET = Path(__file__).resolve().parents[3] / "assets" / "data" / "lg-roadnet.json"
OSRM = "https://router.project-osrm.org/route/v1/driving/{coords}?overview=full&geometries=geojson"


def fetch_route(waypoints):
    # waypoints = [[lat, lon], ...] -> OSRM erwartet "lon,lat;lon,lat;..."
    coords = ";".join(f"{w[1]},{w[0]}" for w in waypoints)
    url = OSRM.format(coords=coords)
    with urllib.request.urlopen(url, timeout=30, context=SSL_CTX) as resp:
        data = json.load(resp)
    if data.get("code") != "Ok" or not data.get("routes"):
        raise RuntimeError(f"OSRM-Fehler: {data.get('code')} / {data.get('message')}")
    route = data["routes"][0]
    geo = route["geometry"]["coordinates"]   # [[lon, lat], ...]
    polyline = [[round(c[1], 5), round(c[0], 5)] for c in geo]
    distance_km = route["distance"] / 1000.0
    return polyline, distance_km


def main():
    net = json.loads(ROADNET.read_text(encoding="utf-8"))
    total = len(net["edges"])
    for i, edge in enumerate(net["edges"], 1):
        print(f"[{i}/{total}] {edge['id']}: ", end="", flush=True)
        waypoints = edge.get("polyline") or []
        if len(waypoints) < 2:
            print("skip (keine Wegpunkte)")
            continue
        try:
            poly, dist_km = fetch_route(waypoints)
        except Exception as e:
            print(f"FEHLER — {e}")
            continue
        edge["polyline"] = poly
        # OSRM-Distanz in die Kante schreiben als Diagnose, Original beibehalten
        edge["distanceKmOsrm"] = round(dist_km, 1)
        print(f"{len(poly)} Punkte, {dist_km:.0f} km (hand: {edge.get('distanceKm')})")
        time.sleep(1.1)   # OSRM-Demo: ~1 req/s, nicht mehr

    ROADNET.write_text(
        json.dumps(net, ensure_ascii=False, indent=2),
        encoding="utf-8",
    )
    print(f"\nFertig — {ROADNET} aktualisiert.")


if __name__ == "__main__":
    main()
