#!/bin/sh
# crc — start a `claude rc` (Remote Control) server in a target dir on a target
# host, inside a durable tmux session so transport drops don't kill it.
#
# `claude rc` (= `claude remote-control`) is a persistent server: you start it
# in a directory, then drive sessions there from claude.ai/code or the Claude
# mobile app. It must keep running after you disconnect — so crc parks it in a
# named tmux session on the host (same durability trick as tssh/remote-run).
#
# The tmux session name is derived from the directory, so re-running crc for the
# same host+dir RE-ATTACHES the existing server instead of starting a second
# one. Detach with Ctrl-b d; the server keeps running. Reattach with the same
# crc command.
#
# Usage:
#   crc                          # apricot.lan, mirror of $PWD
#   crc <host>                   # <host>, mirror of $PWD
#   crc <host> <dir>             # <host>, explicit dir (abs path or ~/...)
#   crc <host> <dir> -- <args>   # extra args passed to `claude rc`
#   crc -n ...                   # open a NEW iTerm window instead of current tab
#   crc -h | --help
#
# Options:
#   -s, --session <name>   override the derived tmux session name (so a boot
#                          unit and an interactive attach share ONE session)
#   --ensure               start the session detached if not already running,
#                          then exit (no attach) — for systemd / scripting
#   --respawn              run `claude rc` in a restart loop inside the session,
#                          so a crash is recovered without systemd intervention
#
# host may be any ssh target (alias, user@host, IP), or local/./localhost to run
# on this machine. When <dir> is omitted, $PWD is mirrored to the same path
# under the remote's $HOME (like rclaude); paths outside $HOME fall back to ~.
#
# Env:
#   CRC_HOST   default host when none given (default: apricot.lan)

set -eu

host=${CRC_HOST:-apricot.lan}
new_window=0
dry_run=0
session_override=''
ensure=0
respawn=0

usage() { sed -n '2,37p' "$0" | sed 's/^# \{0,1\}//'; }

# --- arg parse -------------------------------------------------------------
positional=''         # collected host/dir (max 2), space-free tokens unsafe so
                       # we track count explicitly
have_host=0
dir_set=0
dir=''
rc_args=''            # everything after `--`, verbatim

while [ $# -gt 0 ]; do
    case "$1" in
        -h|--help) usage; exit 0 ;;
        -n|--new-window) new_window=1; shift ;;
        --dry-run) dry_run=1; shift ;;
        -s|--session)
            [ $# -ge 2 ] || { echo "crc: $1 needs a value" >&2; exit 2; }
            session_override=$2; shift 2 ;;
        --ensure) ensure=1; shift ;;
        --respawn) respawn=1; shift ;;
        --) shift; rc_args=$*; break ;;
        -*) echo "crc: unknown option: $1" >&2; exit 2 ;;
        *)
            if [ $have_host -eq 0 ]; then host=$1; have_host=1
            elif [ $dir_set -eq 0 ]; then dir=$1; dir_set=1
            else echo "crc: too many arguments: $1" >&2; exit 2
            fi
            shift ;;
    esac
done

