#!/usr/bin/env bash
set -Eeuo pipefail

RELAY="wss://commander.zippri.com/relay"
PACKAGE_URL="https://commander.zippri.com/downloads/Rabbit-Commander-Customer-Installer-1.1.1.zip"
NODE_CHANNEL_URL="https://nodejs.org/dist/latest-v22.x"
DIR="/workspace/rabbit-commander-agent"
NODE_DIR="/workspace/rabbit-node-v22"
ENV_FILE="$DIR/agent.env"
SUP="$DIR/supervise-rabbit-agent.sh"
LOG="$DIR/agent-supervisor.log"

echo "=================================================="
echo " Rabbit Commander RunPod Installer"
echo "=================================================="

if [ ! -d /workspace ]; then
  echo "ERROR: /workspace is not available. Attach/mount persistent RunPod storage first."
  exit 2
fi
if ! command -v curl >/dev/null 2>&1; then
  echo "ERROR: curl is required."
  exit 5
fi

NODE_BIN="$(command -v node || true)"
NODE_MAJOR=0
if [ -n "$NODE_BIN" ]; then
  NODE_MAJOR="$("$NODE_BIN" -p 'process.versions.node.split(".")[0]' 2>/dev/null || echo 0)"
fi

if [ "${NODE_MAJOR:-0}" -lt 18 ]; then
  echo "Node.js 18+ not found. Bootstrapping portable Node.js 22 under /workspace..."
  case "$(uname -m)" in
    x86_64|amd64) NODE_ARCH="x64" ;;
    aarch64|arm64) NODE_ARCH="arm64" ;;
    *)
      echo "ERROR: unsupported CPU architecture for automatic Node bootstrap: $(uname -m)"
      exit 3
      ;;
  esac

  TMP_NODE="$(mktemp -d)"
  trap 'rm -rf "$TMP_NODE"' EXIT
  curl -fsSL "$NODE_CHANNEL_URL/SHASUMS256.txt" -o "$TMP_NODE/SHASUMS256.txt"
  LINE="$(awk -v suffix="linux-${NODE_ARCH}.tar.gz" '$2 ~ suffix"$" {print $1" "$2; exit}' "$TMP_NODE/SHASUMS256.txt")"
  EXPECTED_SHA="${LINE%% *}"
  NODE_FILE="${LINE#* }"
  if [ -z "$EXPECTED_SHA" ] || [ -z "$NODE_FILE" ] || [ "$NODE_FILE" = "$LINE" ]; then
    echo "ERROR: unable to resolve portable Node.js package."
    exit 3
  fi

  curl -fsSL "$NODE_CHANNEL_URL/$NODE_FILE" -o "$TMP_NODE/$NODE_FILE"
  printf '%s  %s\n' "$EXPECTED_SHA" "$TMP_NODE/$NODE_FILE" | sha256sum -c -
  mkdir -p "$TMP_NODE/extract"
  tar -xzf "$TMP_NODE/$NODE_FILE" -C "$TMP_NODE/extract"
  EXTRACTED="$(find "$TMP_NODE/extract" -mindepth 1 -maxdepth 1 -type d | head -1)"
  if [ -z "$EXTRACTED" ] || [ ! -x "$EXTRACTED/bin/node" ]; then
    echo "ERROR: portable Node.js extraction failed."
    exit 3
  fi
  rm -rf "$NODE_DIR"
  mv "$EXTRACTED" "$NODE_DIR"
  NODE_BIN="$NODE_DIR/bin/node"
  NODE_MAJOR="$("$NODE_BIN" -p 'process.versions.node.split(".")[0]')"
  echo "Portable Node.js installed: $("$NODE_BIN" --version)"
  rm -rf "$TMP_NODE"
  trap - EXIT
fi

if [ "${NODE_MAJOR:-0}" -lt 18 ]; then
  echo "ERROR: Node.js 18+ is required."
  exit 4
