import os
from datetime import datetime, timezone
from uuid import UUID

from fastapi import FastAPI, HTTPException
from shieldlabs import ShieldLabs, ShieldLabsError

app = FastAPI()
client = ShieldLabs(api_key=os.environ["SHIELDLABS_API_KEY"])
expected_domain = os.environ["SHIELDLABS_DOMAIN"]

@app.get("/identification/{request_id}")
def read_identification(request_id: UUID):
    try:
        result = client.identifications.get(str(request_id), timeout=5)
    except ShieldLabsError:
        raise HTTPException(503, "Identification service unavailable")
    if result is None:
        raise HTTPException(409, "Identification pending or unavailable")
    if result.domain != expected_domain:
        raise HTTPException(403, "Unexpected domain")
    if result.observed_at is None:
        raise HTTPException(409, "Observation time unavailable")
    age = (datetime.now(timezone.utc) - result.observed_at).total_seconds()
    if not 0 <= age <= 300:
        raise HTTPException(409, "Observation is not current")
    if result.is_rate_limited:
        raise HTTPException(409, "Identification rate limited")
    return {
        "request_id": result.request_id,
        "risk_score": result.risk_score,
        "risk_band": result.risk_band,
        "signals": [signal.name for signal in result.signals],
    }

from fastapi import Request
from shieldlabs import IdentificationScoredEvent, webhooks
from shieldlabs import SignatureVerificationError, WebhookParseError

@app.post("/shieldlabs/webhook")
async def receive_webhook(request: Request):
    raw_body = await request.body()
    try:
        event = webhooks.construct_event(
            raw_body,
            request.headers.get("X-Shield-Signature"),
            os.environ["SHIELDLABS_WEBHOOK_SECRET"],
        )
    except (SignatureVerificationError, WebhookParseError):
        raise HTTPException(400, "Invalid webhook")
    if isinstance(event, IdentificationScoredEvent):
        # Persist event.data by request_id in a durable queue or database.
        # This demonstration validates the delivery without storing it.
        return {"received": True, "event_type": event.event_type}
    return {"received": True}
