#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=ai/tools/approved-action-dispatcher/lib.sh
source "$script_dir/lib.sh"
aad_init

mode="text"
case "${1:-}" in
  --json) mode="json" ;;
  --kv) mode="kv" ;;
  "" ) ;;
  -h | --help) echo "Usage: ai/tools/approved-action-dispatcher/status.sh [--json|--kv]"; exit 0 ;;
  *) echo "approved action dispatcher status error: unknown argument: $1" >&2; exit 2 ;;
esac

heartbeat_age="unknown"
if [[ -f "$AAD_HEARTBEAT_FILE" ]]; then
  now="$(date +%s)"
  mtime="$(stat -c '%Y' "$AAD_HEARTBEAT_FILE" 2>/dev/null || stat -f '%m' "$AAD_HEARTBEAT_FILE" 2>/dev/null || true)"
  [[ "$mtime" =~ ^[0-9]+$ ]] && heartbeat_age="$((now - mtime))"
fi
results="$(find "$AAD_RESULT_DIR" -type f -name '*.env' 2>/dev/null | wc -l | tr -d ' ')"
last_result="$(find "$AAD_RESULT_DIR" -type f -name '*.env' -printf '%T@ %p\n' 2>/dev/null | sort -n | tail -1 | awk '{print $2}')"
approved_json="$(OQ_SKIP_CONSUME_PENDING=true "$AAD_REPO_ROOT/ai/tools/operator-questions/list-approved-actions.sh" --json --all)"
pending="$(printf '%s\n' "$approved_json" | node -e "let s='';process.stdin.on('data',d=>s+=d);process.stdin.on('end',()=>{const j=JSON.parse(s); console.log(j.approved_unexecuted_count || 0);})")"
stale="$(printf '%s\n' "$approved_json" | node -e "let s='';process.stdin.on('data',d=>s+=d);process.stdin.on('end',()=>{const j=JSON.parse(s); console.log(j.stale_count || 0);})")"
failed="$(node -e '
const fs = require("node:fs");
const path = require("node:path");
const resultDir = process.argv[1];
const approved = JSON.parse(process.argv[2] || "{}");
const inactive = new Set(["executed", "resolved_stale", "ignored"]);
const actionById = new Map((approved.actions || []).map((item) => [item.question_id, item]));
let count = 0;
if (fs.existsSync(resultDir)) {
  for (const name of fs.readdirSync(resultDir).filter((item) => item.endsWith(".env"))) {
    const text = fs.readFileSync(path.join(resultDir, name), "utf8");
    if (!/^status=failed$/m.test(text)) continue;
    const qid = name.replace(/\.env$/, "");
    const action = actionById.get(qid);
    if (action && inactive.has(action.execution_status || "")) continue;
    count += 1;
  }
}
console.log(count);
' "$AAD_RESULT_DIR" "$approved_json")"
status="not_running"
health="down"
if [[ "$heartbeat_age" =~ ^[0-9]+$ ]]; then
  if (( heartbeat_age <= 10 )); then
    status="running"
    health="$([[ "$failed" == "0" ]] && echo healthy || echo degraded)"
  else
    status="stale"
    health="degraded"
  fi
fi

if [[ "$mode" == "kv" ]]; then
  printf 'state_dir=%q\n' "$AAD_STATE_DIR"
  printf 'status=%q\n' "$status"
  printf 'health=%q\n' "$health"
  printf 'heartbeat_age_seconds=%q\n' "$heartbeat_age"
  printf 'results=%s\n' "$results"
  printf 'approved_pending=%s\n' "$pending"
  printf 'approved_stale=%s\n' "$stale"
  printf 'failed=%s\n' "$failed"
  printf 'last_result=%q\n' "${last_result:-}"
  exit 0
fi

if [[ "$mode" == "json" ]]; then
  node - "$AAD_STATE_DIR" "$status" "$health" "$heartbeat_age" "$results" "$pending" "$stale" "$failed" "${last_result:-}" <<'NODE'
const [stateDir, status, health, heartbeatAge, results, pending, stale, failed, lastResult] = process.argv.slice(2);
console.log(JSON.stringify({
  state_dir: stateDir,
  status,
  health,
  heartbeat_age_seconds: /^\d+$/.test(heartbeatAge) ? Number(heartbeatAge) : null,
  results: Number(results),
  approved_pending: Number(pending),
  approved_stale: Number(stale),
  failed: Number(failed),
  last_result: lastResult,
}, null, 2));
NODE
  exit 0
fi

printf 'Approved Action Dispatcher\n'
printf 'State dir: %s\n' "$AAD_STATE_DIR"
printf 'Status: %s\n' "$status"
printf 'Health: %s\n' "$health"
printf 'Heartbeat age seconds: %s\n' "$heartbeat_age"
printf 'Results: %s\n' "$results"
printf 'Approved pending: %s\n' "$pending"
printf 'Approved stale: %s\n' "$stale"
printf 'Failed results: %s\n' "$failed"
printf 'Last result: %s\n' "${last_result:-none}"
