#!/bin/bash
# verify-worktree.sh — Verifica build, tests y cierre de issue en un worktree.
#
# Uso:
#   ./verify-worktree.sh <worktree-path> [build-cmd] [test-cmd]
#
# Ejemplos:
#   ./verify-worktree.sh worktrees/0026-foo
#   ./verify-worktree.sh worktrees/0026-foo "go build -tags fts5 ./..." "go test -tags fts5 ./..."
#   BUILD_CMD="cmake --build cpp/build" TEST_CMD="ctest --test-dir cpp/build" ./verify-worktree.sh worktrees/0026-foo
#
# Resolucion de comandos (en orden de prioridad):
#   1. Argumentos posicionales (build-cmd, test-cmd)
#   2. Variables de entorno BUILD_CMD / TEST_CMD
#   3. Archivo .parallel-fix-issues.yml en la raiz del worktree (claves: build, test)
#   4. Auto-deteccion segun ficheros del proyecto:
#        - go.mod          → "go build ./..."          + "go test ./..."
#        - CMakeLists.txt  → "cmake -S . -B build && cmake --build build" + "ctest --test-dir build"
#        - Cargo.toml      → "cargo build"             + "cargo test"
#        - package.json    → "npm run build"           + "npm test"
#        - pyproject.toml  → ""                         + "pytest"
#   5. Si nada se detecta, salta build/test con WARN.
#
# Auto-deteccion adicional: si hay go.mod, intenta extraer build tag de //go:build.
#
# Exit codes:
#   0 = todo OK
#   1 = error de argumento
#   2 = build fallo
#   3 = tests fallaron
#   4 = issue no cerrado (solo WARN, no falla)
#   5 = sin commits propios

set -euo pipefail

