#!/bin/bash
set -e

G='\033[0;32m'
Y='\033[1;33m'
R='\033[0;31m'
B='\033[0;34m'
C='\033[0;36m'
Z='\033[0m'
BOLD='\033[1m'

echo -e "${BOLD}${B}"
echo '  ██████╗ ██████╗  █████╗ ████████╗██╗   ██╗'
echo '  ██╔══██╗██╔══██╗██╔══██╗╚══██╔══╝██║   ██║'
echo '  ██████╔╝██████╔╝███████║   ██║   ██║   ██║'
echo '  ██╔═══╝ ██╔══██╗██╔══██║   ██║   ██║   ██║'
echo '  ██║     ██║  ██║██║  ██║   ██║   ╚██████╔╝'
echo '  ╚═╝     ╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝    ╚═════╝ '
echo -e "${Z}"
echo -e "${BOLD}  VM Setup Script${Z} — OpenSSH · Node.js · Cloudflare Tunnel"
echo -e "  ${C}platform-registry.pages.dev${Z}"
echo

# ─── Step 1: OpenSSH ────────────────────────────────────────────────────────
echo -e "${Y}[1/6]${Z} Checking OpenSSH..."
if command -v sshd &>/dev/null && pgrep -x sshd >/dev/null; then
    echo -e "${G}✓${Z} OpenSSH already running"
else
    echo -e "${Y}  Installing OpenSSH...${Z}"
    if command -v apt-get &>/dev/null; then
        apt-get update -qq 2>/dev/null && apt-get install -y -qq openssh-server >/dev/null 2>&1 || true
    elif command -v yum &>/dev/null; then
        yum install -y -q openssh-server >/dev/null 2>&1 || true
    fi
    mkdir -p /run/sshd 2>/dev/null || true
    /usr/sbin/sshd 2>/dev/null || true
    sleep 1
    echo -e "${G}✓${Z} OpenSSH installed and started"
fi

# ─── Step 2: SSH Key Auth ────────────────────────────────────────────────────
echo -e "\n${Y}[2/6]${Z} Configuring SSH key authentication..."
mkdir -p /root/.ssh
chmod 700 /root/.ssh
touch /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
sed -i 's/#PermitRootLogin.*/PermitRootLogin yes/'              /etc/ssh/sshd_config 2>/dev/null || true
sed -i 's/PermitRootLogin.*/PermitRootLogin yes/'               /etc/ssh/sshd_config 2>/dev/null || true
sed -i 's/#PubkeyAuthentication.*/PubkeyAuthentication yes/'    /etc/ssh/sshd_config 2>/dev/null || true
sed -i 's/#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config 2>/dev/null || true
sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config 2>/dev/null || true
grep -q 'PermitRootLogin yes'      /etc/ssh/sshd_config || echo 'PermitRootLogin yes'      >> /etc/ssh/sshd_config
grep -q 'PubkeyAuthentication yes' /etc/ssh/sshd_config || echo 'PubkeyAuthentication yes' >> /etc/ssh/sshd_config
grep -q 'PasswordAuthentication no' /etc/ssh/sshd_config || echo 'PasswordAuthentication no' >> /etc/ssh/sshd_config
/usr/sbin/sshd -t 2>/dev/null && pkill -HUP sshd 2>/dev/null || true
echo -e "${G}✓${Z} Key-only auth enabled (password SSH disabled)"

# ─── Step 3: Node.js v18+ ───────────────────────────────────────────────────
echo -e "\n${Y}[3/6]${Z} Checking Node.js (v18+ required)..."
NODE_OK=false
if command -v node &>/dev/null; then
    NODE_VER=$(node -e 'process.stdout.write(String(process.versions.node.split(".")[0]))' 2>/dev/null || echo 0)
    if [ "$NODE_VER" -ge 18 ] 2>/dev/null; then
        echo -e "${G}✓${Z} Node.js $(node --version) already installed"
        NODE_OK=true
    else
        echo -e "${Y}  Node.js v${NODE_VER} found but < 18, upgrading...${Z}"
    fi
