#!/bin/sh
# Per-user bootstrap for the timbre push-to-talk dictation client.
#
# The client's one pip-only dependency is `sounddevice` (PortAudio bindings over
# the system libportaudio2) — it is NOT packaged on Debian, so it can't be a
# distro dependency. Everything else the client needs (evdev, python3-gi, numpy,
# Xlib) ARE distro packages. So this provisions a tiny PER-USER venv created with
# --system-site-packages (it sees those distro packages directly) and pip-installs
# just sounddevice into it, then execs the shipped client under that venv. No
# root, no manual step: built in the user's data dir on first run.
#
# The client *code* (timbre_client.py, mic.py) is run straight from /usr/lib, not
# installed into the venv, so upgrades are live; the venv only carries the pip
# dep, hence the static signature below (bump it only when that dep set changes).
set -eu

CLIENT=/usr/lib/timbre/client/timbre_client.py
DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
VENV="$DATA_HOME/timbre/client-venv"
PY="$VENV/bin/python"
STAMP="$VENV/.build-stamp"
SIG="sounddevice/v1"

if [ ! -f "$CLIENT" ]; then
    echo "timbre-client: shipped client missing at $CLIENT — reinstall the package." >&2
    exit 1
fi

# Fast path: venv already built for the current dep set.
if [ -x "$PY" ] && [ "$(cat "$STAMP" 2>/dev/null || true)" = "$SIG" ]; then
    exec "$PY" "$CLIENT" "$@"
fi

mkdir -p "$DATA_HOME/timbre"

build() {
    echo "timbre-client: provisioning per-user environment at $VENV…" >&2
    rm -rf "$VENV"
    # --system-site-packages: see distro evdev/gi/numpy/Xlib; only sounddevice
    # is installed into the venv.
    python3 -m venv --system-site-packages "$VENV" || return 1
    "$PY" -m pip install --quiet --upgrade pip || return 1
    "$PY" -m pip install --quiet sounddevice || return 1
    [ -x "$PY" ] || return 1
    printf '%s' "$SIG" > "$STAMP"
    echo "timbre-client: environment ready." >&2
}

run_build() {
    if ! build; then
        rm -rf "$VENV"
        echo "timbre-client: environment build failed (offline?). Retries on next start." >&2
        exit 1
    fi
}

# Serialize against a concurrent start (see packaging/bin/timbred).
if command -v flock >/dev/null 2>&1; then
    exec 9>"$DATA_HOME/timbre/.client-build.lock"
    flock 9
    if [ -x "$PY" ] && [ "$(cat "$STAMP" 2>/dev/null || true)" = "$SIG" ]; then
        exec "$PY" "$CLIENT" "$@"
    fi
    run_build
else
    run_build
fi

exec "$PY" "$CLIENT" "$@"