if [ $# -lt 1 ]; then
  echo "ERROR: se necesita el path del worktree"
  echo "Uso: $0 <worktree-path> [build-cmd] [test-cmd]"
  exit 1
fi

WORKTREE="$1"
ARG_BUILD_CMD="${2:-}"
ARG_TEST_CMD="${3:-}"

# Resolver path absoluto
if [[ "$WORKTREE" != /* ]]; then
  REPO_ROOT="$(git rev-parse --show-toplevel)"
  WORKTREE="${REPO_ROOT}/${WORKTREE}"
fi

if [ ! -d "$WORKTREE" ]; then
  echo "ERROR: worktree no encontrado: ${WORKTREE}"
  exit 1
fi

SLUG="$(basename "$WORKTREE")"
echo "=== Verificando: ${SLUG} ==="

# --- Resolver build/test commands ---
BUILD_CMD="${ARG_BUILD_CMD:-${BUILD_CMD:-}}"
TEST_CMD="${ARG_TEST_CMD:-${TEST_CMD:-}}"

# Manifest opcional
MANIFEST="${WORKTREE}/.parallel-fix-issues.yml"
if [ -z "$BUILD_CMD" ] && [ -f "$MANIFEST" ]; then
  M_BUILD=$(grep -E "^build:" "$MANIFEST" 2>/dev/null | sed -E 's/^build:[[:space:]]*"?([^"]*)"?[[:space:]]*$/\1/' | head -1 || true)
  if [ -n "$M_BUILD" ]; then BUILD_CMD="$M_BUILD"; echo "INFO: build desde manifest"; fi
fi
if [ -z "$TEST_CMD" ] && [ -f "$MANIFEST" ]; then
  M_TEST=$(grep -E "^test:" "$MANIFEST" 2>/dev/null | sed -E 's/^test:[[:space:]]*"?([^"]*)"?[[:space:]]*$/\1/' | head -1 || true)
  if [ -n "$M_TEST" ]; then TEST_CMD="$M_TEST"; echo "INFO: test desde manifest"; fi
fi

# Auto-deteccion
if [ -z "$BUILD_CMD" ] || [ -z "$TEST_CMD" ]; then
  AUTO_BUILD=""
  AUTO_TEST=""
  if [ -f "${WORKTREE}/go.mod" ]; then
    # Detectar build tag
    AUTO_TAG=$(grep -rh "^//go:build " --include="*.go" "$WORKTREE" 2>/dev/null \
      | sed -E 's|^//go:build ([a-zA-Z0-9_]+).*|\1|' \
      | sort -u | head -1 || true)
    TAG_FLAG=""
    [ -n "$AUTO_TAG" ] && TAG_FLAG="-tags $AUTO_TAG"
    AUTO_BUILD="go build $TAG_FLAG ./..."
    AUTO_TEST="go test $TAG_FLAG ./..."
    echo "INFO: stack detectado: Go${TAG_FLAG:+ ($TAG_FLAG)}"
  elif [ -f "${WORKTREE}/CMakeLists.txt" ] || ls "${WORKTREE}"/cpp/CMakeLists.txt >/dev/null 2>&1; then
    CMAKE_DIR="."
    [ -f "${WORKTREE}/cpp/CMakeLists.txt" ] && [ ! -f "${WORKTREE}/CMakeLists.txt" ] && CMAKE_DIR="cpp"
    AUTO_BUILD="cmake -S ${CMAKE_DIR} -B ${CMAKE_DIR}/build -DCMAKE_BUILD_TYPE=Release && cmake --build ${CMAKE_DIR}/build -j"
    AUTO_TEST="ctest --test-dir ${CMAKE_DIR}/build --output-on-failure || true"
    echo "INFO: stack detectado: C++/CMake (dir=${CMAKE_DIR})"
  elif [ -f "${WORKTREE}/Cargo.toml" ]; then
    AUTO_BUILD="cargo build"
    AUTO_TEST="cargo test"
    echo "INFO: stack detectado: Rust"
  elif [ -f "${WORKTREE}/package.json" ]; then
    AUTO_BUILD="npm run build --if-present"
    AUTO_TEST="npm test --if-present"
    echo "INFO: stack detectado: Node"
  elif [ -f "${WORKTREE}/pyproject.toml" ] || [ -f "${WORKTREE}/setup.py" ]; then
    AUTO_BUILD=""  # python normalmente no tiene build step
    AUTO_TEST="pytest"
    echo "INFO: stack detectado: Python"
  else
    echo "WARN: no se detecto stack; usar BUILD_CMD/TEST_CMD env o manifest .parallel-fix-issues.yml"
  fi
  [ -z "$BUILD_CMD" ] && BUILD_CMD="$AUTO_BUILD"
  [ -z "$TEST_CMD"  ] && TEST_CMD="$AUTO_TEST"
fi

# 1. Verificar commits propios
echo ""
echo "--- Commits propios ---"
COMMIT_COUNT=$(cd "$WORKTREE" && git log master..HEAD --oneline 2>/dev/null | wc -l)
if [ "$COMMIT_COUNT" -eq 0 ]; then
  echo "FAIL: sin commits propios en la branch"
  exit 5
fi
echo "OK: ${COMMIT_COUNT} commits desde master"
cd "$WORKTREE" && git log master..HEAD --oneline

# 2. Build
echo ""
if [ -n "$BUILD_CMD" ]; then
  echo "--- Build ($BUILD_CMD) ---"
  if (cd "$WORKTREE" && bash -c "$BUILD_CMD" 2>&1); then
    echo "OK: build exitoso"
  else
    echo "FAIL: build fallo"
    exit 2
  fi
else
  echo "--- Build SKIPPED (sin comando) ---"
fi

# 3. Tests
echo ""
if [ -n "$TEST_CMD" ]; then
  echo "--- Tests ($TEST_CMD) ---"
  if (cd "$WORKTREE" && bash -c "$TEST_CMD" 2>&1); then
    echo "OK: tests pasaron"
  else
    echo "FAIL: tests fallaron"
    exit 3
  fi
else
  echo "--- Tests SKIPPED (sin comando) ---"
fi

# 4. Issue cerrado
echo ""
echo "--- Cierre de issue ---"
COMPLETED_FILES=$(cd "$WORKTREE" && git diff --name-only master -- dev/issues/completed/ 2>/dev/null | wc -l)
if [ "$COMPLETED_FILES" -gt 0 ]; then
  echo "OK: issue movido a completed/"
  cd "$WORKTREE" && git diff --name-only master -- dev/issues/completed/
else
  echo "WARN: no se detecto issue movido a completed/ (verificar manualmente)"
fi

echo ""
echo "=== RESULTADO: ${SLUG} — OK ==="
