"""tmux-pilot Hermes plugin.

Writes two per-agent files for subagents launched by tmux-pilot:

- a JSONL session mirror ($PI_TMUX_MIRROR_FILE) — one line per hook event
  (session_start / api / tool / end), parsed by tmux-pilot's
  analyzeHermesSessionFile(); tmux-pilot never reads hermes' SQLite store.
- a line-structured lifecycle-end sentinel ($PI_TMUX_END_FILE) — a
  {"completed": bool, "interrupted": bool} line appended on every
  on_session_end, truncated (re-armed) on pre_api_request so a mid-turn
  steer interrupt never reads as terminal.

Env-gated: every callback returns immediately unless BOTH env vars are set.
tmux-pilot's launch command sets them; the user's own hermes sessions never
do, so the permanently-installed plugin is inert outside tmux-pilot spawns.

All writes are best-effort — an IO error must never raise into hermes.
"""

import json
import os
import time


def _paths():
    """Return (mirror, end) paths, or None when not launched by tmux-pilot."""
    mirror = os.environ.get("PI_TMUX_MIRROR_FILE")
    end = os.environ.get("PI_TMUX_END_FILE")
    if not mirror or not end:
        return None
    return mirror, end


def _append_line(path, obj):
    """Append one JSON line. Best-effort — never raises into hermes."""
    try:
        line = json.dumps(obj, ensure_ascii=False, default=str)
        with open(path, "a", encoding="utf-8") as f:
            f.write(line + "\n")
    except Exception:
        pass


def _now_ms():
    return int(time.time() * 1000)


def _on_session_start(**kwargs):
    paths = _paths()
    if paths is None:
        return
    mirror, _end = paths
    _append_line(
        mirror,
        {
            "type": "session_start",
            "session_id": kwargs.get("session_id"),
            "model": kwargs.get("model"),
            "ts": _now_ms(),
        },
    )


def _pre_api_request(**kwargs):
    """Re-arm the end sentinel: a new turn (or a steer resumption) is running."""
    paths = _paths()
    if paths is None:
        return
    _mirror, end = paths
    try:
        if os.path.exists(end):
            with open(end, "w", encoding="utf-8"):
                pass
    except Exception:
        pass


def _post_api_request(**kwargs):
    paths = _paths()
    if paths is None:
        return
    mirror, _end = paths

    usage = kwargs.get("usage")
    if not isinstance(usage, dict):
        usage = {}

    # Final assistant text lives at response.assistant_message.content
    # (sanitized dict — spike-verified payload shape).
    content = None
    response = kwargs.get("response")
    if isinstance(response, dict):
        assistant = response.get("assistant_message")
        if isinstance(assistant, dict):
            raw = assistant.get("content")
            if isinstance(raw, str):
                content = raw

    _append_line(
        mirror,
        {
            "type": "api",
            "turn_id": kwargs.get("turn_id"),
            "finish_reason": kwargs.get("finish_reason"),
            "usage": {
                "prompt_tokens": usage.get("prompt_tokens"),
                "total_tokens": usage.get("total_tokens"),
            },
            "content": content,
            "tool_call_count": kwargs.get("assistant_tool_call_count"),
            "ts": _now_ms(),
        },
    )


def _post_tool_call(**kwargs):
    paths = _paths()
    if paths is None:
        return
    mirror, _end = paths
    _append_line(
        mirror,
        {
            "type": "tool",
            "turn_id": kwargs.get("turn_id"),
            "tool_name": kwargs.get("tool_name"),
            "status": kwargs.get("status"),
            "duration_ms": kwargs.get("duration_ms"),
            "ts": _now_ms(),
        },
    )


def _on_session_end(**kwargs):
    paths = _paths()
    if paths is None:
        return
    mirror, end = paths
    completed = bool(kwargs.get("completed"))
    interrupted = bool(kwargs.get("interrupted"))
    _append_line(
        mirror,
        {
            "type": "end",
            "turn_id": kwargs.get("turn_id"),
            "completed": completed,
            "interrupted": interrupted,
            "ts": _now_ms(),
        },
    )
    _append_line(
        end,
        {
            "completed": completed,
            "interrupted": interrupted,
            "turn_id": kwargs.get("turn_id"),
            "ts": _now_ms(),
        },
    )


def register(ctx):
    ctx.register_hook("on_session_start", _on_session_start)
    ctx.register_hook("pre_api_request", _pre_api_request)
    ctx.register_hook("post_api_request", _post_api_request)
    ctx.register_hook("post_tool_call", _post_tool_call)
    ctx.register_hook("on_session_end", _on_session_end)
