#!/bin/sh
#
# vwm-start -- launch a NEW vwm session under dtach.
#
# vwm runs detached from your login shell, so you can disconnect (an SSH
# drop, a closed laptop, or the Ctrl-\ detach key) and later run
# vwm-resume to pick up exactly where you left off.
#
#   vwm-start   -- START a session (use this once)
#   vwm-resume  -- RECONNECT to a session that is already running
#
# Detach key while attached:  Ctrl-\
#
# Environment:
#   VWM_SOCK  path to the dtach socket   (default: ~/.vwm.sock)
#   VWM_BIN   path to the vwm binary     (default: vwm, from PATH)

set -u

SOCK="${VWM_SOCK:-$HOME/.vwm.sock}"

# --- locate dtach ---------------------------------------------------
if ! command -v dtach >/dev/null 2>&1; then
    echo "vwm-start: dtach is not installed." >&2
    echo "  Debian/Ubuntu:  sudo apt install dtach" >&2
    exit 1
fi

# --- locate the vwm binary ------------------------------------------
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
if [ -n "${VWM_BIN:-}" ]; then
    :                                   # caller specified one
elif command -v vwm >/dev/null 2>&1; then
    VWM_BIN=vwm                         # installed, on PATH
elif [ -x "$script_dir/../vwm" ]; then
    VWM_BIN="$script_dir/../vwm"        # running from a build tree
else
    VWM_BIN=vwm                         # last resort; let dtach report it
fi

# --- find the PID holding the socket, if any (i.e. a live session) --
socket_holder() {
    [ -S "$1" ] || return 0

    if command -v ss >/dev/null 2>&1; then
        ss -xlp 2>/dev/null | grep -F "$1" \
            | grep -o 'pid=[0-9]*' | head -n1 | cut -d= -f2
    elif command -v lsof >/dev/null 2>&1; then
        lsof -t -- "$1" 2>/dev/null | head -n1
    elif command -v fuser >/dev/null 2>&1; then
        fuser "$1" 2>/dev/null | tr -s ' ' '\n' \
            | grep -E '^[0-9]+$' | head -n1
    fi
}

# --- disable mouse reporting on the OUTER terminal at detach --------
# vwm enabled it by writing escapes straight to the tty, and dtach gives
# the inner process no detach hook, so vwm never hears the detach and
# cannot turn it off.  Without this the shell we return to receives
# every mouse movement as escape-sequence garbage.
disable_mouse() {
    printf '\033[?1003l\033[?1002l\033[?1000l\033[?1006l\033[?1015l' \
        > /dev/tty 2>/dev/null || true
}

# --- sanity check: is a session already present? --------------------
if [ -e "$SOCK" ]; then
    holder=$(socket_holder "$SOCK")

    if [ -n "$holder" ]; then
        echo "A vwm session is already running (pid $holder)."
        echo "To reconnect to it, use:  vwm-resume"
        echo
        echo "Starting a new session means terminating that one and"
        echo "every program inside it."
        printf "Terminate it and start fresh? [y/N] "
        read -r reply
        case "$reply" in
            y|Y|yes|YES)
                kill "$holder" 2>/dev/null
                i=0
                while kill -0 "$holder" 2>/dev/null; do
                    i=$((i + 1))
                    if [ "$i" -ge 10 ]; then
                        kill -9 "$holder" 2>/dev/null
                        break
                    fi
                    sleep 0.2
                done
                rm -f "$SOCK"
                ;;
            *)
                echo "Left the running session alone.  Use vwm-resume."
                exit 0
                ;;
        esac
    else
        echo "Found a leftover socket from a session that is no longer"
        echo "running:  $SOCK"
        printf "Clean it up and start fresh? [Y/n] "
        read -r reply
        case "$reply" in
            n|N|no|NO)
                echo "Aborted."
                exit 0
                ;;
            *)
                rm -f "$SOCK"
                ;;
        esac
    fi
fi

# --- launch ---------------------------------------------------------
# No `exec`: the disable_mouse trap must outlive dtach so it can run
# when the client detaches.  -r winch makes vwm repaint and re-arm the
# mouse on every (re)attach; -z keeps Ctrl-Z from orphaning dtach.
trap disable_mouse EXIT

# Mark the environment so vwm can show a "dtach active" panel indicator
# (vwm reads getenv("VWM_SOCK")).  This is the supported entry point.
export VWM_SOCK="$SOCK"

dtach -c "$SOCK" -r winch -z "$VWM_BIN"
