from __future__ import annotations from pathlib import Path from fastapi import APIRouter, Depends, HTTPException from fastapi.responses import FileResponse from backend.api.schemas import HealthResponse, SimulationStartRequest, SimulationStartResponse, SimulationStopResponse from backend.services.simulation_manager import SimulationManager from backend.utils import safe_join def get_router(simulation_manager: SimulationManager, file_root: Path) -> APIRouter: router = APIRouter() @router.get("/health", response_model=HealthResponse) async def health() -> HealthResponse: return HealthResponse() @router.get("/api/devices") async def devices(): runtime = simulation_manager.current() return { "data": [ { "device_id": "controlbox_01", "device_type": "mock_vehicle", "connected": bool(runtime and runtime.status == "running"), } ] } @router.post("/api/simulation/start", response_model=SimulationStartResponse) async def start_simulation(body: SimulationStartRequest) -> SimulationStartResponse: simulation_id = await simulation_manager.start(body.model_dump()) return SimulationStartResponse(simulation_id=simulation_id) @router.post("/api/simulation/{simulation_id}/stop", response_model=SimulationStopResponse) async def stop_simulation(simulation_id: str) -> SimulationStopResponse: await simulation_manager.stop(simulation_id) return SimulationStopResponse(simulation_id=simulation_id, status="stopped") @router.get("/files/{file_path:path}") async def files(file_path: str): try: resolved = safe_join(file_root, file_path) except ValueError: raise HTTPException(status_code=400, detail="invalid path") if not resolved.exists() or not resolved.is_file(): raise HTTPException(status_code=404, detail="not found") return FileResponse(str(resolved)) return router