#!/usr/bin/env bash
# git_pull_with_stash — Si el repo tiene cambios, los stashea antes de pullear.
# Hace fetch + pull --ff-only. Si hay divergencia, restaura el stash y reporta.
# Exit 0 siempre (el caller decide como manejar los errores).

git_pull_with_stash() {
    local repo_dir="${1:-.}"

    if [[ ! -d "$repo_dir/.git" ]]; then
        echo "git_pull_with_stash: '$repo_dir' no es un repo git" >&2
        return 1
    fi

    local abs_repo
    abs_repo="$(cd "$repo_dir" && pwd)"

    local repo_name
    repo_name="$(basename "$abs_repo")"

    # Comprobar si hay cambios pendientes
    local dirty
    dirty=$(git -C "$abs_repo" status --porcelain | wc -l)
    local stashed=0

    if [[ "$dirty" -gt 0 ]]; then
        git -C "$abs_repo" stash push \
            --include-untracked \
            -m "auto-stash before pull" \
            >/dev/null 2>&1 || true
        stashed=1
    fi

    # Fetch origin
    git -C "$abs_repo" fetch origin >/dev/null 2>&1 || {
        # Sin remote configurado o sin red — considerar up-to-date
        if [[ "$stashed" -eq 1 ]]; then
            git -C "$abs_repo" stash pop >/dev/null 2>&1 || true
        fi
        echo "[up-to-date] $repo_name (no remote)"
        return 0
    }

    # Pull --ff-only
    local pull_out
    pull_out=$(git -C "$abs_repo" pull --ff-only 2>&1)
    local pull_exit=$?

    if [[ $pull_exit -ne 0 ]]; then
        # Divergencia — restaurar stash y reportar
        if [[ "$stashed" -eq 1 ]]; then
            git -C "$abs_repo" stash pop >/dev/null 2>&1 || true
        fi
        echo "[diverged] $repo_name"
        return 0
    fi

    # Pull exitoso — restaurar stash si habia
    if [[ "$stashed" -eq 1 ]]; then
        local pop_out
        pop_out=$(git -C "$abs_repo" stash pop 2>&1)
        local pop_exit=$?
        if [[ $pop_exit -ne 0 ]]; then
            echo "[stash-conflict] $repo_name"
            return 0
        fi
    fi

    # Determinar si se trajo algo nuevo
    if echo "$pull_out" | grep -q "Already up to date"; then
        echo "[up-to-date] $repo_name"
    else
        local commits
        commits=$(echo "$pull_out" | grep -c 'Fast-forward\|commit\|Merge' || true)
        echo "[pulled] $repo_name"
    fi
}

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    git_pull_with_stash "$@"
fi
