#!/usr/bin/env bash
set -euo pipefail

# Simple setup script to bootstrap the Dockerized dev stack for this project.
# - Builds and starts containers (php, nginx, mariadb, mailpit via override)
# - Installs composer dependencies
# - Ensures APP_SECRET is set (generates if empty)
# - Creates and migrates the database
# - Installs/imports JS dependencies
# - Prints helpful info on success

# Usage:
#   ./docker/setup.sh            # full setup
#   ./docker/setup.sh --no-build # skip image rebuild
#   ./docker/setup.sh --down     # stop and remove containers (down)
#   ./docker/setup.sh --recreate # force recreate containers

ROOT_DIR=$(cd "$(dirname "$0")"/.. && pwd)
DOCKER_DIR="$ROOT_DIR/docker"
# Determine the docker compose command (V2 'docker compose' or V1 'docker-compose')
if docker compose version >/dev/null 2>&1; then
  DOCKER_COMPOSE="docker compose"
elif command -v docker-compose >/dev/null 2>&1; then
  DOCKER_COMPOSE="docker-compose"
else
  echo "Error: Neither 'docker compose' nor 'docker-compose' was found. Please install Docker Compose." >&2
  exit 1
fi

# Helper to run docker compose from the docker/ directory
dc() { (cd "$DOCKER_DIR" && $DOCKER_COMPOSE -f compose.yaml "$@"); }

REBUILD=1
RECREATE=0
DOWN_ONLY=0

for arg in "$@"; do
  case "$arg" in
    --no-build) REBUILD=0 ;;
    --recreate) RECREATE=1 ;;
    --down) DOWN_ONLY=1 ;;
    *) echo "Unknown option: $arg" >&2; exit 1 ;;
  esac
done

need() { command -v "$1" >/dev/null 2>&1 || { echo "Error: '$1' is required but not installed." >&2; exit 1; }; }

need docker

if [ "$DOWN_ONLY" -eq 1 ]; then
  dc down
  exit 0
fi

BUILD_ARGS=()
if [ "$REBUILD" -eq 1 ]; then
  BUILD_ARGS+=("--build")
fi
if [ "$RECREATE" -eq 1 ]; then
  BUILD_ARGS+=("--force-recreate")
fi

# Start stack
dc up "${BUILD_ARGS[@]}"

# Helper to run commands in php container
pexec() { dc exec -T php "$@"; }

# Wait for database to be healthy (mariadb)
printf "Waiting for database to be healthy..."
# Use docker inspect health status
DB_HEALTH=""
for i in {1..60}; do
  DB_HEALTH=$(docker inspect -f '{{.State.Health.Status}}' "$(docker ps --filter name=_database_ --format '{{.ID}}' | head -n1)" 2>/dev/null || true)
  if [ "$DB_HEALTH" = "healthy" ]; then
    echo " OK"
    break
  fi
  printf "."
  sleep 2
  if [ "$i" -eq 60 ]; then
    echo "\nWarning: database health check not healthy yet, continuing anyway."
  fi
done

# Ensure composer is available and install dependencies
pexec composer install --no-interaction

# Ensure APP_SECRET is set
if grep -q '^APP_SECRET=$' "$ROOT_DIR/.env" 2>/dev/null; then
  echo "Generating APP_SECRET in .env.local..."
  mkdir -p "$ROOT_DIR"
  SECRET=$(openssl rand -hex 16)
  # Write to .env.local so we don't commit it
  if [ ! -f "$ROOT_DIR/.env.local" ]; then
    printf "APP_SECRET=%s\n" "$SECRET" > "$ROOT_DIR/.env.local"
  elif ! grep -q '^APP_SECRET=' "$ROOT_DIR/.env.local"; then
    printf "APP_SECRET=%s\n" "$SECRET" >> "$ROOT_DIR/.env.local"
  fi
fi

# Prepare DB
pexec php bin/console doctrine:database:create --if-not-exists || true
pexec php bin/console doctrine:migrations:migrate -n || true

# Import JS deps (Importmap/Asset Mapper)
pexec php bin/console importmap:install || true

APP_URL=http://localhost:8080
MAILPIT_URL=http://localhost:8025

cat <<EOT

Setup complete!

Open the app:      $APP_URL
Mailpit (dev):     $MAILPIT_URL

Common commands:
  (cd docker && $DOCKER_COMPOSE logs -f nginx)
  (cd docker && $DOCKER_COMPOSE logs -f php)
  (cd docker && $DOCKER_COMPOSE exec php bash)
  (cd docker && $DOCKER_COMPOSE down)

You can re-run this script any time. Use --no-build to skip rebuilding images.
EOT
