#!/bin/bash
# Git audit: check ~/dev/ repos for unpushed changes
# Hourly: only fetch repos with local changes (dirty or ahead)
# --full: fetch all repos (daily at 6am)
# Reports anomalies only — silence = healthy

DEV_DIR="/home/johan/dev"
CLAWD_DIR="/home/johan/clawd"
STATE_FILE="/home/johan/clawd/memory/git-audit-lastfull.txt"
ANOMALIES=""
FULL=false

# Full sweep if --full flag or last full was >20h ago
if [ "${1:-}" = "--full" ]; then
  FULL=true
elif [ -f "$STATE_FILE" ]; then
  LAST=$(cat "$STATE_FILE")
  NOW=$(date +%s)
  AGE=$(( NOW - LAST ))
  [ "$AGE" -gt 72000 ] && FULL=true
else
  FULL=true
fi

audit_repo() {
  local dir="$1"
  local repo=$(basename "$dir")

  # Check for remote
  if ! git -C "$dir" remote get-url origin >/dev/null 2>&1; then
    ANOMALIES+="❌ $repo: NO REMOTE\n"
    return
  fi

  # Uncommitted changes
  local DIRTY=$(git -C "$dir" status --porcelain 2>/dev/null)
  local DIRTY_COUNT=0
  if [ -n "$DIRTY" ]; then
    DIRTY_COUNT=$(echo "$DIRTY" | wc -l)
  fi

  # Current branch
  local BRANCH=$(git -C "$dir" rev-parse --abbrev-ref HEAD 2>/dev/null)
  local AHEAD=0
  if [ -n "$BRANCH" ] && git -C "$dir" rev-parse "origin/$BRANCH" >/dev/null 2>&1; then
    AHEAD=$(git -C "$dir" rev-list --count "origin/$BRANCH..HEAD" 2>/dev/null || echo 0)
  fi

  # Only fetch if full mode OR repo has local changes
  if $FULL || [ "$DIRTY_COUNT" -gt 0 ] || [ "$AHEAD" -gt 0 ]; then
    timeout 5 git -C "$dir" fetch origin --quiet 2>/dev/null || true
    # Recheck ahead after fetch
    if [ -n "$BRANCH" ] && git -C "$dir" rev-parse "origin/$BRANCH" >/dev/null 2>&1; then
      AHEAD=$(git -C "$dir" rev-list --count "origin/$BRANCH..HEAD" 2>/dev/null || echo 0)
    fi
  fi

  # Auto-commit repos I own (skip inou — Johan's code)
  if [ "$DIRTY_COUNT" -gt 0 ] && [ "$repo" != "inou" ]; then
    git -C "$dir" add -A 2>/dev/null
    git -C "$dir" commit -m "chore: auto-commit uncommitted changes" --quiet 2>/dev/null && {
      AHEAD=$(git -C "$dir" rev-list --count "origin/$BRANCH..HEAD" 2>/dev/null || echo 0)
    }
    DIRTY_COUNT=0
  fi

  # Auto-push if ahead
  if [ "$AHEAD" -gt 0 ] && [ "$repo" != "inou" ]; then
    timeout 5 git -C "$dir" push origin "$BRANCH" --quiet 2>/dev/null && AHEAD=0 || true
  fi

  [ "$DIRTY_COUNT" -gt 0 ] && ANOMALIES+="⚠️ $repo: $DIRTY_COUNT uncommitted file(s)\n"
  [ "$AHEAD" -gt 0 ] && ANOMALIES+="🔺 $repo: $AHEAD unpushed commit(s) on $BRANCH\n"
}

for dir in "$DEV_DIR"/*/; do
  [ -d "$dir/.git" ] || continue
  audit_repo "$dir"
done

[ -d "$CLAWD_DIR/.git" ] && audit_repo "$CLAWD_DIR"

$FULL && date +%s > "$STATE_FILE"

if [ -n "$ANOMALIES" ]; then
  echo -e "Git audit found issues:\n$ANOMALIES"
  exit 1
else
  exit 0
fi