# --- new-window mode: relaunch self (sans -n) in a fresh iTerm window -------
if [ "$new_window" -eq 1 ]; then
    cmd="crc"
    [ $have_host -eq 1 ] && cmd="$cmd $(printf %q "$host")"
    [ $dir_set -eq 1 ]        && cmd="$cmd $(printf %q "$dir")"
    [ -n "$session_override" ] && cmd="$cmd --session $(printf %q "$session_override")"
    [ -n "$rc_args" ]         && cmd="$cmd -- $rc_args"
    escaped=$(printf %s "$cmd" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g')
    osascript <<OSA
tell application "iTerm"
    activate
    create window with default profile
    tell current session of current window to write text "${escaped}"
end tell
OSA
    exit 0
fi

# --- resolve dir into a remote-evaluable shell expression ------------------
# rel  → mirror of $PWD relative to $HOME (remote expands $HOME)
# abs  → explicit path, used verbatim (handles absolute and ~/...)
rel=''
abs=''
slug_src=''
if [ $dir_set -eq 1 ]; then
    abs=$dir
    slug_src=$dir
else
    case "$PWD" in
        "$HOME") rel='' ; slug_src='home' ;;
        "$HOME"/*) rel=${PWD#"$HOME"/} ; slug_src=$rel ;;
        *) rel='' ; slug_src='home' ;;   # outside $HOME → remote home
    esac
fi

# tmux session name: a --session override (sanitized — tmux forbids '.' and
# ':'), else stable and derived from the dir.
if [ -n "$session_override" ]; then
    session=$(printf %s "$session_override" | tr '.:' '--')
else
    slug=$(printf %s "$slug_src" | tr '[:upper:]' '[:lower:]' | sed -e 's#[^a-z0-9]\{1,\}#-#g' -e 's#^-##' -e 's#-$##')
    [ -n "$slug" ] || slug='home'
    session="claude-rc-${slug}"
fi

# --- build the remote bootstrap (base64'd to survive all quoting layers) ----
# Decoded and run by `sh` on the far side. Resolves DIR, validates it, then
# starts `claude rc` in a tmux session under a login shell (so ~/.local/bin,
# where claude lives, is on PATH). tmux -c sets the session start-dir, avoiding
# a fragile inner `cd "$DIR"`. ENSURE=1 → start detached if absent, no attach.
# RESPAWN=1 → wrap claude rc in a restart loop so crashes self-heal.
boot=$(cat <<BOOT
REL=$(printf %q "$rel")
ABS=$(printf %q "$abs")
RC_ARGS=$(printf %q "$rc_args")
SESS=$(printf %q "$session")
ENSURE=$ensure
RESPAWN=$respawn
if [ "\$ABS" = "~" ]; then DIR=\$HOME
elif [ -n "\$ABS" ] && [ "\${ABS#~/}" != "\$ABS" ]; then DIR="\$HOME/\${ABS#~/}"
elif [ -n "\$ABS" ]; then DIR=\$ABS
else DIR="\$HOME\${REL:+/\$REL}"
fi
if ! cd "\$DIR" 2>/dev/null; then
    echo "crc: directory not found on host: \$DIR" >&2
    exit 1
fi
SH=\${SHELL:-/bin/sh}
if [ "\$RESPAWN" = 1 ]; then
    CMD="\$SH -lc 'while true; do claude rc \$RC_ARGS; sleep 3; done'"
else
    CMD="\$SH -lc 'exec claude rc \$RC_ARGS'"
fi
if [ "\$ENSURE" = 1 ]; then
    if tmux has-session -t "\$SESS" 2>/dev/null; then
        echo "crc: \$SESS already running" >&2
    else
        tmux new-session -d -c "\$DIR" -s "\$SESS" "\$CMD" && echo "crc: started detached \$SESS" >&2
    fi
else
    exec tmux new-session -A -c "\$DIR" -s "\$SESS" "\$CMD"
fi
BOOT
)
boot_b64=$(printf %s "$boot" | base64 | tr -d '\n')

run_remote="printf %s '${boot_b64}' | base64 -d | sh"

echo "crc: ${session} → claude rc in ${abs:-\$HOME/${rel}} on ${host}" >&2
[ "$ensure" -eq 0 ] && echo "crc: detach with Ctrl-b d (server keeps running); reattach by re-running this command." >&2

if [ "$dry_run" -eq 1 ]; then
    echo "--- remote script ($host) ---" >&2
    printf %s "$boot_b64" | base64 -d
    echo
    exit 0
fi

case "$host" in
    local|localhost|.)
        command -v tmux >/dev/null 2>&1 || { echo "crc: tmux not found locally" >&2; exit 127; }
        eval "$run_remote"
        ;;
    *)
        if [ "$ensure" -eq 1 ]; then exec ssh "$host" "$run_remote"
        else exec ssh -t "$host" "$run_remote"; fi
        ;;
esac
