#!/bin/bash
# resume-tunnel.sh — Resume the Cloudflare tunnel on boot
#
# Called as ExecStartPre in maxy.service. Reads ~/.cloudflared/tunnel.state,
# checks whether the recorded PID is still a running cloudflared process,
# and spawns a new daemon if not. All failures exit 0 — this script must
# never prevent maxy.service from starting.
#
# Dependencies: jq, cloudflared (both installed by create-maxy)

set -uo pipefail

STATE_FILE="$HOME/.cloudflared/tunnel.state"

# Derive configDir from brand.json (MAXY_PLATFORM_ROOT is set by the systemd service).
# Fall back to .maxy if brand.json is unreadable.
CONFIG_DIR=".maxy"
if [ -n "${MAXY_PLATFORM_ROOT:-}" ] && [ -f "$MAXY_PLATFORM_ROOT/config/brand.json" ]; then
  BRAND_CONFIG_DIR=$(jq -r '.configDir // empty' "$MAXY_PLATFORM_ROOT/config/brand.json" 2>/dev/null || true)
  if [ -n "$BRAND_CONFIG_DIR" ]; then
    CONFIG_DIR="$BRAND_CONFIG_DIR"
  fi
fi

LOG_DIR="$HOME/$CONFIG_DIR/logs"
LOG_FILE="$LOG_DIR/cloudflared.log"

log() {
  mkdir -p "$LOG_DIR"
  echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] resume-tunnel: $1" >> "$LOG_FILE"
}

# No state file — no tunnel configured. Normal boot.
if [ ! -f "$STATE_FILE" ]; then
  exit 0
fi

log "configDir resolved to $CONFIG_DIR"

# Parse state file
if ! STATE=$(jq -r '.' "$STATE_FILE" 2>/dev/null); then
  log "WARNING: tunnel.state is not valid JSON — skipping resume"
  exit 0
fi

CONNECTOR_TOKEN=$(echo "$STATE" | jq -r '.connectorToken // empty')
TUNNEL_ID=$(echo "$STATE" | jq -r '.tunnelId // empty')
DOMAIN=$(echo "$STATE" | jq -r '.domain // empty')
OLD_PID=$(echo "$STATE" | jq -r '.pid // empty')

if [ -z "$CONNECTOR_TOKEN" ]; then
  log "WARNING: tunnel.state has no connectorToken — skipping resume"
  exit 0
fi

# Check if the recorded PID is still a running cloudflared process
if [ -n "$OLD_PID" ] && [ "$OLD_PID" != "null" ]; then
  if kill -0 "$OLD_PID" 2>/dev/null; then
    # PID is alive — verify it's actually cloudflared (not a reused PID)
    PROC_NAME=$(cat "/proc/$OLD_PID/comm" 2>/dev/null || true)
    if [ "$PROC_NAME" = "cloudflared" ]; then
      log "Tunnel already running (PID $OLD_PID) — skipping resume"
      exit 0
    fi
    # PID alive but not cloudflared — stale PID from before reboot
    log "PID $OLD_PID is alive but is '$PROC_NAME', not cloudflared — will start new daemon"
  fi
fi

# Find cloudflared binary
CLOUDFLARED_BIN=$(command -v cloudflared 2>/dev/null || true)
if [ -z "$CLOUDFLARED_BIN" ]; then
  log "ERROR: cloudflared binary not found — cannot resume tunnel"
  exit 0
fi

# Start the tunnel daemon (detached, survives service restart)
log "Resuming tunnel $TUNNEL_ID for $DOMAIN..."
mkdir -p "$LOG_DIR"
nohup "$CLOUDFLARED_BIN" tunnel run --token "$CONNECTOR_TOKEN" >> "$LOG_FILE" 2>&1 &
NEW_PID=$!

if [ -z "$NEW_PID" ] || [ "$NEW_PID" -le 0 ] 2>/dev/null; then
  log "ERROR: failed to spawn cloudflared — no PID returned"
  exit 0
fi

# Update state file with new PID
UPDATED_STATE=$(echo "$STATE" | jq --argjson pid "$NEW_PID" --argjson ts "$(date +%s)000" \
  '.pid = $pid | .startedAt = $ts')

if echo "$UPDATED_STATE" > "$STATE_FILE.tmp" 2>/dev/null && mv "$STATE_FILE.tmp" "$STATE_FILE" 2>/dev/null; then
  log "Tunnel resumed — PID $NEW_PID"
else
  rm -f "$STATE_FILE.tmp" 2>/dev/null
  log "WARNING: tunnel started (PID $NEW_PID) but failed to update state file"
fi

exit 0
