#!/usr/bin/env bash
# =============================================================================
# record.sh — run the recorder WITHOUT the web dashboard.
#
# The backup plan: it finds a working way to run g1_record_replay.py and uses it,
# instead of you remembering which python has the Unitree SDK on which machine.
#
#   ./record.sh doctor                      what's available here, what's missing
#   ./record.sh record --output wave --seconds 20
#   ./record.sh replay --input wave --speed 0.5
#   ./record.sh eth0 record --output wave   # explicit interface (else auto)
#
# Any flag the script takes is passed straight through — this adds nothing to the
# recorder, it only starts it.
#
# How it picks a runtime, best first:
#   1. $RECORDER_PY            — you said which python to use
#   2. a python that can already import unitree_sdk2py (conda g1_env, system, …)
#   3. ../vendor/unitree_sdk2_python on PYTHONPATH, if that makes it importable
#   4. the inspire-hand container, which has the SDK baked in
# Use --how to see which one it chose without running anything.
#
# Env: IFACE (default: eth0 on the robot, enp3s0 elsewhere)
# =============================================================================
set -uo pipefail

HERE="$(cd "$(dirname "$0")" && pwd)"
SCRIPT="$HERE/g1_record_replay.py"
VENDOR="$(cd "$HERE/.." 2>/dev/null && pwd)/vendor/unitree_sdk2_python"
CONTAINER="${CONTAINER:-inspire-hand}"
[ "$(uname -m)" = "aarch64" ] && DEF_IFACE=eth0 || DEF_IFACE=enp3s0
IFACE="${IFACE:-$DEF_IFACE}"

g=$'\033[32m'; r=$'\033[31m'; y=$'\033[33m'; d=$'\033[2m'; n=$'\033[0m'

have_sdk() {   # $1 = python, $2 = optional PYTHONPATH
    PYTHONPATH="${2:-}" "$1" -c 'import unitree_sdk2py' >/dev/null 2>&1
}

# ---- pick a runtime ---------------------------------------------------------
MODE=""; PY=""; PYPATH=""
if [ -n "${RECORDER_PY:-}" ] && have_sdk "$RECORDER_PY"; then
    MODE=local; PY="$RECORDER_PY"
else
    for cand in "${RECORDER_PY:-}" "$HOME/miniconda3/envs/g1_env/bin/python3" \
                "$HOME/anaconda3/envs/g1_env/bin/python3" python3; do
        [ -n "$cand" ] || continue
        command -v "$cand" >/dev/null 2>&1 || [ -x "$cand" ] || continue
        if have_sdk "$cand"; then MODE=local; PY="$cand"; break; fi
        # The vendored SDK is pure python, but it still needs the compiled
        # cyclonedds bindings — so this only helps where those already exist.
        if [ -d "$VENDOR" ] && have_sdk "$cand" "$VENDOR"; then
            MODE=local; PY="$cand"; PYPATH="$VENDOR"; break
        fi
    done
fi
if [ -z "$MODE" ] && command -v docker >/dev/null 2>&1 \
   && docker exec "$CONTAINER" true >/dev/null 2>&1; then
    MODE=docker
fi

describe() {
    case "$MODE" in
        local)  printf '  %sruntime%s  local python: %s%s\n' "$g" "$n" "$PY" \
                       "${PYPATH:+  (PYTHONPATH=$PYPATH)}"
                printf '  %stakes%s    %s/DataG1\n' "$d" "$n" "$PWD" ;;
        docker) printf '  %sruntime%s  the %s container (SDK baked in)\n' "$g" "$n" "$CONTAINER"
                printf '  %stakes%s    /opt/recorder/DataG1 in the container = ~/hand_data/DataG1 on the host\n' "$d" "$n" ;;
        *)      printf '  %sno runtime%s — no python here can import unitree_sdk2py, and the %s container is not running\n' \
                       "$r" "$n" "$CONTAINER" ;;
    esac
}

# ---- doctor -----------------------------------------------------------------
if [ "${1:-}" = "doctor" ] || [ "${1:-}" = "--how" ]; then
    printf '\nRecorder runtime\n'; describe
    printf '\nDetail\n'
    printf '  script            %s\n' "$([ -f "$SCRIPT" ] && echo "$SCRIPT" || echo "MISSING")"
    printf '  vendored SDK      %s\n' "$([ -d "$VENDOR" ] && echo "$VENDOR" || echo "not next to this folder")"
    printf '  home pose         %s\n' "$([ -f "$HERE/arm_home.jsonl" ] && echo "arm_home.jsonl" || echo "MISSING — replay skips return-to-home")"
    printf '  interface         %s\n' "$IFACE"
    for c in "$HOME/miniconda3/envs/g1_env/bin/python3" python3; do
        [ -x "$c" ] || command -v "$c" >/dev/null 2>&1 || continue
        if have_sdk "$c"; then s="${g}has unitree_sdk2py${n}"; else s="${y}no unitree_sdk2py${n}"; fi
        printf '  python            %-46s %s\n' "$c" "$s"
    done
    if [ "$MODE" = "" ]; then
        printf '\n%sFix one of these%s\n' "$y" "$n"
        printf '  · conda activate g1_env   (workstation — the env that has the SDK)\n'
        # Only suggest it where it exists: a standalone bundle has no start.sh.
        [ -f "$HERE/../start.sh" ] && \
        printf '  · start the hand stack:  ../start.sh    (then this uses the container)\n'
        printf '  · install the bindings:  pip install "cyclonedds==0.10.2" && pip install -e %s\n' "$VENDOR"
        exit 1
    fi
    exit 0
fi

[ -f "$SCRIPT" ] || { echo "${r}missing${n} $SCRIPT"; exit 1; }
if [ -z "$MODE" ]; then
    printf '%sno way to run the recorder here%s — try: %s doctor\n' "$r" "$n" "$0" >&2
    exit 1
fi

# ---- interface: accept it as $1, or insert the default ----------------------
# The recorder takes the interface as its first positional arg. Typing it every
# time is noise, so if the first argument is already an action we insert one.
case "${1:-}" in
    record|replay) set -- "$IFACE" "$@" ;;
esac

describe >&2
printf '%s>> %s %s%s\n' "$d" "$(basename "$SCRIPT")" "$*" "$n" >&2

if [ "$MODE" = "docker" ]; then
    # -it: the in-take keys (o/c/[/]/;/' and 1-9) and the pause key need a TTY.
    exec docker exec -it -w /opt/recorder "$CONTAINER" python3 g1_record_replay.py "$@"
fi
cd "$PWD" || exit 1          # takes land in the CALLER's DataG1, not the script's
exec env ${PYPATH:+PYTHONPATH="$PYPATH"} "$PY" "$SCRIPT" "$@"
