#!/usr/bin/env bash

set -euo pipefail

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

compose() {
  if docker compose version >/dev/null 2>&1; then
    docker compose "$@"
  elif command -v docker-compose >/dev/null 2>&1; then
    docker-compose "$@"
  else
    echo "docker compose or docker-compose is required." >&2
    exit 1
  fi
}

ensure_env_file() {
  if [[ ! -f "$bundle_dir/.env" && -f "$bundle_dir/.env.example" ]]; then
    cp "$bundle_dir/.env.example" "$bundle_dir/.env"
    echo "Created .env from .env.example"
  fi
}

load_env() {
  set -a
  # shellcheck disable=SC1091
  source "$bundle_dir/.env"
  set +a
}

http_get() {
  local url="$1"
  if command -v curl >/dev/null 2>&1; then
    curl -fsS "$url" >/dev/null
  elif command -v wget >/dev/null 2>&1; then
    wget -q -O /dev/null "$url"
  else
    return 2
  fi
}

wait_for_http() {
  local name="$1"
  local url="$2"
  local attempt

  for attempt in {1..90}; do
    if http_get "$url"; then
      echo "$name is ready: $url"
      return 0
    fi
    sleep 2
  done

  echo "$name is not ready after 180 seconds: $url" >&2
  exit 1
}

wait_for_kafka() {
  local attempt
  for attempt in {1..60}; do
    if compose exec -T kafka kafka-topics.sh --bootstrap-server kafka:9092 --list >/dev/null 2>&1; then
      echo "Kafka is ready."
      return 0
    fi
    sleep 2
  done

  echo "Kafka is not ready after 120 seconds." >&2
  exit 1
}

wait_for_external_kafka() {
  local container_name="${EXTERNAL_KAFKA_CONTAINER:-}"
  local attempt

  if [[ -z "$container_name" ]]; then
    echo "External Kafka container is not configured; skipping Kafka readiness check."
    return 0
  fi

  for attempt in {1..60}; do
    if docker exec "$container_name" kafka-topics --bootstrap-server "${PCP_KAFKA_HOST:-kafka}:${PCP_KAFKA_PORT:-9092}" --list >/dev/null 2>&1 ||
      docker exec "$container_name" kafka-topics.sh --bootstrap-server "${PCP_KAFKA_HOST:-kafka}:${PCP_KAFKA_PORT:-9092}" --list >/dev/null 2>&1; then
      echo "External Kafka is ready in container $container_name."
      return 0
    fi
    sleep 2
  done

  echo "External Kafka is not ready after 120 seconds: $container_name" >&2
  exit 1
}

app_services=(
  pcp-srpring-boot-admin-server
  pcp-satellite-catalog-service
  pcp-ballistics-service
  pcp-request-service
  pcp-route-processing-service
  slots-service
  pcp-complex-mission-service
  pcp-mission-planing-service
  pcp-coverage-scheme-service
  pcp-dynamic-plan-service
  pcp-stations-service
  pcp-ui-service
  pcp-tgu-service
)

ensure_env_file
load_env

cd "$bundle_dir"

if [[ "${USE_EXTERNAL_INFRA:-false}" == "true" ]]; then
  echo "Using external infrastructure. Skipping local postgres/kafka startup."
  echo "Postgres endpoint for services: ${PCP_POSTGRES_HOST:-postgres}:${PCP_POSTGRES_PORT:-5432}"
  echo "Kafka endpoint for services: ${PCP_KAFKA_HOST:-kafka}:${PCP_KAFKA_PORT:-9092}"
  wait_for_external_kafka
else
  echo "Starting infrastructure..."
  compose up -d postgres kafka
  wait_for_kafka
fi

if [[ "${SKIP_DB_INIT:-false}" != "true" ]]; then
  "$script_dir/init-db.sh"
fi

echo "Starting spring-cloud-config-server..."
compose up -d spring-cloud-config-server
wait_for_http "spring-cloud-config-server" "http://localhost:${CONFIG_SERVER_PORT:-38888}/actuator/health"

echo "Starting application services..."
for service_name in "${app_services[@]}"; do
  echo "Starting $service_name..."
  compose up -d "$service_name"
done

echo "Application startup requested."
compose ps
