#!/usr/bin/env bash
# AgentOS 进程健康巡检：进程不存在或心跳 ACK 僵死则 restart
set -euo pipefail

export PATH="${HOME}/.npm-global/bin:/usr/local/bin:${PATH:-/usr/bin:/bin}"

LOG="${HOME}/.xyt-agent/logs/xyt-client.log"
PID_FILE="${HOME}/.xyt-agent/xyt-client.pid"
STALE_SEC="${AGENTOS_WS_STALE_SEC:-120}"
MIN_UNMATCHED="${AGENTOS_WS_MIN_UNMATCHED:-3}"

if ! command -v xyt-client >/dev/null 2>&1; then
  echo "[watchdog] xyt-client not in PATH"
  exit 0
fi

if [[ ! -f "$LOG" ]]; then
  echo "[watchdog] no log yet, starting"
  xyt-client start 2>/dev/null || true
  exit 0
fi

if [[ ! -f "$PID_FILE" ]] || ! kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
  echo "[watchdog] agentos not running, starting"
  export FORCE_CONTAINER_MODE="${FORCE_CONTAINER_MODE:-true}"
  xyt-client start 2>/dev/null || true
  exit 0
fi

python3 - <<PY
import os, re, subprocess, time
from datetime import datetime

log_path = os.path.expanduser("${LOG}")
stale_sec = int("${STALE_SEC}")
min_unmatched = int("${MIN_UNMATCHED}")

text = open(log_path, encoding="utf-8", errors="ignore").read().splitlines()
last_ack_line = None
last_ack_idx = -1
for i, line in enumerate(text):
    if "心跳响应:" in line:
        last_ack_line = line
        last_ack_idx = i

unmatched = 0
if last_ack_idx >= 0:
    for line in text[last_ack_idx + 1:]:
        if "已发送心跳" in line:
            unmatched += 1

reason = None
if last_ack_line is None:
    reason = "no heartbeat ack in log"
elif unmatched >= min_unmatched:
    reason = f"{unmatched} heartbeats without ack after last response"
else:
    m = re.search(r"心跳响应:\s*(.+)$", last_ack_line)
    if m:
        try:
            ts = datetime.strptime(m.group(1).strip(), "%m/%d/%Y, %I:%M:%S %p")
            ts = ts.replace(year=datetime.now().year)
            age = (datetime.now() - ts).total_seconds()
            if age > stale_sec and unmatched > 0:
                reason = f"last ack {int(age)}s ago"
        except Exception:
            pass

if not reason:
    print(f"[watchdog] ok unmatched={unmatched}")
    raise SystemExit(0)

print(f"[watchdog] restart: {reason}")
subprocess.run(
    "export PATH=$HOME/.npm-global/bin:/usr/local/bin:$PATH; "
    "export FORCE_CONTAINER_MODE=${FORCE_CONTAINER_MODE:-true}; "
    "xyt-client restart",
    shell=True,
    executable="/bin/bash",
)
PY
