#!/bin/sh
# Unattended cast cluster population — dev lab and staging template.
# Usage:
#   sudo sh populate_lab_setup.sh              # full setup on this node
#   sudo sh populate_lab_setup.sh --coordinator # from jump host: all nodes in order
#   sudo sh populate_lab_setup.sh --phase baseline|db|app|all
set -eu

ROOT="$(cd "$(dirname "$0")" && pwd)"
export CAST_CLUSTER_ROOT="$ROOT"
# shellcheck source=/dev/null
. "$ROOT/scripts/lib/common.sh"
export JOURNAL_ACTOR=populate

PHASE=all
COORDINATOR=0

while [ $# -gt 0 ]; do
  case "$1" in
    --coordinator) COORDINATOR=1; shift ;;
    --phase) PHASE="${2:-all}"; shift 2 ;;
    --help|-h)
      echo "Usage: sudo sh populate_lab_setup.sh [--coordinator] [--phase baseline|db|app|all]"
      exit 0
      ;;
    *) die "unknown arg: $1" ;;
  esac
done

run_phase_baseline() {
  JOURNAL_PHASE=baseline
  journal_start phase_baseline "$(host_short)"
  log "phase baseline on $(host_short)"
  journal_start apk_upgrade
  apk update
  apk upgrade -U -a || apk upgrade -U || true
  journal_ok apk_upgrade
  run_script "$ROOT/scripts/baseline.sh"
  journal_ok phase_baseline
}

run_phase_db() {
  JOURNAL_PHASE=db
  journal_start phase_db "$(host_short)"
  if is_primary_node; then
    log "phase db primary on $(host_short)"
    run_script "$ROOT/scripts/mariadb-primary.sh"
    run_script "$ROOT/scripts/load-schemas.sh"
    journal_ok phase_db "primary"
    return
  fi
  if is_replica_node; then
    log "phase db replica on $(host_short) — waiting for primary"
    wait_for_primary_db
    wait_for_tcp "$PRIMARY_DB_HOST" "$PRIMARY_DB_PORT" 300
    run_script "$ROOT/scripts/mariadb-replica.sh"
    journal_ok phase_db "replica"
    return
  fi
  journal_nok phase_db "unknown host"
  die "unknown host for db phase: $(host_short)"
}

run_phase_app() {
  JOURNAL_PHASE=app
  journal_start phase_app "$(host_short)"
  log "phase app on $(host_short)"
  if is_replica_node; then
    wait_for_primary_db
  fi
  run_script "$ROOT/scripts/deploy-app.sh"
  run_script "$ROOT/scripts/configure-nginx.sh"
  rc-service php-fpm83 restart 2>/dev/null || true
  rc-service nginx reload 2>/dev/null || rc-service nginx restart 2>/dev/null || true
  if is_primary_node; then
    rc-service mariadb restart 2>/dev/null || true
  elif is_replica_node; then
    rc-service mariadb restart 2>/dev/null || true
  fi
  journal_ok phase_app
}

run_local() {
  ensure_shared_mounted
  journal_start populate_local "phase=${PHASE}"
  case "$PHASE" in
    baseline) run_phase_baseline ;;
    db) run_phase_baseline; run_phase_db ;;
    app) run_phase_app ;;
    all)
      run_phase_baseline || exit 1
      run_phase_db || exit 1
      run_phase_app || exit 1
      run_script "$ROOT/verify_lab_setup.sh" --local || exit 1
      ;;
    *) journal_nok populate_local "unknown phase"; die "unknown phase: $PHASE" ;;
  esac
  journal_ok populate_local "phase=${PHASE}"
}

run_coordinator() {
  ensure_shared_mounted
  journal_start populate_coordinator "nodes=${ALL_CAST_HOSTS}"
  log "coordinator: ${CLUSTER_NAME} nodes=${ALL_CAST_HOSTS}"

  for H in $CAST01_HOST $CAST02_HOST $CAST03_HOST; do
    ssh_node "$H" "sudo sh ${SHARED_MOUNT}/cluster/populate_lab_setup.sh --phase baseline" &
  done
  wait || die "baseline failed on one or more nodes"

  ssh_node "$CAST01_HOST" "sudo sh ${SHARED_MOUNT}/cluster/populate_lab_setup.sh --phase db"

  for H in $CAST02_HOST $CAST03_HOST; do
    ssh_node "$H" "sudo sh ${SHARED_MOUNT}/cluster/populate_lab_setup.sh --phase db" &
  done
  wait

  for H in $CAST01_HOST $CAST02_HOST $CAST03_HOST; do
    ssh_node "$H" "sudo sh ${SHARED_MOUNT}/cluster/populate_lab_setup.sh --phase app" &
  done
  wait

  sh "$ROOT/verify_lab_setup.sh" --cluster
  journal_ok populate_coordinator
  log "populate_coordinator_ok ${CLUSTER_NAME}"
}

if [ "$(id -u)" -ne 0 ]; then
  die "run as root (sudo sh populate_lab_setup.sh)"
fi

if [ "$COORDINATOR" -eq 1 ]; then
  run_coordinator
else
  run_local
fi
