#!/usr/bin/env bash
# Compare the deployed box copy against what git actually holds.
#
# It compares against `git show HEAD:<file>`, NOT the working copy. On Windows with
# core.autocrlf=true the working tree can hold CRLF while the index and the box both
# hold LF — on 2026-07-29 that produced a red drift report on collect.py when nothing
# had drifted at all. A drift check that cries wolf gets ignored, which is worse than
# not having one.
#
# Usage: bin/drift-check.sh [host]
set -uo pipefail

HOST="${1:-root@134.199.153.159}"
REMOTE="/root/personal-cos"
cd "$(dirname "$0")/.."

FILES=$(git ls-files '*.py' 'config/*' 'deploy/*' 'bin/*.sh')
# Flattened to one line before it crosses the wire. Passing the newline-separated
# list straight into the remote command made the far shell execute each filename
# as a command and report every file MISSING — a red report from a broken check.
FILES_ONE_LINE=$(printf '%s ' $FILES)

red=0
printf '%-42s %s\n' "FILE" "STATUS"
printf '%-42s %s\n' "------------------------------------------" "------"

# ONE connection, not two. This used to open a second ssh for the box-only scan, and
# two back-to-back connections trip the box's rapid-connection limit — which produced a
# red report twice on 2026-07-29 while a bare `ssh echo` succeeded immediately either
# side of it. A checker that fails on its own connection budget is a checker nobody
# trusts. Both halves now come back in one round trip, with a retry behind them.
remote=""
for attempt in 1 2 3; do
    remote=$(ssh -o BatchMode=yes -o ConnectTimeout=30 "$HOST" \
        "cd $REMOTE 2>/dev/null && md5sum $FILES_ONE_LINE 2>/dev/null; \
         echo '---BOX-ONLY---'; ls *.py config/* deploy/* bin/*.sh 2>/dev/null" || true)
    case "$remote" in *---BOX-ONLY---*) break ;; esac
    [ "$attempt" -lt 3 ] && sleep $((attempt * 10))
done

case "$remote" in
    *---BOX-ONLY---*) ;;
    *) echo "could not read $HOST:$REMOTE after 3 attempts — UNVERIFIED, not clean"; exit 2 ;;
esac

remote_sums=${remote%%---BOX-ONLY---*}
remote_listing=${remote#*---BOX-ONLY---}

for f in $FILES; do
    want=$(git show "HEAD:$f" | md5sum | cut -d' ' -f1)
    have=$(printf '%s\n' "$remote_sums" | awk -v f="$f" '$2==f {print $1}')
    if [ -z "$have" ]; then
        printf '%-42s %s\n' "$f" "MISSING ON BOX"
        red=1
    elif [ "$want" != "$have" ]; then
        printf '%-42s %s\n' "$f" "DRIFT"
        red=1
    fi
done

# Box-ahead matters as much as box-behind: a file that exists only on the box is a
# working copy with no backup, and the next deploy destroys it silently. Listing came
# back on the same connection above — no second ssh.
for f in $remote_listing; do
    if ! printf '%s\n' "$FILES" | grep -qx "$f"; then
        printf '%-42s %s\n' "$f" "BOX-ONLY (not in git)"
        red=1
    fi
done

if [ "$red" -eq 0 ]; then
    echo
    echo "box == git HEAD on all $(printf '%s\n' "$FILES" | wc -l) files"
fi
exit "$red"
