"""Context injection (#255): fetch the RStack context packet via
`rstack-agents context` for prepending to the user's prompt through Tau's real
`input` hook (see the package docstring for why the documented
`before_agent_start` hook is not used).

owner: RStack developed by Richardson Gunde; Tau adapter contributed by Jeomon
"""
from __future__ import annotations

import asyncio
import json
import os

from .proc import _communicate_or_kill, _own_process_group_kwargs
from .resolve import _resolve_bin_argv


async def _fetch_context(cwd: str) -> str:
    """Fetch the RStack context packet via `rstack-agents context` (#255).

    Returns the `additionalContext` string, or "" when there is no active run,
    no context, or anything goes wrong. Best-effort and hard-timeout-bounded:
    this runs on the before_agent_start critical path, so it must never block a
    turn — every failure path returns "" and the turn proceeds unchanged.
    """
    # G-09 (#552): local binary preferred over `npx --yes` — see resolve.py.
    argv_prefix, _needs_network = _resolve_bin_argv("rstack-agents", cwd)
    if argv_prefix is None:
        return ""
    try:
        proc = await asyncio.create_subprocess_exec(
            *argv_prefix, "context", "--source", "tau", "--project", cwd,
            stdin=asyncio.subprocess.DEVNULL,
            stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.DEVNULL,
            env=os.environ, cwd=cwd,
            **_own_process_group_kwargs(),
        )
        # #487: same kill-without-reap gap as _emit_observation — the
        # timeout fired but the broad except swallowed it before any kill.
        out, _ = await _communicate_or_kill(proc, None, timeout=5.0)
    except Exception:
        return ""  # context is additive — never let it break or delay a turn
    text = out.decode("utf-8", "replace").strip()
    if not text:
        return ""
    try:
        data = json.loads(text)
        ctx = data.get("hookSpecificOutput", {}).get("additionalContext", "")
        return str(ctx) if ctx else ""
    except Exception:
        return ""
