#!/usr/bin/env bash
# bin/setup.sh — first-run / fresh-environment bootstrap for alqove-api.
#
# Idempotent. Safe to re-run; only does work that is missing.
# Run from the repo root or via `bin/setup.sh`.

set -euo pipefail

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

step() { printf '\n\033[1;36m[setup]\033[0m %s\n' "$*"; }

# 1. Bootstrap api/.env from .env.example if missing.
if [ ! -f api/.env ]; then
  step "Creating api/.env from .env.example"
  cp api/.env.example api/.env
fi

# 1b. Write WWWUSER/WWWGROUP into the root .env consumed by docker compose,
#     so the sail user inside the laravel.test container runs with the host
#     UID/GID. This keeps host-side file ownership consistent with the
#     container, preventing ".gitignore mode flipped to 755" churn after
#     artisan commands write to storage/.
HOST_UID="$(id -u)"
HOST_GID="$(id -g)"
touch .env
if ! grep -qE '^WWWUSER=' .env; then
  step "Pinning WWWUSER=$HOST_UID in root .env (compose)"
  printf 'WWWUSER=%s\n' "$HOST_UID" >> .env
fi
if ! grep -qE '^WWWGROUP=' .env; then
  printf 'WWWGROUP=%s\n' "$HOST_GID" >> .env
fi

# 2. Install composer deps via a one-shot composer container so vendor/ exists
#    on the host BEFORE `docker compose up` mounts paths under it. Otherwise
#    Docker auto-creates missing bind-mount targets as directories — most
#    notably api/vendor/laravel/sail/database/pgsql/create-testing-database.sql,
#    which postgres then can't read as a SQL init file.
if [ ! -d api/vendor ]; then
  step "Installing composer dependencies (one-shot container)"
  docker run --rm \
    -v "$ROOT/api:/app" \
    -w /app \
    composer:latest \
    install --no-interaction --prefer-dist --no-progress
fi

# 3. Bring up the docker compose stack.
step "Starting docker compose stack"
docker compose up -d

# 4. Wait for the laravel.test container to be ready.
step "Waiting for laravel.test to accept commands"
for _ in $(seq 1 30); do
  if docker compose exec -T laravel.test php -v >/dev/null 2>&1; then break; fi
  sleep 1
done

# 5. Fix storage/ + bootstrap/cache ownership. Docker creates these as root
#    when the bind mount targets do not yet exist; the sail user (uid 1000)
#    then can't write the laravel.log or compiled views.
step "Fixing storage/ + bootstrap/cache ownership"
docker compose exec -T -u root laravel.test bash -c \
  "chown -R sail:sail storage bootstrap/cache && chmod -R u+rwX,g+rwX storage bootstrap/cache"

# 6. Generate APP_KEY if not yet set.
if ! grep -qE '^APP_KEY=base64:' api/.env; then
  step "Generating APP_KEY"
  docker compose exec -T laravel.test php artisan key:generate
fi

# 7. Migrations + seeders.
step "Running migrate:fresh --seed"
docker compose exec -T laravel.test php artisan migrate:fresh --seed

# 8. Typesense schema + initial item index. The collection schema is a
#    separate concern from the SQL migrations, so it does not get created
#    by `migrate:fresh`; without it, /v1/items 500s with ObjectNotFound.
step "Syncing Typesense schema and importing items"
docker compose exec -T laravel.test php artisan alqove:typesense:sync-schema
docker compose exec -T laravel.test php artisan scout:import "App\\Models\\Item"

# 9. Clear caches so any leftover state is gone.
step "Clearing caches"
docker compose exec -T laravel.test php artisan optimize:clear

cat <<DONE

[setup] Done.
  API:     http://localhost:8000
  Mailpit: http://localhost:8025
  Pgsql:   localhost:5432 (sail / password from api/.env)

DONE
