#!/usr/bin/env bash
set -euo pipefail
ROOT=/home/box/zen-lead-form
cd "$ROOT"
PORT=8790

app_healthy() {
  curl -fsS --max-time 3 "http://127.0.0.1:${PORT}/health" >/dev/null 2>&1
}

kill_app() {
  # Kill by pid file(s), anything listening on the port, and matching node mains
  if [[ -f zen-lead-form.pid ]]; then
    local pid
    pid=$(cat zen-lead-form.pid 2>/dev/null || true)
    if [[ -n "${pid}" ]]; then
      kill "$pid" 2>/dev/null || true
      # npm start spawns a child — also kill process group if possible
      pkill -P "$pid" 2>/dev/null || true
    fi
    rm -f zen-lead-form.pid
  fi
  if command -v fuser >/dev/null 2>&1; then
    fuser -k "${PORT}/tcp" >/dev/null 2>&1 || true
  fi
  pkill -f "${ROOT}/src/main.js" 2>/dev/null || true
  sleep 1
}

start_app() {
  nohup npm start >> zen-lead-form.log 2>&1 &
  echo $! > zen-lead-form.pid
  for i in $(seq 1 20); do
    if app_healthy; then
      # Prefer the real node listener pid if we can find it
      local node_pid
      node_pid=$(ss -ltnp 2>/dev/null | rg ":${PORT}\\b" | rg -o 'pid=[0-9]+' | head -1 | cut -d= -f2 || true)
      if [[ -n "${node_pid}" ]]; then
        echo "$node_pid" > zen-lead-form.pid
      fi
      return 0
    fi
    sleep 0.5
  done
  return 1
}

# Restart if source is newer than the running process, or health fails
needs_reload() {
  if ! app_healthy; then return 0; fi
  local node_pid
  node_pid=$(ss -ltnp 2>/dev/null | rg ":${PORT}\\b" | rg -o 'pid=[0-9]+' | head -1 | cut -d= -f2 || true)
  [[ -z "${node_pid}" ]] && return 0
  local start_epoch
  start_epoch=$(stat -c %Y "/proc/${node_pid}" 2>/dev/null || echo 0)
  local newest=0
  local f
  for f in src/*.js public/app.js public/index.html package.json; do
    [[ -f "$f" ]] || continue
    local m
    m=$(stat -c %Y "$f")
    (( m > newest )) && newest=$m
  done
  (( newest > start_epoch )) && return 0
  return 1
}

ensure_app() {
  if needs_reload; then
    kill_app
    start_app
  fi
}

ensure_tunnel() {
  if [[ -f tunnel.pid ]] && kill -0 "$(cat tunnel.pid)" 2>/dev/null; then
    if rg -q 'https://[a-zA-Z0-9.-]+\.trycloudflare\.com' tunnel.log 2>/dev/null; then return 0; fi
  fi
  : > tunnel.log
  nohup cloudflared tunnel --url "http://127.0.0.1:${PORT}" --no-autoupdate >> tunnel.log 2>&1 &
  echo $! > tunnel.pid
  for i in $(seq 1 15); do
    if rg -q 'https://[a-zA-Z0-9.-]+\.trycloudflare\.com' tunnel.log 2>/dev/null; then return 0; fi
    sleep 1
  done
  return 1
}

print_url() { rg -o 'https://[a-zA-Z0-9.-]+\.trycloudflare\.com' tunnel.log | tail -1 || true; }

case "${1:-ensure}" in
  ensure) ensure_app; ensure_tunnel; u=$(print_url); echo "$u" > public-url.txt; echo "$u" ;;
  restart) kill_app; start_app; ensure_tunnel; u=$(print_url); echo "$u" > public-url.txt; echo "$u" ;;
  url) print_url ;;
  *) echo "usage: $0 ensure|restart|url" >&2; exit 2 ;;
esac
