#!/data/data/com.termux/files/usr/bin/bash
# =============================================================================
# gcp-phone-setup-ubuntu.sh — expose a phone's UBUNTU sshd over the GCP relay.
#
# For a phone whose Termux already has an Ubuntu (proot) inside it. Tunnels the
# Ubuntu sshd (port 8021) out through your GCP VM, so you reach a full Ubuntu at
#   ssh -i pc-access-key root@<VM_IP> -p <PORT>
#
# Auto-detects how Ubuntu is launched:
#   * proot-distro     (proot-distro login ubuntu)
#   * start-ubuntu22   (~/start-ubuntu22.sh  +  ~/ubuntu22-fs)   [Andronix style]
# Override with --distro-type / --ubuntu-rootfs / --enter-cmd if needed.
#
# Copy TWO files onto the phone first (any folder):
#   --vm-key      the private key that logs in to the VM as the relay user
#                 (reuse the SAME google_compute_engine key across phones)
#   --pc-pubkey   pc-access-key.pub — authorizes YOUR PC to ssh into this phone
#
# Usage:
#   bash gcp-phone-setup-ubuntu.sh --port 2224 \
#        --vm-key ./google_compute_engine --pc-pubkey ./pc-access-key.pub
#
# Options (defaults): --vm-ip 136.67.4.216  --vm-user karthik  --ssh-port 8021
#   --distro-type proot-distro|start-ubuntu22   --ubuntu-rootfs PATH
#   --enter-cmd "CMD"   --low-battery 20   --no-boot   --no-watchdog   --help
# =============================================================================
set -uo pipefail

VM_IP="136.67.4.216"; VM_USER="karthik"; SSH_PORT="8021"
PORT=""; VM_KEY=""; PC_PUBKEY=""; LOW_BAT="20"
ENABLE_BOOT=1; ENABLE_WATCHDOG=1
DISTRO_TYPE=""; ROOTFS=""; ENTER_CMD=""
BIN="/data/data/com.termux/files/usr/bin"
PREFIX="/data/data/com.termux/files/usr"

die() { echo "ERROR: $*" >&2; exit 1; }
usage() { sed -n '2,34p' "$0"; }

while [ $# -gt 0 ]; do
    case "$1" in
        --port)         PORT="${2:-}"; shift 2;;
        --vm-key)       VM_KEY="${2:-}"; shift 2;;
        --pc-pubkey)    PC_PUBKEY="${2:-}"; shift 2;;
        --vm-ip)        VM_IP="${2:-}"; shift 2;;
        --vm-user)      VM_USER="${2:-}"; shift 2;;
        --ssh-port)     SSH_PORT="${2:-}"; shift 2;;
        --distro-type)  DISTRO_TYPE="${2:-}"; shift 2;;
        --ubuntu-rootfs) ROOTFS="${2:-}"; shift 2;;
        --enter-cmd)    ENTER_CMD="${2:-}"; shift 2;;
        --low-battery)  LOW_BAT="${2:-}"; shift 2;;
        --no-boot)      ENABLE_BOOT=0; shift;;
        --no-watchdog)  ENABLE_WATCHDOG=0; shift;;
        -h|--help)      usage; exit 0;;
        *) die "unknown argument: $1 (use --help)";;
    esac
done

[ -n "$PORT" ]      || die "--port is required"
[ -n "$VM_KEY" ] && [ -f "$VM_KEY" ]       || die "--vm-key file required/not found"
[ -n "$PC_PUBKEY" ] && [ -f "$PC_PUBKEY" ] || die "--pc-pubkey file required/not found"
case "$PORT" in ''|*[!0-9]*) die "--port must be a number";; esac
if [ "$PORT" -lt 2222 ] || [ "$PORT" -gt 2240 ]; then
    echo "WARNING: port $PORT is outside the VM firewall range 2222-2240 — open it first."
fi

echo "==> [1/9] installing Termux tools (openssh, termux-api, util-linux)"
yes | pkg update >/dev/null 2>&1 || true
pkg install -y openssh termux-api util-linux >/dev/null 2>&1 || die "pkg install failed"

