import json import logging from fastapi import APIRouter, Depends, Request, status from fastapi.responses import PlainTextResponse, Response from pydantic import ValidationError from sqlalchemy.orm import Session from app.dependencies import get_db from app.schemas.homeassistant import HomeAssistantPublishEnvelope from app.services.homeassistant_inbound import ( UnsupportedHomeAssistantMessage, handle_homeassistant_message, ) router = APIRouter(tags=["homeassistant"]) logger = logging.getLogger(__name__) BAD_REQUEST_MESSAGE = "bad request" INTERNAL_SERVER_ERROR_MESSAGE = "internal server error" @router.post("/homeassistant/publish") async def publish_from_homeassistant( request: Request, db: Session = Depends(get_db) ) -> Response: try: raw_payload = await request.body() data = json.loads(raw_payload) envelope = HomeAssistantPublishEnvelope.model_validate(data) handle_homeassistant_message(db, envelope) except json.JSONDecodeError as exc: logger.warning("Rejected Home Assistant publish request due to invalid JSON: %s", exc) return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=status.HTTP_400_BAD_REQUEST) except ValidationError as exc: logger.warning( "Rejected Home Assistant publish request due to validation failure: %s", exc ) return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=status.HTTP_400_BAD_REQUEST) except UnsupportedHomeAssistantMessage as exc: logger.warning("Home Assistant publish target/action unsupported: %s", exc) return PlainTextResponse( INTERNAL_SERVER_ERROR_MESSAGE, status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, ) except ValueError as exc: logger.warning("Rejected Home Assistant publish request due to invalid content: %s", exc) return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=status.HTTP_400_BAD_REQUEST) return Response(status_code=status.HTTP_200_OK)