#!/bin/sh
# repoman :: tests for recipes/claude/claude-launcher.sh
# Verifies the claude-share launcher: newest-version selection (semver-aware),
# argument pass-through, self-update interception, and the empty-versions error.

set -eu

here="$(cd "$(dirname -- "$0")" && pwd)"
launcher="$here/../recipes/claude/claude-launcher.sh"

fails=0
check() { # desc, expected, actual
    if [ "$2" = "$3" ]; then
        echo "ok   - $1"
    else
        echo "FAIL - $1"
        echo "         expected: [$2]"
        echo "         actual:   [$3]"
        fails=$((fails + 1))
    fi
}

# Build a throwaway prefix that mirrors the in-container mount layout:
#   <tmp>/.local/bin/claude                      <- the launcher under test
#   <tmp>/.local/share/claude/versions/<ver>     <- fake version binaries
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
mkdir -p "$tmp/.local/bin" "$tmp/.local/share/claude/versions"
cp "$launcher" "$tmp/.local/bin/claude"
chmod +x "$tmp/.local/bin/claude"

make_ver() { # version
    f="$tmp/.local/share/claude/versions/$1"
    printf '#!/bin/sh\necho "RAN %s ARGS=$*"\n' "$1" > "$f"
    chmod +x "$f"
}

# Deliberately out of lexical order to prove semver (not string) sorting:
# string sort would rank 2.1.9 > 2.1.10; sort -V must pick 2.1.10.
make_ver 2.1.9
make_ver 2.1.10
make_ver 2.1.158

claude="$tmp/.local/bin/claude"

# 1. Newest version is selected and args are passed through.
out="$("$claude" --print foo 2>/dev/null)"
check "execs newest version with args" "RAN 2.1.158 ARGS=--print foo" "$out"

# 2. Adding a higher version is picked up live (no reinstall of the launcher).
make_ver 2.1.160
out="$("$claude" 2>/dev/null)"
check "picks up newly-added higher version" "RAN 2.1.160 ARGS=" "$out"

# 3. semver ordering when only 2.1.9 / 2.1.10 exist.
tmp2="$(mktemp -d)"
mkdir -p "$tmp2/.local/bin" "$tmp2/.local/share/claude/versions"
cp "$launcher" "$tmp2/.local/bin/claude"; chmod +x "$tmp2/.local/bin/claude"
for v in 2.1.9 2.1.10; do
    f="$tmp2/.local/share/claude/versions/$v"
    printf '#!/bin/sh\necho "RAN %s"\n' "$v" > "$f"; chmod +x "$f"
done
out="$("$tmp2/.local/bin/claude" 2>/dev/null)"
check "semver: 2.1.10 outranks 2.1.9" "RAN 2.1.10" "$out"
rm -rf "$tmp2"

# 4. self-update subcommands are intercepted (non-zero exit, no version run).
for sub in update upgrade --upgrade; do
    rc=0
    out="$("$claude" "$sub" 2>&1)" || rc=$?
    check "intercepts '$sub' (exit nonzero)" "1" "$rc"
    case "$out" in
        *"Upgrade on the host"*) echo "ok   - '$sub' prints host-upgrade hint" ;;
        *) echo "FAIL - '$sub' missing host-upgrade hint: [$out]"; fails=$((fails + 1)) ;;
    esac
done

# 5. empty versions dir -> clear error, exit 127.
empty="$(mktemp -d)"
mkdir -p "$empty/.local/bin" "$empty/.local/share/claude/versions"
cp "$launcher" "$empty/.local/bin/claude"; chmod +x "$empty/.local/bin/claude"
rc=0
out="$("$empty/.local/bin/claude" 2>&1)" || rc=$?
check "empty versions dir exits 127" "127" "$rc"
rm -rf "$empty"

echo
if [ "$fails" -eq 0 ]; then
    echo "PASS: all claude-launcher checks passed"
    exit 0
fi
echo "FAIL: $fails check(s) failed"
exit 1
