#!/usr/bin/env bash
# verify-agent-output.sh — Smoke-verify a coding-agent's claim of "Done."
#
# Usage:
#   ./verify-agent-output.sh <project_dir> <changed_file1> [changed_file2 ...]
#
# What it does:
#   1. `git diff --stat` to confirm the agent's claimed files actually changed
#   2. `python -m py_compile` on each Python file (catches syntax errors)
#   3. Smoke-import: tries to load each changed Python file's module to catch
#      wiring errors that py_compile misses (missing imports, undeclared
#      symbols that py_compile tolerates because of `from __future__ import annotations`)
#   4. Detects accidentally-added default secrets via regex on .example/.template files
#
# Exit code 0 = clean, 1 = at least one failure.
#
# Designed to be run after `opencode run` says "Done." — never trust that claim.

set -u

PROJECT="${1:?usage: $0 <project_dir> <changed_file...>}"
shift

if [ "$#" -lt 1 ]; then
  echo "usage: $0 <project_dir> <changed_file1> [changed_file2 ...]" >&2
  exit 2
fi

pass=0
fail=0

run_check() {
  local name="$1"
  shift
  echo "==> $name"
  if "$@"; then
    echo "    ✓ OK"
    pass=$((pass + 1))
  else
    echo "    ✗ FAIL"
    fail=$((fail + 1))
  fi
}

# 1. Show what the agent claims changed
cd "$PROJECT" || { echo "cd failed: $PROJECT" >&2; exit 2; }

echo "=== 1. git diff --stat ==="
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  git diff --stat
  DIFF_RC=$?
  if [ "$DIFF_RC" -ne 0 ]; then
    echo "    ✗ git diff failed"
    fail=$((fail + 1))
  else
    pass=$((pass + 1))
  fi
else
  echo "    (not a git repo — skipping; using mtime instead)"
fi

# 2. py_compile on each provided Python file
PY_FILES=()
for f in "$@"; do
  case "$f" in
    *.py) PY_FILES+=("$f") ;;
    *)   ;;
  esac
done

if [ "${#PY_FILES[@]}" -gt 0 ]; then
  echo
  echo "=== 2. python -m py_compile ==="
  for f in "${PY_FILES[@]}"; do
    if [ -f "$PROJECT/$f" ]; then
      run_check "py_compile $f" \
        python3 -m py_compile "$PROJECT/$f"
    else
      echo "    ! skipping $f (not found at $PROJECT/$f)"
    fi
  done
fi

# 3. Smoke-import — try `python -c "import path.to.module"` for each Python file
if [ "${#PY_FILES[@]}" -gt 0 ]; then
  echo
  echo "=== 3. Smoke-import (catches wiring errors py_compile misses) ==="
  for f in "${PY_FILES[@]}"; do
    # Convert filesystem path to dotted module import path
    # e.g., backend/app/foo.py → backend.app.foo
    module=$(echo "$f" | sed 's|/|.|g; s|\.py$||; s|^\.||')
    run_check "import $module" \
      bash -c "cd '$PROJECT' && python3 -c 'import $module; print(\"imported\", \"$module\")'"
  done
fi

# 4. Detect accidentally-added default secrets in *.example / *.template files
echo
echo "=== 4. Check for accidentally-added defaults in example files ==="
EXAMPLE_FILES=()
while IFS= read -r -d '' file; do
  EXAMPLE_FILES+=("$file")
done < <(find "$PROJECT" -type f \( -name '*.example' -o -name '*.template' -o -name '*.sample' \) -print0)

SECRET_PATTERNS=(
  'sk-[A-Za-z0-9_-]{20,}'           # OpenAI / OpenRouter style
  'eyJ[A-Za-z0-9_-]{20,}'           # JWT / OpenAI
  'AIza[A-Za-z0-9_-]{30,}'          # Google API key
  'ghp_[A-Za-z0-9]{30,}'            # GitHub PAT
  'gho_[A-Za-z0-9]{30,}'            # GitHub OAuth
  'xox[baprs]-[A-Za-z0-9-]{10,}'    # Slack
  'AKIA[A-Z0-9]{16}'                # AWS access key
)

if [ "${#EXAMPLE_FILES[@]}" -gt 0 ]; then
  found_secret=0
  for exf in "${EXAMPLE_FILES[@]}"; do
    for pat in "${SECRET_PATTERNS[@]}"; do
      if grep -qE "$pat" "$exf"; then
        echo "    ✗ $exf contains a possible default secret (matched $pat)"
        found_secret=1
        fail=$((fail + 1))
      fi
    done
  done
  if [ "$found_secret" -eq 0 ]; then
    echo "    ✓ No default secrets detected in example/template files"
    pass=$((pass + 1))
  fi
else
  echo "    (no .example/.template files found — skipping)"
fi

echo
echo "=== Summary: $pass passed, $fail failed ==="
[ "$fail" -eq 0 ] && exit 0 || exit 1
