#!/usr/bin/env bash
# sync-repos — Pull latest for all git repos under ~/dev/claude
# Usage:
#   sync-repos              # pull all repos
#   sync-repos --dryrun     # show what would be pulled
#   sync-repos -n           # same as --dryrun

set -euo pipefail

BASE_DIR="${HOME}/dev/claude"
DRYRUN=false

if [[ "${1:-}" == "--dryrun" || "${1:-}" == "-n" ]]; then
    DRYRUN=true
fi

GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
DIM='\033[2m'
RESET='\033[0m'

pulled=0
skipped=0
failed=0
dirty=0

# Find all git repos (look for .git dirs, max depth 3 to cover projects/ and octopus/)
while IFS= read -r gitdir; do
    repo_dir="$(dirname "$gitdir")"
    repo_name="${repo_dir#"${BASE_DIR}/"}"

    # Skip if no remote configured
    if ! git -C "$repo_dir" remote get-url origin &>/dev/null; then
        printf "${DIM}  skip  %-40s no remote${RESET}\n" "$repo_name"
        skipped=$((skipped + 1))
        continue
    fi

    # Check for uncommitted changes
    if ! git -C "$repo_dir" diff --quiet 2>/dev/null || ! git -C "$repo_dir" diff --cached --quiet 2>/dev/null; then
        has_changes=true
    else
        has_changes=false
    fi

    if $DRYRUN; then
        branch="$(git -C "$repo_dir" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")"
        if $has_changes; then
            printf "${YELLOW}  dirty %-40s %s (has uncommitted changes)${RESET}\n" "$repo_name" "$branch"
            dirty=$((dirty + 1))
        else
            printf "${GREEN}  pull  %-40s %s${RESET}\n" "$repo_name" "$branch"
            pulled=$((pulled + 1))
        fi
        continue
    fi

    # Pull with --ff-only to avoid creating merge commits
    branch="$(git -C "$repo_dir" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")"
    output="$(git -C "$repo_dir" pull --ff-only 2>&1)" && rc=0 || rc=$?

    if [[ $rc -eq 0 ]]; then
        if echo "$output" | grep -q "Already up to date"; then
            printf "${DIM}  ok    %-40s %s (up to date)${RESET}\n" "$repo_name" "$branch"
        else
            printf "${GREEN}  pull  %-40s %s${RESET}\n" "$repo_name" "$branch"
        fi
        pulled=$((pulled + 1))
    else
        printf "${RED}  FAIL  %-40s %s${RESET}\n" "$repo_name" "$branch"
        printf "${DIM}         %s${RESET}\n" "$output"
        failed=$((failed + 1))
    fi

done < <(find "$BASE_DIR" -maxdepth 4 -name .git -type d 2>/dev/null | sort)

echo ""
if $DRYRUN; then
    echo "Dryrun: ${pulled} would pull, ${dirty} dirty, ${skipped} skipped"
else
    echo "Done: ${pulled} pulled, ${failed} failed, ${skipped} skipped"
fi

[[ $failed -eq 0 ]]
