#!/usr/bin/env bash
# Generate a gitignored docker-compose.override.yml (busy host ports → free ones)
# and start the local stack. Invoked by `make up-local`.
set -euo pipefail

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

COMPOSE="${COMPOSE:-docker compose}"
OVERRIDE="${LOCAL_OVERRIDE:-docker-compose.override.yml}"

PREFERRED_SIMULATOR="${SIMULATOR_PORT:-8006}"
PREFERRED_POSTGRES="${POSTGRES_HOST_PORT:-5432}"
PREFERRED_TLS="${TLS_GATEWAY_PORT:-8443}"

port_in_use() {
  local port="$1"
  if command -v nc >/dev/null 2>&1; then
    nc -z 127.0.0.1 "$port" >/dev/null 2>&1
    return $?
  fi
  python3 - "$port" <<'PY'
import socket, sys
port = int(sys.argv[1])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(0.25)
try:
    sys.exit(0 if s.connect_ex(("127.0.0.1", port)) == 0 else 1)
finally:
    s.close()
PY
}

ours_on_port() {
  local port="$1"
  # Host publish lines look like: 0.0.0.0:8006->8006/tcp or 127.0.0.1:5432->5432/tcp
  $COMPOSE ps --format '{{.Ports}}' 2>/dev/null \
    | grep -E "(^|[, ])(([0-9.]+|\[::\]):)?${port}->" >/dev/null 2>&1
}

pick_port() {
  local preferred="$1"
  local label="$2"
  local max=$((preferred + 100))
  local p="$preferred"
  while [ "$p" -le "$max" ]; do
    if ! port_in_use "$p" || ours_on_port "$p"; then
      if [ "$p" -ne "$preferred" ]; then
        echo "Port ${preferred} busy for ${label} → using ${p}" >&2
      fi
      echo "$p"
      return 0
    fi
    p=$((p + 1))
  done
  echo "No free host port near ${preferred} for ${label}" >&2
  exit 1
}

SIMULATOR_HOST_PORT="$(pick_port "$PREFERRED_SIMULATOR" "simulator")"
POSTGRES_HOST_PORT="$(pick_port "$PREFERRED_POSTGRES" "postgres")"
TLS_HOST_PORT="$(pick_port "$PREFERRED_TLS" "tls-gateway")"

cat >"$OVERRIDE" <<EOF
# Generated by scripts/up-local.sh / \`make up-local\`.
# Gitignored — do not commit. Compose loads this file automatically.
services:
  postgres:
    ports: !override
      - "127.0.0.1:${POSTGRES_HOST_PORT}:5432"
  simulator:
    ports: !override
      - "${SIMULATOR_HOST_PORT}:8006"
  tls-gateway:
    ports: !override
      - "${TLS_HOST_PORT}:8443"
EOF

echo "Wrote ${OVERRIDE}:"
echo "  simulator  → http://localhost:${SIMULATOR_HOST_PORT}/"
echo "  postgres   → 127.0.0.1:${POSTGRES_HOST_PORT}"
echo "  tls-gateway→ https://localhost:${TLS_HOST_PORT}/ (profile tls)"

test -f .env || cp .env.example .env
$COMPOSE up -d --build --wait

echo
echo "Local stack is up: http://localhost:${SIMULATOR_HOST_PORT}/"
echo "Health:            http://localhost:${SIMULATOR_HOST_PORT}/health/ready"