# ---- detect the Ubuntu launcher -------------------------------------------
echo "==> [2/9] detecting Ubuntu environment"
if [ -z "$DISTRO_TYPE" ]; then
    if command -v proot-distro >/dev/null 2>&1 && \
       proot-distro list 2>/dev/null | grep -qiE 'ubuntu.*installed|installed.*ubuntu' ; then
        DISTRO_TYPE="proot-distro"
    elif [ -f "$HOME/start-ubuntu22.sh" ] && [ -d "$HOME/ubuntu22-fs" ]; then
        DISTRO_TYPE="start-ubuntu22"
    else
        die "no Ubuntu found. Install one first (e.g. 'pkg install proot-distro && proot-distro install ubuntu') or pass --distro-type/--ubuntu-rootfs/--enter-cmd"
    fi
fi
case "$DISTRO_TYPE" in
    proot-distro)
        : "${ROOTFS:=$PREFIX/var/lib/proot-distro/installed-rootfs/ubuntu}"
        : "${ENTER_CMD:=proot-distro login ubuntu}"
        # run a command inside ubuntu:
        urun() { proot-distro login ubuntu -- bash -lc "$1"; }
        # command that boots ubuntu and runs the relay in the FOREGROUND:
        UBUNTU_FG="proot-distro login ubuntu -- bash -lc 'service ssh start; exec bash /root/gcp_relay.sh'"
        ;;
    start-ubuntu22)
        : "${ROOTFS:=$HOME/ubuntu22-fs}"
        : "${ENTER_CMD:=bash $HOME/start-ubuntu22.sh}"
        urun() { bash "$HOME/start-ubuntu22.sh" "$1"; }
        UBUNTU_FG="bash $HOME/start-ubuntu22.sh 'service ssh start; exec bash /root/gcp_relay.sh'"
        ;;
    *) die "unknown --distro-type '$DISTRO_TYPE'";;
esac
[ -d "$ROOTFS/root" ] || die "ubuntu rootfs /root not found under: $ROOTFS"
echo "    type=$DISTRO_TYPE  rootfs=$ROOTFS"
UROOT="$ROOTFS/root"

echo "==> [3/9] installing openssh-server inside Ubuntu"
urun "apt-get update -y >/dev/null 2>&1; DEBIAN_FRONTEND=noninteractive apt-get install -y openssh-server openssh-client >/dev/null 2>&1; echo ok" \
    | tail -1 | grep -q ok || echo "    (apt may have warned; continuing)"

echo "==> [4/9] authorizing your PC key + key-only Ubuntu sshd on :$SSH_PORT"
mkdir -p "$UROOT/.ssh"; chmod 700 "$UROOT/.ssh"
touch "$UROOT/.ssh/authorized_keys"
cat "$PC_PUBKEY" >> "$UROOT/.ssh/authorized_keys"
sort -u "$UROOT/.ssh/authorized_keys" -o "$UROOT/.ssh/authorized_keys"
chmod 600 "$UROOT/.ssh/authorized_keys"
mkdir -p "$ROOTFS/etc/ssh/sshd_config.d"
cat > "$ROOTFS/etc/ssh/sshd_config.d/00-relay.conf" <<CONF
Port $SSH_PORT
PasswordAuthentication no
PermitRootLogin prohibit-password
PubkeyAuthentication yes
CONF

echo "==> [5/9] installing VM access key + relay config into Ubuntu"
install -m 600 "$VM_KEY" "$UROOT/.ssh/gcp_vm_key"
cat > "$UROOT/.gcp-relay.conf" <<CONF
VM_IP="$VM_IP"
VM_USER="$VM_USER"
LOCAL_SSH_PORT="$SSH_PORT"
CONF
echo "$PORT" > "$UROOT/.relay-port"

echo "==> checking VM port $PORT is free ..."
inuse=$(ssh -i "$VM_KEY" -o StrictHostKeyChecking=accept-new -o ConnectTimeout=15 \
        "$VM_USER@$VM_IP" "sudo ss -tlnH 2>/dev/null | grep -c ':$PORT '" 2>/dev/null || echo "?")