fi
if [ "$NODE_OK" = false ]; then
    echo -e "${Y}  Installing Node.js v20 LTS...${Z}"
    if command -v apt-get &>/dev/null; then
        curl -fsSL https://deb.nodesource.com/setup_20.x 2>/dev/null | bash - >/dev/null 2>&1 || true
        apt-get install -y -qq nodejs >/dev/null 2>&1 || true
    elif command -v yum &>/dev/null; then
        curl -fsSL https://rpm.nodesource.com/setup_20.x 2>/dev/null | bash - >/dev/null 2>&1 || true
        yum install -y -q nodejs >/dev/null 2>&1 || true
    else
        # Fallback: install via nvm
        curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh 2>/dev/null | bash >/dev/null 2>&1 || true
        export NVM_DIR="$HOME/.nvm"
        [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
        nvm install 20 >/dev/null 2>&1 || true
        nvm use 20 >/dev/null 2>&1 || true
    fi
    if command -v node &>/dev/null; then
        echo -e "${G}✓${Z} Node.js $(node --version) installed"
    else
        echo -e "${R}✗${Z} Node.js install failed — continuing without it"
    fi
fi

# ─── Step 4: cloudflared ────────────────────────────────────────────────────
echo -e "\n${Y}[4/6]${Z} Checking cloudflared..."
if command -v cloudflared &>/dev/null; then
    echo -e "${G}✓${Z} cloudflared already installed"
else
    echo -e "${Y}  Installing cloudflared...${Z}"
    ARCH=$(uname -m)
    if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
        CF_BIN="cloudflared-linux-arm64"
    else
        CF_BIN="cloudflared-linux-amd64"
    fi
    curl -sL "https://github.com/cloudflare/cloudflared/releases/latest/download/${CF_BIN}" -o /usr/local/bin/cloudflared 2>/dev/null
    chmod +x /usr/local/bin/cloudflared 2>/dev/null
    echo -e "${G}✓${Z} cloudflared installed"
fi

# ─── Step 5: Cloudflare Tunnel ───────────────────────────────────────────────
echo -e "\n${Y}[5/6]${Z} Starting Cloudflare Tunnel..."
pkill -f "cloudflared tunnel" 2>/dev/null || true
sleep 1
nohup cloudflared tunnel --url ssh://localhost:22 --log-level error > /tmp/cf.log 2>&1 &
echo -e "  ${C}Waiting for tunnel URL (up to 20s)...${Z}"
for i in $(seq 1 20); do
    TUNNEL_URL=$(grep -oP 'https://[^ ]+\.trycloudflare\.com' /tmp/cf.log 2>/dev/null | head -1)
    [ -n "$TUNNEL_URL" ] && break
    sleep 1
done
if [ -z "$TUNNEL_URL" ]; then
    echo -e "${R}✗${Z} Tunnel failed to start. Check /tmp/cf.log for details."
    exit 1
fi
echo -e "${G}✓${Z} Tunnel ready: ${BOLD}$TUNNEL_URL${Z}"

# ─── Step 6: Register + Fetch Public Key ────────────────────────────────────
echo -e "\n${Y}[6/6]${Z} Registration"
echo

if [ -z "$CODENAME" ]; then
    read -p "  VM codename [$(hostname | cut -d. -f1)]: " CODENAME
fi
HOSTN=$(hostname | cut -d. -f1)
CODENAME="${CODENAME:-$HOSTN}"

if [ -z "$PASSWORD" ]; then
    read -s -p "  Registry password: " PASSWORD
    echo
fi

if [ -z "$PASSWORD" ]; then
    echo -e "${R}✗${Z} Password is required to register"
    exit 1
fi

REGISTRY_URL="${REGISTRY_URL:-https://platform-registry.pages.dev}"
IP=$(hostname -I 2>/dev/null | awk '{print $1}' || echo "localhost")

echo -e "  ${C}Registering VM...${Z}"
RESP=$(curl -s -X POST "$REGISTRY_URL/api/update" \
    -H "Content-Type: application/json" \
    -H "x-registry-password: $PASSWORD" \
    -d "{\"codename\":\"$CODENAME\",\"platform_name\":\"$CODENAME\",\"url\":\"$TUNNEL_URL\",\"ip_address\":\"$IP\",\"metadata\":{\"tunnel_url\":\"$TUNNEL_URL\",\"os\":\"$(uname -s)\",\"hostname\":\"$(hostname)\"}}" 2>&1 || echo '{"ok":false}')

if echo "$RESP" | grep -q '"ok":true'; then
    echo -e "${G}✓${Z} Registered: ${BOLD}$CODENAME${Z} → $TUNNEL_URL"
else
    echo -e "${R}✗${Z} Registration failed: $RESP"
    exit 1
fi

# Fetch SSH public key from registry and add to authorized_keys
echo -e "  ${C}Fetching SSH public key from registry...${Z}"
PUB_KEY=$(curl -s "$REGISTRY_URL/api/platform/$CODENAME" | grep -o '"ssh_public_key":"[^"]*"' | sed 's/"ssh_public_key":"//;s/"$//' 2>/dev/null || echo "")
if [ -n "$PUB_KEY" ] && [ "$PUB_KEY" != "null" ]; then
    if ! grep -qF "$PUB_KEY" /root/.ssh/authorized_keys 2>/dev/null; then
        echo "$PUB_KEY" >> /root/.ssh/authorized_keys
        echo -e "${G}✓${Z} SSH public key added to authorized_keys"
    else
        echo -e "${G}✓${Z} SSH public key already present"
    fi
else
    echo -e "${Y}⚠${Z} No SSH public key in registry yet."
    echo -e "  On your PC: run ${BOLD}node cli.js${Z} → select this VM → press ${BOLD}k${Z} to push your key."
    echo -e "  Then re-run this script (or re-fetch the key manually) to grant access."
fi

# Write heartbeat cron — use printf to expand vars at write-time
printf '*/5 * * * * root curl -s -X POST "%s/api/heartbeat" -H "Content-Type: application/json" -H "x-registry-password: %s" -d "{\"codename\":\"%s\",\"url\":\"%s\"}" >/dev/null 2>&1\n' \
    "$REGISTRY_URL" "$PASSWORD" "$CODENAME" "$TUNNEL_URL" > /etc/cron.d/vm-hb 2>/dev/null || true
echo -e "${G}✓${Z} Heartbeat cron set (every 5 min)"

echo
echo -e "${BOLD}${G}═══════════════════ Setup Complete ═══════════════════${Z}"
echo -e "  VM:       ${BOLD}$CODENAME${Z}"
echo -e "  Tunnel:   ${BOLD}$TUNNEL_URL${Z}"
echo -e "  Registry: ${BOLD}$REGISTRY_URL${Z}"
echo
echo -e "  On your PC:"
echo -e "    1. ${BOLD}node cli.js${Z}                  → open TUI"
echo -e "    2. Select ${BOLD}$CODENAME${Z} → press ${BOLD}k${Z}   → push SSH key"
echo -e "    3. Press ${BOLD}Enter${Z}                  → passwordless connect"
echo -e "${BOLD}${G}══════════════════════════════════════════════════════${Z}"