#!/usr/bin/env bash
# Build (if needed) and start the whole stack.
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
require_docker; ensure_env; check_layout
preflight_ports
bash "$(dirname "${BASH_SOURCE[0]}")/sync-mobile-port.sh" quiet
bash "$(dirname "${BASH_SOURCE[0]}")/gen-packages.sh"
bash "$(dirname "${BASH_SOURCE[0]}")/gen-apps.sh"
bash "$(dirname "${BASH_SOURCE[0]}")/gen-resources.sh"

usage() {
  cat <<EOF
Usage: ${RUN_CMD:-run-stack} up [--build] [--essential] [service...]

Build if needed and start the stack (or the named services).

  --build       Rebuild images before starting
  --essential   Only the services listed under "essential" in run.config.json
  -h, --help    Show this help
EOF
}

# Only on a full up: with an explicit service list, every other service is
# legitimately absent from the request rather than switched off.
# RUN_UP_BUILD=0 skips --build (used by restart without --build).
UP_ARGS=(-d)
if [ "${RUN_UP_BUILD:-1}" = 1 ]; then
  UP_ARGS+=(--build)
fi

essential=false
services=()
for arg in "$@"; do
  case "${arg}" in
    --build) ;; # already handled via RUN_UP_BUILD / default
    --essential) essential=true ;;
    -h|--help)
      usage
      exit 0
      ;;
    -*)
      echo "error: unknown option: ${arg}" >&2
      usage >&2
      exit 1
      ;;
    *) services+=("${arg}") ;;
  esac
done

if [ "${essential}" = true ]; then
  if [ "${#services[@]}" -gt 0 ]; then
    echo "error: pass service names or --essential, not both" >&2
    exit 1
  fi
  ensure_essential_config
  while IFS= read -r name; do
    [ -n "${name}" ] || continue
    services+=("${name}")
  done < <(essential_service_names)
  if [ "${#services[@]}" -eq 0 ]; then
    echo "error: no essential services configured — add them under \"essential\" in ${WORKSPACE_CONFIG}" >&2
    exit 1
  fi
fi

if [ "${#services[@]}" -eq 0 ]; then
  UP_ARGS+=(--remove-orphans)
  prune_disabled
  if ! mobile_enabled; then
    UP_ARGS+=(--scale mobile-client=0 --scale mobile-packages=0 --scale mobile-deps=0)
  fi
fi

if ! dc up "${UP_ARGS[@]}" "${services[@]}"; then
  status=$?
  report_failures || true
  exit "${status}"
fi
start_host_open

# Remember this project's services for autocomplete (Kiro / zsh / bash).
remember_and_list_services >/dev/null || true

# A service can also fail after compose returns, so check either way.
report_failures || exit 1

echo
echo "${PROJECT_LABEL:-${PROJECT_NAME}} is starting. First run installs composer + pnpm deps and may take a few minutes."
print_ports_recap
if desktop_enabled; then
  echo "  Desktop shell ${RUN_CMD:-run-stack} desktop   (${DESKTOP_STACK:-none} runs on the host)"
fi
if mobile_enabled; then
  echo "  Open iOS      ${RUN_CMD:-run-stack} ios   (or the iOS button on the dashboard)"
  echo "  Open Android  ${RUN_CMD:-run-stack} android"
fi
echo
echo "Follow startup with: ${RUN_CMD:-run-stack} logs"
echo "Re-print ports:      ${RUN_CMD:-run-stack} ports --show"
