"""Server-side SDK surface. App teams provide an AgentCard + an AgentExecutor
(their actual agent logic) and a TokenVerifier, and get a fully wired FastAPI
app back -- auth enforcement and the A2A protocol routes are handled here
once, instead of every team doing it themselves. Tracing is opt-in via
`instrument` (requires the `otel` extra).
"""
from __future__ import annotations

from a2a.server.agent_execution import AgentExecutor
from a2a.server.request_handlers import DefaultRequestHandler
from a2a.server.routes import (
    add_a2a_routes_to_fastapi,
    create_agent_card_routes,
    create_jsonrpc_routes,
)
from a2a.server.tasks import InMemoryTaskStore, TaskStore
from a2a.types import AgentCard
from fastapi import FastAPI

from a2a_passport.auth.base import TokenVerifier
from a2a_passport.auth.middleware import PassportAuthMiddleware


def build_agent_app(
    *,
    card: AgentCard,
    executor: AgentExecutor,
    verifier: TokenVerifier,
    expected_audience: str,
    required_scope: str | None = None,
    task_store: TaskStore | None = None,
    instrument: bool = False,
    service_name: str | None = None,
) -> FastAPI:
    """Build a ready-to-run FastAPI app for one A2A agent.

    Give it your AgentCard, your AgentExecutor (the actual agent logic), and
    a TokenVerifier (SharedSecretVerifier for dev, JWKSVerifier for
    production -- see a2a_passport.auth.verifiers), and it returns an app
    with the JSON-RPC + agent-card routes mounted and auth enforced on every
    non-card endpoint. Run it with:
        uvicorn.run(app, host=..., port=...)

    `task_store` defaults to an in-memory store, fine for single-instance
    deployments; pass a persistent implementation for multi-instance ones.
    """
    handler = DefaultRequestHandler(
        agent_executor=executor,
        task_store=task_store or InMemoryTaskStore(),
        agent_card=card,
    )

    app = FastAPI(title=card.name)
    add_a2a_routes_to_fastapi(
        app,
        agent_card_routes=create_agent_card_routes(card),
        jsonrpc_routes=create_jsonrpc_routes(handler, "/"),
    )
    app.add_middleware(
        PassportAuthMiddleware,
        verifier=verifier,
        expected_audience=expected_audience,
        required_scope=required_scope,
    )

    if instrument:
        from a2a_passport.tracing import instrument_asgi_app

        instrument_asgi_app(app, service_name=service_name or card.name)

    return app
