"""Update management API endpoints.""" from typing import Optional from fastapi import APIRouter, HTTPException from pydantic import BaseModel from ..managers.update_manager import get_update_manager, UpdateStatus from ..managers.ble_manager import get_ble_manager, NotificationType router = APIRouter() class UpdateCheckResponse(BaseModel): """Response model for update check.""" update_available: bool current_version: str latest_version: Optional[str] = None release_date: Optional[str] = None changelog: Optional[str] = None is_prerelease: bool = False download_size: Optional[int] = None message: Optional[str] = None class UpdateProgressResponse(BaseModel): """Response model for update progress.""" status: str current_version: str available_version: Optional[str] = None download_progress: float = 0.0 error_message: Optional[str] = None last_check: Optional[str] = None class ReleaseNotesRequest(BaseModel): """Request model for release notes.""" version: Optional[str] = None @router.get("/check", response_model=UpdateCheckResponse) async def check_for_updates(): """Check for available updates. Returns: UpdateCheckResponse with update status and info """ try: manager = get_update_manager() ble_manager = get_ble_manager() result = await manager.check_for_updates() # Send BLE notification if update is available if result.get("update_available"): await ble_manager.send_notification( NotificationType.UPDATE_AVAILABLE, f"Update available: v{result['latest_version']}", {"version": result["latest_version"]} ) return UpdateCheckResponse(**result) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/progress", response_model=UpdateProgressResponse) async def get_update_progress(): """Get current update progress. Returns: UpdateProgressResponse with current status """ try: manager = get_update_manager() progress = await manager.get_progress() return UpdateProgressResponse( status=progress.status.value, current_version=progress.current_version, available_version=progress.available_version, download_progress=progress.download_progress, error_message=progress.error_message, last_check=progress.last_check ) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/download") async def download_update(): """Download the available update. Returns: Success message """ try: manager = get_update_manager() success = await manager.download_update() if success: return {"message": "Update downloaded successfully"} else: raise HTTPException(status_code=500, detail="Download failed") except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/install") async def install_update(): """Install the downloaded update. Returns: Success message """ try: manager = get_update_manager() ble_manager = get_ble_manager() success = await manager.install_update() if success: # Send BLE notification await ble_manager.send_notification( NotificationType.UPDATE_COMPLETE, "Update installed successfully", {"restart_required": True} ) return { "message": "Update installed successfully. Please restart the service.", "restart_required": True } else: raise HTTPException(status_code=500, detail="Installation failed") except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/release-notes", response_model=dict) async def get_release_notes(request: ReleaseNotesRequest): """Get release notes for a specific version. Args: request: Version to get notes for (latest if not specified) Returns: Release notes as markdown """ try: manager = get_update_manager() notes = await manager.get_release_notes(request.version) return { "version": request.version or "latest", "notes": notes } except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/current-version") async def get_current_version(): """Get current system version. Returns: Current version info """ try: manager = get_update_manager() progress = await manager.get_progress() return { "version": progress.current_version, "last_check": progress.last_check } except Exception as e: raise HTTPException(status_code=500, detail=str(e))