#!/usr/bin/env bash
# ── fromSpec Build Script ─────────────────────────────────────────────────────
# Mode is required — there is no implicit default. See `./build.sh help`.
# ──────────────────────────────────────────────────────────────────────────────
set -euo pipefail

usage() {
  cat <<'EOF'
fromSpec build script.

Usage:
  ./build.sh help                  Show this help.
  ./build.sh dev  [<service>]      Build dev stack (hot reload, source
                                   mounts, dev secret defaults).
  ./build.sh prod [<service>]      Build prod stack (slim images,
                                   gunicorn, nginx-served SPA).
                                   Required env in .env:
                                     SECRET_KEY, CORS_ORIGINS,
                                     DATABASE_URL,
                                     KEYCLOAK_ADMIN_PASSWORD, ENV,
                                     VITE_KEYCLOAK_URL,
                                     VITE_WEBSITE_URL
                                   See .env.example for the full list.

Service names: backend | worker | frontend | postgres | redis | keycloak | …
EOF
}

MODE="${1:-}"
case "$MODE" in
  help|-h|--help)
    usage
    exit 0
    ;;
  dev)
    COMPOSE_FILES=(-f docker-compose.yml)
    ;;
  prod)
    COMPOSE_FILES=(-f docker-compose.yml -f docker-compose.prod.yml)
    ;;
  "")
    echo "Error: mode is required (dev | prod | help)." >&2
    echo >&2
    usage >&2
    exit 2
    ;;
  *)
    echo "Error: unknown mode '$MODE' (expected: dev | prod | help)." >&2
    echo >&2
    usage >&2
    exit 2
    ;;
esac
shift

# Reject any leftover flags. There are none today; this guard keeps a
# typo from being silently swallowed as a service name.
while [ $# -gt 0 ]; do
  case "$1" in
    --*)
      echo "Error: unknown flag '$1'." >&2
      echo >&2
      usage >&2
      exit 2
      ;;
    *)
      break  # first non-flag arg is the service name
      ;;
  esac
done

# Single source of truth for the version string. Bump VERSION at the
# repo root → compose substitutes it into image tags AND backend env
# (FROMSPEC_VERSION) → /health and FastAPI's app.version both reflect it.
export FROMSPEC_VERSION=$(cat VERSION 2>/dev/null | tr -d '[:space:]' || echo "0.1.0")

# Auto-detect git metadata
export GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
export GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
export BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)

# Auto-increment build number (stored in .build_number file)
BUILD_FILE=".build_number"
if [ -f "$BUILD_FILE" ]; then
  CURRENT=$(cat "$BUILD_FILE")
  export BUILD_NUMBER=$((CURRENT + 1))
else
  export BUILD_NUMBER=1
fi
echo "$BUILD_NUMBER" > "$BUILD_FILE"

# Print build info
echo "┌──────────────────────────────────────┐"
echo "│  fromSpec ${FROMSPEC_VERSION} (build #${BUILD_NUMBER})"
echo "│  Mode:    ${MODE}"
echo "│  Commit:  ${GIT_COMMIT}"
echo "│  Branch:  ${GIT_BRANCH}"
echo "│  Time:    ${BUILD_TIME}"
echo "└──────────────────────────────────────┘"

TARGET="${1:-}"

if [ -n "$TARGET" ]; then
  echo "→ Building: $TARGET"
  docker compose "${COMPOSE_FILES[@]}" up -d --build "$TARGET"
else
  echo "→ Building: all services"
  docker compose "${COMPOSE_FILES[@]}" up -d --build
fi

echo "✓ Build complete"

# GitHub IdP provisioning is handled by the ``keycloak-init`` sidecar
# in docker-compose.yml — it auto-runs after KC reaches healthy and
# reads ``GITHUB_CLIENT_ID`` / ``GITHUB_CLIENT_SECRET`` from .env.
# To re-apply after rotating credentials without touching the rest of
# the stack:
#   docker compose up -d --force-recreate keycloak-init
#
# Tail the sidecar so a silent failure (bad YAML, KC race, auth fail)
# doesn't slip past unnoticed — keycloak-init has ``restart: "no"`` by
# design and nothing else depends on it, so without this surface an
# error would only become visible when a user later clicks "Sign in
# with GitHub".
if docker compose "${COMPOSE_FILES[@]}" ps -a --format '{{.Name}}' | grep -q '^fromspec_keycloak_init$'; then
  echo
  echo "── keycloak-init (last 10 lines) ──"
  docker compose "${COMPOSE_FILES[@]}" logs --tail=10 keycloak-init 2>&1 \
    || echo "warning: failed to read keycloak-init logs" >&2
fi
