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

PROJECT_DIR="/home/long/project/蚊子"
REPORT_DIR="$PROJECT_DIR/logs/prd-review"
RUN_LOG="$PROJECT_DIR/logs/prd_review_cycle.log"
LOCK_FILE="/tmp/mosquito_prd_review_cycle.lock"
PID_FILE="$PROJECT_DIR/logs/prd-review/cycle.pid"
FORCE_RERUN="${FORCE_RERUN:-0}"
STALE_SECONDS="${STALE_SECONDS:-10800}"
CLAUDE_BIN="$HOME/.cursor/extensions/anthropic.claude-code-2.1.15-linux-x64/resources/native-binary/claude"
EVIDENCE_CHECK_SCRIPT="$PROJECT_DIR/scripts/verify_review_evidence.sh"

# cron环境下PATH通常不完整，显式补齐nvm/codex
export HOME="${HOME:-/home/long}"
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
export PATH="$HOME/.local/bin:$HOME/bin:/usr/local/bin:/usr/bin:/bin:$PATH"

if ! command -v codex >/dev/null 2>&1; then
  if [ -s "$NVM_DIR/nvm.sh" ]; then
    # shellcheck disable=SC1090
    . "$NVM_DIR/nvm.sh" >/dev/null 2>&1 || true
    nvm use --silent 20 >/dev/null 2>&1 || true
    nvm use --silent default >/dev/null 2>&1 || true
  fi
fi

CODEX_BIN="$(command -v codex || true)"
if [ -z "$CODEX_BIN" ] && [ -x "$HOME/.nvm/versions/node/v20.19.0/bin/codex" ]; then
  CODEX_BIN="$HOME/.nvm/versions/node/v20.19.0/bin/codex"
fi

mkdir -p "$REPORT_DIR" "$PROJECT_DIR/logs"

if [ -f "$PID_FILE" ]; then
  prev_pid="$(cat "$PID_FILE" 2>/dev/null || true)"
  if [ -n "${prev_pid:-}" ] && kill -0 "$prev_pid" 2>/dev/null; then
    now_ts=$(date +%s)
    pid_age=$((now_ts - $(stat -c %Y "$PID_FILE" 2>/dev/null || echo "$now_ts")))
    if [ "$FORCE_RERUN" = "1" ] || [ "$pid_age" -gt "$STALE_SECONDS" ]; then
      echo "[$(date '+%F %T')] force/stale rerun: killing previous pid=$prev_pid age=${pid_age}s" >> "$RUN_LOG"
      kill "$prev_pid" 2>/dev/null || true
      sleep 2
    fi
  fi
fi

exec 9>"$LOCK_FILE"
if ! flock -n 9; then
  echo "[$(date '+%F %T')] skip: previous cycle still running" >> "$RUN_LOG"
  exit 0
fi

echo $$ > "$PID_FILE"
trap 'rm -f "$PID_FILE"' EXIT

cd "$PROJECT_DIR"

TIMESTAMP="$(date '+%Y%m%d_%H%M%S')"
REPORT_FILE="$REPORT_DIR/review_${TIMESTAMP}.md"
LATEST_REPORT="$REPORT_DIR/latest_review.md"
CLAUDE_SUMMARY="$REPORT_DIR/claude_apply_${TIMESTAMP}.md"

PRD_FILES=()
for f in "$PROJECT_DIR/docs/PRD.md" "$PROJECT_DIR/docs/prd"/*.md; do
  if [ -f "$f" ]; then
    PRD_FILES+=("$f")
  fi
done

if [ ${#PRD_FILES[@]} -eq 0 ]; then
  echo "[$(date '+%F %T')] error: no PRD files found" >> "$RUN_LOG"
  exit 1
fi

PRD_LIST=$(printf '%s\n' "${PRD_FILES[@]}")

CODEX_PROMPT=$(cat <<EOF
你是严格的项目评审官。请在仓库 $PROJECT_DIR 执行全面review，并以 PRD 为基准进行差距分析。

PRD文件如下：
$PRD_LIST

输出要求（中文，Markdown）：
1. 总体结论（是否满足最新PRD）
2. PRD事项对照矩阵（事项/当前状态/证据文件路径/优先级）
3. 未完成清单（P0/P1/P2）
4. 给Claude可直接执行的优化任务清单（按顺序，包含具体文件与验收标准）
5. 建议执行命令（构建、测试、e2e）

请务必面向“可执行落地”，不要空泛建议。
EOF
)

if [ -z "$CODEX_BIN" ]; then
  echo "[$(date '+%F %T')] error: codex binary not found (PATH=$PATH)" >> "$RUN_LOG"
  exit 1
fi

echo "[$(date '+%F %T')] cycle start: generating codex report with $CODEX_BIN" >> "$RUN_LOG"
"$CODEX_BIN" exec \
  --cd "$PROJECT_DIR" \
  --dangerously-bypass-approvals-and-sandbox \
  --output-last-message "$REPORT_FILE" \
  "$CODEX_PROMPT" >> "$RUN_LOG" 2>&1

if [ ! -s "$REPORT_FILE" ]; then
  echo "[$(date '+%F %T')] error: codex report is empty: $REPORT_FILE" >> "$RUN_LOG"
  exit 1
fi

cp -f "$REPORT_FILE" "$LATEST_REPORT"

echo "[$(date '+%F %T')] codex report ready: $REPORT_FILE" >> "$RUN_LOG"

CLAUDE_PROMPT=$(cat <<EOF
请读取并执行该评审报告中的优化任务：
$REPORT_FILE

要求：
1) 按优先级执行修复，优先完成P0/P1
2) 可以直接修改代码并运行必要命令（含后端测试、前端测试、端到端测试）
3) 若修复后仍有失败，继续迭代直到通过或给出明确阻塞原因
4) 输出最终摘要：执行命令、修改文件、测试结果、剩余未完成PRD项
5) 必须输出“证据矩阵”，每条包含：命令 | 退出码 | 原始日志路径 | 结果结论
6) 所有结论都要附可追溯日志路径（如 logs/*.log、target/surefire-reports/*.xml）

若无法提供可追溯证据，必须明确写“证据不足-本轮无效”。
请直接开始执行，不要只给计划。
EOF
)

echo "[$(date '+%F %T')] cycle continue: running claude apply" >> "$RUN_LOG"
"$CLAUDE_BIN" -p \
  --permission-mode dontAsk \
  --dangerously-skip-permissions \
  "$CLAUDE_PROMPT" > "$CLAUDE_SUMMARY" 2>> "$RUN_LOG"

if [ ! -s "$CLAUDE_SUMMARY" ]; then
  echo "[$(date '+%F %T')] error: claude summary is empty: $CLAUDE_SUMMARY" >> "$RUN_LOG"
  exit 1
fi

if [ -x "$EVIDENCE_CHECK_SCRIPT" ]; then
  if "$EVIDENCE_CHECK_SCRIPT" "$CLAUDE_SUMMARY" "$PROJECT_DIR" >> "$RUN_LOG" 2>&1; then
    echo "[$(date '+%F %T')] evidence gate pass" >> "$RUN_LOG"
  else
    echo "[$(date '+%F %T')] error: evidence gate failed, mark cycle invalid" >> "$RUN_LOG"
    exit 1
  fi
else
  echo "[$(date '+%F %T')] warn: evidence checker missing: $EVIDENCE_CHECK_SCRIPT" >> "$RUN_LOG"
  exit 1
fi

echo "[$(date '+%F %T')] cycle done: $CLAUDE_SUMMARY" >> "$RUN_LOG"
