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

# ECC Codex Git Hook: pre-push
# Runs a lightweight verification flow before pushes.

if [[ "${ECC_SKIP_GIT_HOOKS:-0}" == "1" || "${ECC_SKIP_PREPUSH:-0}" == "1" ]]; then
  exit 0
fi

if [[ -f ".ecc-hooks-disable" || -f ".git/ecc-hooks-disable" ]]; then
  exit 0
fi

if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  exit 0
fi

# Skip checks for branch deletion pushes (e.g., git push origin --delete <branch>).
# The pre-push hook receives lines on stdin: <local ref> <local sha> <remote ref> <remote sha>.
# For deletions, the local sha is the zero OID.
is_delete_only=true
while read -r _local_ref local_sha _remote_ref _remote_sha; do
  if [[ "$local_sha" != "0000000000000000000000000000000000000000" ]]; then
    is_delete_only=false
    break
  fi
done
if [[ "$is_delete_only" == "true" ]]; then
  exit 0
fi

ran_any_check=0

log() {
  printf '[ECC pre-push] %s\n' "$*"
}

fail() {
  printf '[ECC pre-push] FAILED: %s\n' "$*" >&2
  exit 1
}

detect_pm() {
  if [[ -f "pnpm-lock.yaml" ]]; then
    echo "pnpm"
  elif [[ -f "bun.lockb" ]]; then
    echo "bun"
  elif [[ -f "yarn.lock" ]]; then
    echo "yarn"
  elif [[ -f "package-lock.json" ]]; then
    echo "npm"
  else
    echo "npm"
  fi
}

has_node_script() {
  local script_name="$1"
  node -e 'const fs=require("fs"); const p=JSON.parse(fs.readFileSync("package.json","utf8")); process.exit(p.scripts && p.scripts[process.argv[1]] ? 0 : 1)' "$script_name" >/dev/null 2>&1
}

run_node_script() {
  local pm="$1"
  local script_name="$2"
  case "$pm" in
    pnpm) pnpm run "$script_name" ;;
    bun) bun run "$script_name" ;;
    yarn) yarn "$script_name" ;;
    npm) npm run "$script_name" ;;
    *) npm run "$script_name" ;;
  esac
}

if [[ -f "package.json" ]]; then
  pm="$(detect_pm)"
  log "Node project detected (package manager: $pm)"

  for script_name in lint typecheck test build; do
    if has_node_script "$script_name"; then
      ran_any_check=1
      log "Running: $script_name"
      run_node_script "$pm" "$script_name" || fail "$script_name failed"
    else
      log "Skipping missing script: $script_name"
    fi
  done

  if [[ "${ECC_PREPUSH_AUDIT:-0}" == "1" ]]; then
    ran_any_check=1
    log "Running dependency audit (ECC_PREPUSH_AUDIT=1)"
    case "$pm" in
      pnpm) pnpm audit --prod || fail "pnpm audit failed" ;;
      bun) bun audit || fail "bun audit failed" ;;
      yarn) yarn npm audit --recursive || fail "yarn audit failed" ;;
      npm) npm audit --omit=dev || fail "npm audit failed" ;;
      *) npm audit --omit=dev || fail "npm audit failed" ;;
    esac
  fi
fi

if [[ -f "go.mod" ]] && command -v go >/dev/null 2>&1; then
  ran_any_check=1
  log "Go project detected. Running: go test ./..."
  go test ./... || fail "go test failed"
fi

if [[ -f "pyproject.toml" || -f "requirements.txt" ]]; then
  if command -v pytest >/dev/null 2>&1; then
    ran_any_check=1
    log "Python project detected. Running: pytest -q"
    pytest -q || fail "pytest failed"
  else
    log "Python project detected but pytest is not installed. Skipping."
  fi
fi

if [[ "$ran_any_check" -eq 0 ]]; then
  log "No supported checks found in this repository. Skipping."
else
  log "Verification checks passed."
fi

exit 0
