#!/usr/bin/env bash
# CodeBuddy Hook 脚本 — 由 cls-codingagent 注入到 ~/.codebuddy/settings.json
#
# CodeBuddy 触发 hook 时，通过 stdin 传入 JSON 事件数据。
# 本脚本将事件委托给 codebuddy-hook-processor.mjs 处理：
#   - stop:           解析 transcript，写 JSONL 供 HookInput 消费
#   - subagent-start: 记录子 session 状态
#   - subagent-stop:  合并子 session 状态
#   - 其余事件:       直接忽略（fail-open）
#
# 设计原则（fail-open）：
#   - hook 脚本绝不阻塞 CodeBuddy 执行
#   - 任何错误都静默处理，输出 "{}" 并 exit 0
#   - 超时由 CodeBuddy 的 hook timeout 控制（默认 10s）

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROCESSOR="$SCRIPT_DIR/codebuddy-hook-processor.mjs"
EMPTY_RESULT='{}'
SUBCOMMAND="${1:-unknown}"

# 只处理已注册的 3 个 subcommand，其余直接返回
case "$SUBCOMMAND" in
  stop|subagent-start|subagent-stop)
    ;;
  *)
    printf '%s\n' "$EMPTY_RESULT"
    exit 0
    ;;
esac

log_error() {
  local stage="$1"
  local message="$2"
  local data_dir="${CLS_CODEBUDDY_DATA_DIR:-$HOME/.cls-codebuddy}"
  local day
  day="$(date -u +%Y-%m-%d 2>/dev/null || true)"
  [ -n "$day" ] || day="unknown"
  local dir="$data_dir/logs/codebuddy/errors"
  local file="$dir/codebuddy-error-$day.jsonl"
  mkdir -p "$dir" 2>/dev/null || return 0
  printf '{"time":"%s","gen_ai.agent.type":"codebuddy","stage":"%s","error.type":"shell_%s","error.message":"%s"}\n' \
    "$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || true)" \
    "$stage" "$stage" "$message" \
    >> "$file" 2>/dev/null || true
}

# stdin 是 tty 说明被人工执行（无 hook payload），快速返回
if [ -t 0 ]; then
  printf '%s\n' "$EMPTY_RESULT"
  exit 0
fi

if [ ! -f "$PROCESSOR" ]; then
  log_error "missing_processor" "hook processor not found: $PROCESSOR"
  printf '%s\n' "$EMPTY_RESULT"
  exit 0
fi

MIN_NODE_MAJOR=18

find_node() {
  local candidate=""
  # 1. 显式环境变量
  if [ -n "${CLS_CODEBUDDY_NODE:-}" ] && [ -x "$CLS_CODEBUDDY_NODE" ]; then
    candidate="$CLS_CODEBUDDY_NODE"
  fi
  # 2. nvm 默认版本（sort -V 在 macOS BSD sort 中不可用，改用 awk 版本比较）
  if [ -z "$candidate" ]; then
    local nvm_dir="${NVM_DIR:-$HOME/.nvm}"
    if [ -d "$nvm_dir/versions/node" ]; then
      local latest
      latest=$(ls -d "$nvm_dir/versions/node/v"* 2>/dev/null \
        | awk -F'/' '{
            n=split($NF, a, /[v.]/);
            printf "%05d%05d%05d %s\n", a[2]+0, a[3]+0, a[4]+0, $0
          }' \
        | sort | tail -n1 | awk '{print $2}')
      if [ -n "$latest" ] && [ -x "$latest/bin/node" ]; then
        candidate="$latest/bin/node"
      fi
    fi
  fi
  # 3. PATH 查找
  if [ -z "$candidate" ]; then
    candidate="$(command -v node 2>/dev/null || true)"
  fi
  # 4. 常见安装路径
  if [ -z "$candidate" ]; then
    for p in /usr/local/bin/node /opt/homebrew/bin/node; do
      if [ -x "$p" ]; then candidate="$p"; break; fi
    done
  fi

  if [ -z "$candidate" ]; then
    return 1
  fi

  # 版本校验
  local ver
  ver=$("$candidate" -e 'process.stdout.write(String(process.versions.node.split(".")[0]))' 2>/dev/null || echo "0")
  if [ "$ver" -lt "$MIN_NODE_MAJOR" ] 2>/dev/null; then
    return 1
  fi

  echo "$candidate"
}

NODE_BIN="$(find_node || true)"
if [ -z "$NODE_BIN" ]; then
  log_error "missing_node" "node >= $MIN_NODE_MAJOR not found in PATH/NVM"
  printf '%s\n' "$EMPTY_RESULT"
  exit 0
fi

# 执行 processor；若失败则输出空 JSON 并 exit 0（fail-open）
RESULT=$("$NODE_BIN" "$PROCESSOR" "$SUBCOMMAND" 2>/dev/null) || {
  log_error "processor_crash" "hook processor exited non-zero for subcommand=$SUBCOMMAND"
  printf '%s\n' "$EMPTY_RESULT"
  exit 0
}

if [ -n "$RESULT" ]; then
  printf '%s\n' "$RESULT"
else
  printf '%s\n' "$EMPTY_RESULT"
fi
exit 0