if [ "$inuse" = "1" ]; then
    die "port $PORT already in use on the VM — pick a different --port"
elif [ "$inuse" = "?" ]; then
    echo "    (could not reach VM to pre-check; continuing)"
else
    echo "    port $PORT is free"
fi

echo "==> [6/9] writing /root/gcp_relay.sh inside Ubuntu"
cat > "$UROOT/gcp_relay.sh" <<'RELAY'
#!/bin/bash
# Single reverse SSH tunnel: Ubuntu sshd -> VM:PORT. Singleton per port (flock).
CONF="/root/.gcp-relay.conf"; [ -f "$CONF" ] && . "$CONF"
VM_IP="${VM_IP:-136.67.4.216}"; VM_USER="${VM_USER:-karthik}"
LOCAL_SSH_PORT="${LOCAL_SSH_PORT:-8021}"
REMOTE_PORT="${1:-$(cat /root/.relay-port 2>/dev/null || echo 2222)}"
VM_KEY="/root/.ssh/gcp_vm_key"
LOCK="/root/.gcp_relay.${REMOTE_PORT}.lock"; PIDFILE="/root/.gcp_relay.${REMOTE_PORT}.pid"
exec 9>"$LOCK"
if ! flock -n 9; then echo "[$(date '+%F %T')] relay $REMOTE_PORT already running"; exit 0; fi
echo $$ > "$PIDFILE"; trap 'rm -f "$PIDFILE"' EXIT
while true; do
    echo "[$(date '+%F %T')] tunnel $VM_IP:$REMOTE_PORT -> localhost:$LOCAL_SSH_PORT ..."
    ssh -i "$VM_KEY" -o StrictHostKeyChecking=accept-new \
        -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes -N \
        -R "0.0.0.0:${REMOTE_PORT}:localhost:${LOCAL_SSH_PORT}" "$VM_USER@$VM_IP" 9<&-
    echo "[$(date '+%F %T')] dropped (exit $?), retry 5s"; sleep 5
done
RELAY
chmod +x "$UROOT/gcp_relay.sh"

# Ubuntu /root/.bashrc autostart (interactive; flock dedupes)
if ! grep -qF ">>> gcp-relay autostart >>>" "$UROOT/.bashrc" 2>/dev/null; then
cat >> "$UROOT/.bashrc" <<'BRC'

# >>> gcp-relay autostart >>>
service ssh start >/dev/null 2>&1
setsid bash /root/gcp_relay.sh >>/root/relay.log 2>&1 </dev/null &
# <<< gcp-relay autostart <<<
BRC
fi

if [ "$ENABLE_WATCHDOG" = 1 ]; then
echo "==> [7/9] writing battery-watchdog.sh (Termux side, engages at ${LOW_BAT}%)"
cat > "$HOME/battery-watchdog.sh" <<WD
#!/data/data/com.termux/files/usr/bin/bash
LOW=$LOW_BAT; RESUME=35; INTERVAL=60; LOG=\$HOME/battery-watchdog.log
BIN=/data/data/com.termux/files/usr/bin
command -v "\$BIN/termux-battery-status" >/dev/null 2>&1 || { echo "[\$(date)] no termux-api" >> "\$LOG"; exit 1; }
echo "[\$(date '+%F %T')] watchdog started (LOW=\$LOW)" >> "\$LOG"; protected=0
while true; do
    js=\$("\$BIN/termux-battery-status" 2>/dev/null)
    pct=\$(printf '%s' "\$js" | grep -oE '"percentage": *[0-9]+' | grep -oE '[0-9]+')
    plug=\$(printf '%s' "\$js" | grep -oE '"plugged": *"[^"]*"' | sed -E 's/.*"([^"]*)"\$/\1/')
    [ -z "\$pct" ] && { sleep "\$INTERVAL"; continue; }
    if [ "\$protected" = 0 ] && [ "\$pct" -le "\$LOW" ] && [ "\$plug" = "UNPLUGGED" ]; then
        echo "[\$(date '+%F %T')] LOW \$pct% unplugged -> sync + wake-unlock" >> "\$LOG"
        sync; "\$BIN/termux-wake-unlock"; protected=1
    elif [ "\$protected" = 1 ] && [ "\$pct" -ge "\$RESUME" ] && [ "\$plug" != "UNPLUGGED" ]; then
        echo "[\$(date '+%F %T')] recovered \$pct% charging -> wake-lock" >> "\$LOG"
        "\$BIN/termux-wake-lock"; protected=0
    fi
    sleep "\$INTERVAL"
