"""
engine.dispatcher — Route execution requests to sync/async/stream modes.
"""
from __future__ import annotations
import json
from typing import Any, AsyncIterator
from agentpaas.engine.sandbox import Sandbox, ExecutionResult, ResourceLimits
from agentpaas.engine.cache import CompileCache
from agentpaas.engine.queue import Job, create_queue
from agentpaas.config import settings


_compile_cache = CompileCache()
_job_queue = None
_sandbox = None


def get_sandbox() -> Sandbox:
    global _sandbox
    if _sandbox is None:
        _sandbox = Sandbox(level=settings.sandbox_level, limits=ResourceLimits(
            max_steps=settings.max_steps, max_tokens=settings.max_tokens,
        ))
    return _sandbox


def get_queue():
    global _job_queue
    if _job_queue is None:
        _job_queue = create_queue(settings.redis_url)
    return _job_queue


async def dispatch_sync(config: dict, input_text: str, timeout: int = None) -> ExecutionResult:
    """Synchronous execution via sandbox."""
    sandbox = get_sandbox()
    return await sandbox.execute(config, input_text, timeout or settings.default_timeout)


async def dispatch_async(job: Job) -> str:
    """Enqueue for async execution. Returns job_id."""
    queue = get_queue()
    return await queue.enqueue(job)


async def dispatch_stream(config: dict, input_text: str) -> AsyncIterator[dict]:
    """SSE stream execution — yields step events."""
    # For MVP, execute synchronously and yield result as single event
    result = await dispatch_sync(config, input_text)
    yield {"event": "step", "data": {"step": 1, "type": "answer", "content": result.output}}
    yield {"event": "done", "data": {"status": result.status, "duration_ms": result.duration_ms}}
