#!/bin/bash
set -euo pipefail

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

# Load local environment overrides when present.
[ -f .env ] && source .env

# Defaults (kept in sync with docker-compose.yml defaults).
MYSQL_PORT=${MYSQL_PORT:-3306}
REDIS_PORT=${REDIS_PORT:-6379}
RABBITMQ_AMQP_PORT=${RABBITMQ_AMQP_PORT:-5672}
RABBITMQ_MGMT_PORT=${RABBITMQ_MGMT_PORT:-15672}
SEAWEEDFS_MASTER_PORT=${SEAWEEDFS_MASTER_PORT:-9333}
MCI_SERVER_PORT=${MCI_SERVER_PORT:-8080}
ADMIN_WEB_PORT=${ADMIN_WEB_PORT:-80}
CHANNEL_SERVICE_PORT=${CHANNEL_SERVICE_PORT:-8000}

# Docker Compose 内部连接必须使用容器名，覆盖 .env 中的 host 配置。
# 当用本脚本启动应用服务时，应用与基础设施在同一 Docker 网络。
dc() {
  MYSQL_HOST=mci-mysql \
  REDIS_HOST=mci-redis \
  RABBITMQ_HOST=mci-rabbitmq \
  SEAWEEDFS_HOST=mci-seaweedfs \
  MCI_SERVER_URL=http://mci-server:8080/msg-platform \
    docker compose "$@"
}

WITH_APPS=""
BUILD_FLAG=""
INIT_DATA=""
INIT_FULL_DATA=""
FORCE_INIT=""

usage() {
  cat <<EOF
Usage: $0 [OPTIONS]

Start local Docker infrastructure (and optionally application services).

Options:
  --with-apps        Also start mci-server, admin-web and channel-service
  --build            Force (re)build images before starting services
  --init-data        Import scripts/init-data.sql after MySQL is healthy
  --init-full-data   Import scripts/full-init-data.sql after MySQL is healthy
  --force-init       Skip empty check and import init SQL directly
  -h, --help         Show this help message and exit
EOF
}

while [ $# -gt 0 ]; do
  case "$1" in
    --with-apps) WITH_APPS=1 ;;
    --build) BUILD_FLAG="--build" ;;
    --init-data) INIT_DATA=1 ;;
    --init-full-data) INIT_FULL_DATA=1 ;;
    --force-init) FORCE_INIT=1 ;;
    -h|--help) usage; exit 0 ;;
    *) echo "Unknown option: $1" >&2; usage; exit 1 ;;
  esac
  shift
done

wait_for_healthy() {
  local service=$1
  local max_retries=${2:-60}
  local retry_count=0
  local container_name

  echo "Waiting for $service to become healthy..."
  while [ "$retry_count" -lt "$max_retries" ]; do
    container_name=$(dc -p sino-mci --profile infra --profile app ps -q "$service" 2>/dev/null | head -n1 || true)

    if [ -n "$container_name" ]; then
      local status
      status=$(docker inspect --format='{{.State.Health.Status}}' "$container_name" 2>/dev/null || true)
      if [ "$status" = "healthy" ]; then
        echo "$service is healthy."
        return 0
      fi
    fi

    retry_count=$((retry_count + 1))
    sleep 2
  done

  echo "$service did not become healthy within $((max_retries * 2)) seconds."
  dc -p sino-mci --profile infra --profile app logs --tail=50 "$service"
  return 1
}

init_database() {
  local sql_file=$1
  if [ ! -f "$sql_file" ]; then
    echo "Init SQL file not found: $sql_file" >&2
    return 1
  fi

  if [ -z "$FORCE_INIT" ]; then
    local tenant_count
    tenant_count=$(docker exec -i mci-mysql mysql -uroot -proot -N -s sino_mci -e "SELECT COUNT(*) FROM mci_tenant;" 2>/dev/null || echo "0")
    if [ "$tenant_count" -gt 0 ]; then
      echo "Database already contains $tenant_count tenant(s), skipping init. Use --force-init to override."
      return 0
    fi
  fi

  echo "Initializing database with $sql_file ..."
  docker exec -i mci-mysql mysql -uroot -proot sino_mci < "$sql_file"
  echo "Database initialized from $sql_file."
}

echo "Starting infrastructure services..."
dc -p sino-mci --profile infra up -d $BUILD_FLAG

wait_for_healthy mysql 60
wait_for_healthy redis 30
wait_for_healthy rabbitmq 60

if [ -n "$INIT_DATA" ]; then
  init_database "scripts/init-data.sql"
elif [ -n "$INIT_FULL_DATA" ]; then
  init_database "scripts/full-init-data.sql"
fi

echo "Infrastructure is ready."
echo "MySQL: jdbc:mysql://localhost:${MYSQL_PORT}/${MYSQL_DATABASE:-sino_mci}"
echo "Redis: localhost:${REDIS_PORT}"
echo "RabbitMQ: localhost:${RABBITMQ_AMQP_PORT} / http://localhost:${RABBITMQ_MGMT_PORT}"
echo "SeaweedFS: http://localhost:${SEAWEEDFS_MASTER_PORT}"

if [ -n "$WITH_APPS" ]; then
  echo "Starting application services..."
  # Include infra profile so that depends_on conditions can resolve.
  dc -p sino-mci --profile infra --profile app up -d $BUILD_FLAG

  wait_for_healthy mci-server 90
  wait_for_healthy channel-service 60

  echo "Application services are ready."
  echo "Admin Web: http://localhost:${ADMIN_WEB_PORT}"
  echo "Backend API: http://localhost:${MCI_SERVER_PORT}/msg-platform"
  echo "Channel Service: http://localhost:${CHANNEL_SERVICE_PORT}"
fi
