# Copyright (C) 2026 GoodData Corporation

"""Context-like adapter that emits progress events to stdout.

This is used by "external JSON" runners that still call the in-repo Python validators:
instead of sending MCP progress to a client directly, they print `AIDA_EVENT ...`
lines. The parent `validate` tool can stream/parse those lines and forward them to the
real MCP Context.
"""

from __future__ import annotations

import sys
from dataclasses import dataclass
from typing import Any

from aida_mcp.output.progress_events import format_event


@dataclass(slots=True)
class EventEmittingContext:
    """Minimal subset of FastMCP Context used by our validators."""

    tool: str

    async def info(self, message: str) -> None:
        self._emit({"kind": "info", "tool": self.tool, "message": str(message)})

    async def report_progress(self, progress: float, total: float | None = None, message: str | None = None) -> None:
        payload: dict[str, object] = {"kind": "progress", "tool": self.tool, "progress": float(progress)}
        if total is not None:
            payload["total"] = float(total)
        if message:
            payload["message"] = str(message)
        self._emit(payload)

    def _emit(self, payload: dict[str, object]) -> None:
        try:
            sys.stdout.write(format_event(payload))
            sys.stdout.write("\n")
            sys.stdout.flush()
        except Exception:
            # External runners must never crash because progress couldn't be emitted.
            return


def maybe_event_ctx(*, enabled: bool, tool: str) -> Any | None:
    """Helper for external runners: return event ctx when enabled."""
    return EventEmittingContext(tool=tool) if enabled else None
