#!/bin/bash
set -euo pipefail

echo "=== apt update ==="
apt update

echo ""
echo "=== Held packages (apt-mark hold) ==="
HELD=$(apt-mark showhold)
if [ -n "$HELD" ]; then
    echo "$HELD"
else
    echo "(none)"
fi

echo ""
echo "=== Upgradable packages ==="
apt list --upgradable 2>/dev/null | grep -v "^Listing"

echo ""
echo "=== Kept-back packages (simulated dist-upgrade) ==="
SIMULATE=$(apt-get -s dist-upgrade 2>/dev/null || true)
echo "$SIMULATE" | grep -E "kept back|NOT upgraded" || echo "(none kept back)"

echo ""
echo "=== Reason per kept-back package ==="
# Extract package names from the kept-back block
echo "$SIMULATE" \
    | awk '/have been kept back:/{found=1; next} found && /^  /{print; next} found && /^[^ ]/{exit}' \
    | tr ' ' '\n' \
    | grep -v '^$' \
    | while read -r pkg; do
        echo "--- $pkg ---"
        if apt-mark showhold | grep -qx "$pkg"; then
            echo "  ON HOLD (apt-mark hold)"
        else
            # Show installed vs candidate version
            apt-cache policy "$pkg" 2>/dev/null \
                | grep -E "Installed|Candidate|Package pin" | sed 's/^/  /'
            echo "  [dependency simulation:]"
            # || true prevents pipefail from killing the loop
            apt-get install -s "$pkg" 2>&1 \
                | grep -v "^Reading\|^Building\|^Inst\|^Conf\|^NOTE" \
                | head -20 \
                | sed 's/^/  /' || true
        fi
    done

echo ""
echo "=== dist-upgrade ==="
apt dist-upgrade

echo ""
echo "=== Autoremove check (dry run, nothing removed) ==="
apt autoremove --dry-run 2>/dev/null \
    | grep "^Remv" | sed 's/^/  would remove: /' || echo "(nothing to autoremove)"