fi

read -r -p "Rabbit Commander Device ID: " DEVICE_ID < /dev/tty
read -r -s -p "Rabbit Commander Device Token: " DEVICE_TOKEN < /dev/tty
echo > /dev/tty

if [[ ! "$DEVICE_ID" =~ ^[0-9a-fA-F-]{36}$ ]]; then
  echo "ERROR: Device ID format looks invalid."
  exit 7
fi
if [ "${#DEVICE_TOKEN}" -lt 40 ]; then
  echo "ERROR: Device Token format looks invalid."
  exit 8
fi

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
curl -fsSL "$PACKAGE_URL" -o "$TMP/rabbit.zip"
if command -v unzip >/dev/null 2>&1; then
  unzip -q "$TMP/rabbit.zip" -d "$TMP/pkg"
elif command -v python3 >/dev/null 2>&1; then
  python3 -m zipfile -e "$TMP/rabbit.zip" "$TMP/pkg"
else
  echo "ERROR: unzip or python3 is required to extract the installer package."
  exit 6
fi

if [ ! -f "$TMP/pkg/agent/agent.js" ]; then
  echo "ERROR: Rabbit Commander agent payload is missing from the package."
  exit 9
fi

mkdir -p "$DIR"
cp "$TMP/pkg/agent/agent.js" "$DIR/agent.js"
cp "$TMP/pkg/agent/package.json" "$DIR/package.json"
cp "$TMP/pkg/agent/package-lock.json" "$DIR/package-lock.json"
rm -rf "$DIR/node_modules"
cp -R "$TMP/pkg/agent/node_modules" "$DIR/node_modules"

cat > "$ENV_FILE" <<EOF
RABBIT_COMMANDER_RELAY=$RELAY
RABBIT_COMMANDER_DEVICE_ID=$DEVICE_ID
RABBIT_COMMANDER_TOKEN=$DEVICE_TOKEN
RABBIT_COMMANDER_ENABLE_SHELL=1
RABBIT_COMMANDER_NODE_BIN=$NODE_BIN
EOF
chmod 600 "$ENV_FILE"

cat > "$SUP" <<'EOF'
#!/usr/bin/env bash
set -Eeuo pipefail
DIR="/workspace/rabbit-commander-agent"
ENV_FILE="$DIR/agent.env"
LOG="$DIR/agent-supervisor.log"
while true; do
  set -a
  source "$ENV_FILE"
  set +a
  NODE_BIN="${RABBIT_COMMANDER_NODE_BIN:-$(command -v node || true)}"
  if [ -z "$NODE_BIN" ] || [ ! -x "$NODE_BIN" ]; then
    echo "$(date -Is) node runtime unavailable; restarting in 5s" >> "$LOG"
    sleep 5
    continue
  fi
  echo "$(date -Is) starting Rabbit Commander agent with $NODE_BIN" >> "$LOG"
  set +e
  "$NODE_BIN" "$DIR/agent.js" >> "$LOG" 2>&1
  code=$?
  set -e
  echo "$(date -Is) agent exited code=$code; restarting in 5s" >> "$LOG"
  sleep 5
done
EOF
chmod 700 "$SUP"

pkill -f "$DIR/agent.js" 2>/dev/null || true
pkill -f "$SUP" 2>/dev/null || true
nohup bash "$SUP" >> "$DIR/supervisor-launch.log" 2>&1 &
sleep 4

echo
echo "Rabbit Commander RunPod agent installed."
echo "Persistent path: $DIR"
echo "Node runtime: $NODE_BIN ($("$NODE_BIN" --version))"
echo
echo "Process check:"
pgrep -af "$DIR/agent.js|supervise-rabbit-agent.sh" || true
echo
echo "Last log lines:"
tail -20 "$LOG" 2>/dev/null || true
echo
echo "Next: open https://commander.zippri.com and confirm the RunPod device is ONLINE."
