"""Demo Agent 1: Weather Agent -- server only, called by the Orchestrator.
This is a throwaway test fixture, not a real weather service: it returns
canned data for a small set of cities so the end-to-end A2A chain has
something real to call.
"""
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent))

import uvicorn
from a2a.helpers import get_data_parts, new_data_part, new_task_from_user_message
from a2a.server.agent_execution import AgentExecutor, RequestContext
from a2a.server.events import EventQueue
from a2a.server.tasks import TaskUpdater
from a2a.types import AgentCapabilities, AgentCard, AgentInterface, AgentSkill
from a2a.types.a2a_pb2 import TaskState

from a2a_passport import build_agent_app
from a2a_passport.auth.verifiers import SharedSecretVerifier
from a2a_passport.testing import JWT_SECRET

PORT = 9201
AUDIENCE = "weather-agent"
REQUIRED_SCOPE = "weather:read"

_FAKE_WEATHER = {
    "paris": {"condition": "light rain", "temp_c": 17},
    "tokyo": {"condition": "humid, partly cloudy", "temp_c": 29},
    "bengaluru": {"condition": "clear", "temp_c": 24},
}


class WeatherExecutor(AgentExecutor):
    async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
        task = context.current_task or new_task_from_user_message(context.message)
        if not context.current_task:
            await event_queue.enqueue_event(task)
        updater = TaskUpdater(event_queue=event_queue, task_id=task.id, context_id=task.context_id)
        await updater.update_status(state=TaskState.TASK_STATE_WORKING)

        incoming = get_data_parts(context.message.parts)
        request = incoming[0] if incoming else {}
        city = str(request.get("city", "")).strip().lower()
        info = _FAKE_WEATHER.get(city, {"condition": "unknown", "temp_c": None})

        result = {"city": request.get("city"), **info}
        await updater.add_artifact(parts=[new_data_part(data=result)], name="weather_result")
        await updater.update_status(state=TaskState.TASK_STATE_COMPLETED)

    async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
        raise NotImplementedError("cancel is not supported by the weather agent demo")


def build_app():
    skill = AgentSkill(
        id="get_weather",
        name="Get Weather",
        description="Returns current weather conditions for a supported city.",
        input_modes=["application/json"],
        output_modes=["application/json"],
        tags=["demo", "weather"],
        examples=['{"city": "Paris"}'],
    )
    card = AgentCard(
        name="Weather Agent",
        description="Demo agent providing canned weather data.",
        version="0.1.0",
        default_input_modes=["application/json"],
        default_output_modes=["application/json"],
        capabilities=AgentCapabilities(streaming=False),
        supported_interfaces=[AgentInterface(protocol_binding="JSONRPC", url=f"http://127.0.0.1:{PORT}")],
        skills=[skill],
    )
    # SharedSecretVerifier + the mock IdP is the dev/demo pairing. In
    # production, swap this one line for:
    #   JWKSVerifier(jwks_uri="https://your-idp/.well-known/jwks.json", issuer="https://your-idp/")
    # -- nothing else in this file changes.
    return build_agent_app(
        card=card,
        executor=WeatherExecutor(),
        verifier=SharedSecretVerifier(JWT_SECRET),
        expected_audience=AUDIENCE,
        required_scope=REQUIRED_SCOPE,
        service_name="weather-agent",
    )


if __name__ == "__main__":
    uvicorn.run(build_app(), host="127.0.0.1", port=PORT)
