#!/usr/bin/env bash

set -Eeuo pipefail
IFS=$'\n\t'

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

log() {
  echo "[bff:dev] $*"
}

kill_tree() {
  local pid="$1"
  if [ -z "${pid:-}" ]; then return 0; fi
  if kill -0 "$pid" >/dev/null 2>&1; then
    kill "$pid" >/dev/null 2>&1 || true
    # Give it a moment to exit gracefully
    sleep 0.2 || true
    kill -9 "$pid" >/dev/null 2>&1 || true
  fi
}

PID_BUILD=""
PID_ALIAS=""
PID_NODE=""

cleanup() {
  log "Stopping dev processes..."
  kill_tree "$PID_NODE"
  kill_tree "$PID_ALIAS"
  kill_tree "$PID_BUILD"
}

trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

cd "$ROOT_DIR"

log "Starting TypeScript build watcher (tsc --watch)..."
pnpm run -s dev:build:watch &
PID_BUILD=$!

# Wait for initial output to exist
MAIN_FILE="$ROOT_DIR/dist/main.js"
WAIT_SECS="${BFF_BUILD_WAIT_SECS:-180}"
log "Waiting for initial build output: $MAIN_FILE (timeout: ${WAIT_SECS}s)"
loops=$((WAIT_SECS * 4))
for ((i=1; i<=loops; i++)); do
  if [ -f "$MAIN_FILE" ]; then
    break
  fi
  sleep 0.25
  if ! kill -0 "$PID_BUILD" >/dev/null 2>&1; then
    log "Build watcher exited unexpectedly."
    exit 1
  fi
done

if [ ! -f "$MAIN_FILE" ]; then
  log "Timed out waiting for $MAIN_FILE"
  log "Tip: if this keeps happening, run: pnpm -C \"$ROOT_DIR\" run build"
  exit 1
fi

log "Rewriting path aliases in dist (tsc-alias)..."
pnpm run -s dev:alias

log "Starting alias rewriter watcher (tsc-alias -w)..."
pnpm run -s dev:alias:watch &
PID_ALIAS=$!

RUN_SCRIPT="${BFF_NODE_RUN_SCRIPT:-dev:run:watch}"
log "Starting Node runtime watcher ($RUN_SCRIPT)..."
pnpm run -s "$RUN_SCRIPT" &
PID_NODE=$!

# If any process exits, stop the rest (compatible with bash 3.2)
while true; do
  for pid in "$PID_BUILD" "$PID_ALIAS" "$PID_NODE"; do
    if ! kill -0 "$pid" 2>/dev/null; then
      wait "$pid" 2>/dev/null || true
      exit_code=$?
      log "A dev process exited (code=$exit_code). Shutting down."
      exit "$exit_code"
    fi
  done
  sleep 1
done