done
WD
chmod +x "$HOME/battery-watchdog.sh"
fi

echo "==> [8/9] Termux ~/.bashrc auto-enter Ubuntu (Ctrl-C within 3s to skip)"
if ! grep -qF ">>> gcp-relay enter-ubuntu >>>" "$HOME/.bashrc" 2>/dev/null; then
cat >> "$HOME/.bashrc" <<BRC

# >>> gcp-relay enter-ubuntu >>>
case \$- in *i*)
    if [ ! -f ~/.no-ubuntu-autostart ]; then
        termux-wake-lock 2>/dev/null
        echo "Entering Ubuntu + GCP relay in 3s...  (Ctrl-C for plain Termux shell)"
        if sleep 3; then $ENTER_CMD; fi
    fi ;;
esac
# <<< gcp-relay enter-ubuntu <<<
BRC
fi

if [ "$ENABLE_BOOT" = 1 ]; then
echo "==> [9/9] installing Termux:Boot autostart script"
mkdir -p "$HOME/.termux/boot"
cat > "$HOME/.termux/boot/00-start-relay.sh" <<BOOT
#!/data/data/com.termux/files/usr/bin/bash
BIN=/data/data/com.termux/files/usr/bin
export PATH="\$BIN:\$PATH"
LOG="\$HOME/boot.log"
echo "[\$(date '+%F %T')] boot start" >> "\$LOG"
[ -f "\$HOME/battery-watchdog.sh" ] && \$BIN/setsid \$BIN/bash "\$HOME/battery-watchdog.sh" >/dev/null 2>&1 </dev/null &
\$BIN/termux-wake-lock
$UBUNTU_FG >> "\$LOG" 2>&1 &
echo "[\$(date '+%F %T')] boot launched ubuntu+relay" >> "\$LOG"
BOOT
chmod +x "$HOME/.termux/boot/00-start-relay.sh"
else
echo "==> [9/9] skipping Termux:Boot script (--no-boot)"
fi

echo "==> starting now (entering Ubuntu once to launch sshd + relay) ..."
urun "service ssh start >/dev/null 2>&1; setsid bash /root/gcp_relay.sh >>/root/relay.log 2>&1 </dev/null & sleep 2; echo started" >/dev/null 2>&1 &
sleep 14
if ssh -i "$VM_KEY" -o StrictHostKeyChecking=accept-new -o ConnectTimeout=15 \
      "$VM_USER@$VM_IP" "timeout 5 bash -c 'exec 3<>/dev/tcp/127.0.0.1/$PORT; head -1 <&3'" 2>/dev/null \
      | grep -q "SSH-2.0"; then
    RESULT="VERIFIED — tunnel is live"
else
    RESULT="not confirmed yet (still connecting? check Ubuntu /root/relay.log)"
fi

cat <<DONE

============================================================
 SETUP COMPLETE — $RESULT   (distro: $DISTRO_TYPE)
============================================================
 Connect to THIS phone's Ubuntu from your PC:
     ssh -i pc-access-key -p $PORT root@$VM_IP

 Logs:  Ubuntu /root/relay.log  |  ~/boot.log  |  ~/battery-watchdog.log
 Stop / free the port:  bash gcp-phone-teardown-ubuntu.sh
 Finish boot autostart: open Termux:Boot once + realme auto-launch/battery-unrestricted,
                        and TEST the watchdog before trusting unattended boot.
============================================================
DONE
