#!/bin/sh
# szsdlc launcher — POSIX sh, for WSL, Linux, macOS and Git Bash on Windows.
#
# Hooks invoke this on every file write and every turn end, so it has to
# resolve an interpreter without asking anyone anything. The order is:
#
#   1. an installed `szsdlc` already on PATH — a developer's own venv wins;
#   2. a venv this launcher previously created, refreshed when it is stale;
#   3. create that venv from the plugin source, once, on first run.
#
# Failure is silent-ish by design: a hook that dies noisily in a project which
# does not even use szsdlc is worse than one that does nothing.

set -u

# Guard against resolving to ourselves if this directory is on PATH.
if [ "${SZSDLC_LAUNCHER:-}" = "1" ]; then
    echo "szsdlc: launcher recursion; is bin/ on PATH?" >&2
    exit 5
fi
SZSDLC_LAUNCHER=1
export SZSDLC_LAUNCHER

# 1. An installed console script — but never this launcher itself.
#
# The plugin puts this directory on PATH, so a bare `command -v szsdlc` finds
# *us*, execs us, and the recursion guard above fires on every hook invocation.
# Compare directories rather than exact paths so a sibling `szsdlc.exe` in this
# same bin/ is excluded too.
self_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
found="$(command -v szsdlc 2>/dev/null || true)"
if [ -n "$found" ] && [ -x "$found" ]; then
    found_dir="$(CDPATH= cd -- "$(dirname -- "$found")" 2>/dev/null && pwd || true)"
    if [ "$found_dir" != "$self_dir" ]; then
        exec "$found" "$@"
    fi
fi

plugin_root="${CLAUDE_PLUGIN_ROOT:-$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)}"
data_dir="${CLAUDE_PLUGIN_DATA:-${XDG_DATA_HOME:-$HOME/.local/share}/szsdlc}"
venv="$data_dir/venv"
stamp="$data_dir/installed-from"

# What the venv is supposed to contain. Claude Code installs each release into
# its own cache directory and leaves the old ones in place, so the path alone
# catches an update; the version also catches a checkout updated in place.
release=$(sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' \
    "$plugin_root/.claude-plugin/plugin.json" 2>/dev/null | head -1)
want="$plugin_root@$release"

# 2. A venv this launcher built earlier — but only if it holds *this* release.
#
# Without the check the launcher execs whichever venv it built first, forever:
# `/plugin update` writes new code to disk that nothing ever runs, and the fix
# is an `rm -rf` nobody knows to perform.
for candidate in "$venv/bin/python" "$venv/Scripts/python.exe"; do
    if [ -x "$candidate" ]; then
        if [ "$(cat "$stamp" 2>/dev/null || true)" != "$want" ]; then
            # Install over the venv rather than rebuilding it: the interpreter
            # is already there and pip replaces the package. Stamped only on
            # success, so a broken pip keeps retrying and keeps saying so
            # rather than silently pinning the caller to old code.
            if "$candidate" -m pip install --quiet --disable-pip-version-check \
                    --upgrade "$plugin_root" >/dev/null 2>&1; then
                printf '%s\n' "$want" > "$stamp" 2>/dev/null || true
            else
                echo "szsdlc: could not refresh $venv to $release; running what is there." >&2
                echo "Fix: $candidate -m pip install --upgrade $plugin_root" >&2
            fi
        fi
        exec "$candidate" -m szsdlc.cli "$@"
    fi
done

# 3. First run: build the venv.
#
# Candidates are *probed*, not merely found. Under Git Bash on Windows,
# `python3` resolves to the Microsoft Store stub in WindowsApps — present on
# PATH, on the front of it, and unable to run anything. Taking the first name
# that exists picks the stub every time and the hook silently does nothing.
# Running each candidate also enforces the 3.12 floor for free.
probe='import sys; sys.exit(0 if sys.version_info >= (3, 12) else 1)'
interpreter=""
for candidate in python3 python py; do
    command -v "$candidate" >/dev/null 2>&1 || continue
    if "$candidate" -c "$probe" >/dev/null 2>&1; then
        interpreter="$candidate"
        break
    fi
done
if [ -z "$interpreter" ]; then
    echo "szsdlc: no working Python 3.12+ found (tried python3, python, py)." >&2
    echo "Fix: install Python 3.12 or later and rerun" >&2
    exit 5
fi

mkdir -p "$data_dir" || exit 5
"$interpreter" -m venv "$venv" >/dev/null 2>&1 || {
    echo "szsdlc: could not create a virtualenv at $venv." >&2
    echo "Fix: pip install $plugin_root" >&2
    exit 5
}

for candidate in "$venv/bin/python" "$venv/Scripts/python.exe"; do
    if [ -x "$candidate" ]; then
        "$candidate" -m pip install --quiet --disable-pip-version-check \
            "$plugin_root" >/dev/null 2>&1 || {
            echo "szsdlc: could not install szsdlc into $venv." >&2
            echo "Fix: $candidate -m pip install $plugin_root" >&2
            exit 5
        }
        printf '%s\n' "$want" > "$stamp" 2>/dev/null || true
        exec "$candidate" -m szsdlc.cli "$@"
    fi
done

echo "szsdlc: virtualenv at $venv has no python executable." >&2
echo "Fix: rm -rf $venv and rerun" >&2
exit 5
