"""FastAPI server streaming wormhole wireframe data and static assets."""

from __future__ import annotations

import argparse
import json
import os
from pathlib import Path
from typing import Any, Dict, Optional

from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse, HTMLResponse
from fastapi.staticfiles import StaticFiles
import uvicorn

_STATE_PATH: Optional[Path] = None
_SUMMARY_PATH: Optional[Path] = None
_HOTSPOT_PATH: Optional[Path] = None
_static_dir = Path(__file__).parent / "static"
_default_summary = Path(__file__).resolve().parents[2] / "artifacts" / "relativistic_suite" / "gr_metric_summary.json"
_default_hotspots = Path(__file__).resolve().parents[2] / "artifacts" / "relativistic_suite" / "gr_hotspots.json"

app = FastAPI(title="Wormhole Wireframe", version="1.0.0")
app.mount("/assets", StaticFiles(directory=_static_dir), name="assets")


def _resolve_state_path() -> Path:
    global _STATE_PATH
    if _STATE_PATH is None:
        env_path = os.getenv("WORMHOLE_WIREFRAME_FEED")
        if env_path:
            candidate = Path(env_path)
            if candidate.exists():
                _STATE_PATH = candidate
    if _STATE_PATH is None:
        raise HTTPException(status_code=500, detail="Wireframe feed path not configured")
    return _STATE_PATH


def _resolve_summary_path() -> Path:
    global _SUMMARY_PATH
    if _SUMMARY_PATH is None:
        env_path = os.getenv("WORMHOLE_GR_SUMMARY")
        if env_path:
            candidate = Path(env_path)
            if candidate.exists():
                _SUMMARY_PATH = candidate
    if _SUMMARY_PATH is None:
        if _default_summary.exists():
            _SUMMARY_PATH = _default_summary
        else:
            raise HTTPException(status_code=404, detail="Diagnostics summary not configured")
    return _SUMMARY_PATH


def _resolve_hotspot_path() -> Optional[Path]:
    global _HOTSPOT_PATH
    if _HOTSPOT_PATH is None:
        env_path = os.getenv("WORMHOLE_GR_HOTSPOTS")
        if env_path:
            candidate = Path(env_path)
            if candidate.exists():
                _HOTSPOT_PATH = candidate
    if _HOTSPOT_PATH is None and _default_hotspots.exists():
        _HOTSPOT_PATH = _default_hotspots
    return _HOTSPOT_PATH


def _load_state() -> Dict[str, Any]:
    path = _resolve_state_path()
    if not path.exists():
        raise HTTPException(status_code=404, detail=f"Feed {path} not found")
    try:
        return json.loads(path.read_text(encoding="utf-8"))
    except json.JSONDecodeError as exc:
        raise HTTPException(status_code=500, detail=f"Malformed JSON feed: {exc}") from exc


def _load_summary() -> Dict[str, Any]:
    path = _resolve_summary_path()
    if not path.exists():
        raise HTTPException(status_code=404, detail=f"Diagnostics summary {path} not found")
    try:
        return json.loads(path.read_text(encoding="utf-8"))
    except json.JSONDecodeError as exc:
        raise HTTPException(status_code=500, detail=f"Malformed diagnostics summary: {exc}") from exc


def _load_hotspots() -> Optional[Dict[str, Any]]:
    path = _resolve_hotspot_path()
    if path is None:
        return None
    if not path.exists():
        return None
    try:
        return json.loads(path.read_text(encoding="utf-8"))
    except json.JSONDecodeError:
        return None


@app.get("/state")
def get_state() -> Dict[str, Any]:
    """Return the latest wormhole experiment snapshot."""
    return _load_state()


@app.get("/diagnostics")
def get_diagnostics() -> Dict[str, Any]:
    """Return GR analogue diagnostics summary for highlighting hotspots."""
    summary = _load_summary()
    hotspot_payload = _load_hotspots()
    if hotspot_payload:
        summary = dict(summary)
        summary.setdefault("hotspot_snapshots", hotspot_payload)
    return summary


@app.get("/", response_class=HTMLResponse)
def index() -> str:
    """Serve the wireframe viewer shell."""
    index_path = _static_dir / "index.html"
    if not index_path.exists():
        raise HTTPException(status_code=500, detail="index.html missing from static assets")
    return index_path.read_text(encoding="utf-8")


@app.get("/assets/{asset_name}")
def get_asset(asset_name: str) -> FileResponse:
    asset_path = _static_dir / asset_name
    if not asset_path.exists():
        raise HTTPException(status_code=404, detail=f"Asset {asset_name} not found")
    return FileResponse(asset_path)


def main() -> None:
    parser = argparse.ArgumentParser(description="Run the wormhole wireframe server")
    parser.add_argument("--feed", type=Path, required=True, help="Path to wireframe JSON feed")
    parser.add_argument(
        "--summary",
        type=Path,
        default=_default_summary,
        help="Path to GR diagnostics summary JSON",
    )
    parser.add_argument(
        "--hotspots",
        type=Path,
        default=_default_hotspots,
        help="Path to GR hotspot snapshot JSON",
    )
    parser.add_argument("--host", type=str, default="0.0.0.0")
    parser.add_argument("--port", type=int, default=8765)
    args = parser.parse_args()

    global _STATE_PATH
    _STATE_PATH = args.feed.resolve()
    os.environ["WORMHOLE_WIREFRAME_FEED"] = str(_STATE_PATH)

    global _SUMMARY_PATH
    if args.summary:
        _SUMMARY_PATH = args.summary.resolve()
        os.environ["WORMHOLE_GR_SUMMARY"] = str(_SUMMARY_PATH)

    global _HOTSPOT_PATH
    if args.hotspots:
        _HOTSPOT_PATH = args.hotspots.resolve()
        os.environ["WORMHOLE_GR_HOTSPOTS"] = str(_HOTSPOT_PATH)

    uvicorn.run("wormhole_proof.wireframe.server:app", host=args.host, port=args.port, reload=False)


if __name__ == "__main__":
    main()
