version: '3.8'

services:
  # ============================================================================
  # API Gateway - Entry point for all client requests
  # ============================================================================
  api-gateway:
    build: ../templates/api-gateway
    container_name: api-gateway
    ports:
      - "8000:8000"
    environment:
      - USER_SERVICE_URL=http://user-service:8001
      - PRODUCT_SERVICE_URL=http://product-service:8002
      - ORDER_SERVICE_URL=http://order-service:8003
      - JAEGER_AGENT_HOST=jaeger
      - JAEGER_AGENT_PORT=6831
      - RUST_LOG=info
    depends_on:
      - user-service
      - product-service
      - order-service
      - jaeger
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health/live"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s
    restart: always
    networks:
      - microservices

  # ============================================================================
  # User Service - User management and authentication
  # ============================================================================
  user-service:
    build: ../templates/user-service
    container_name: user-service
    ports:
      - "8001:8001"
    environment:
      - DATABASE_URL=postgresql://postgres:postgres@postgres:5432/users
      - JAEGER_AGENT_HOST=jaeger
      - JAEGER_AGENT_PORT=6831
      - NODE_ENV=production
      - PORT=8001
    depends_on:
      postgres:
        condition: service_healthy
      jaeger:
        condition: service_started
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8001/health/live"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s
    restart: always
    networks:
      - microservices

  # ============================================================================
  # Product Service - Product catalog and inventory
  # ============================================================================
  product-service:
    build: ../templates/product-service
    container_name: product-service
    ports:
      - "8002:8002"
    environment:
      - MONGO_URL=mongodb://mongodb:27017/products
      - JAEGER_AGENT_HOST=jaeger
      - JAEGER_AGENT_PORT=6831
      - PYTHON_ENV=production
      - PORT=8002
    depends_on:
      mongodb:
        condition: service_healthy
      jaeger:
        condition: service_started
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8002/health/live"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s
    restart: always
    networks:
      - microservices

  # ============================================================================
  # Order Service - Order processing and payment coordination
  # ============================================================================
  order-service:
    build: ../templates/order-service
    container_name: order-service
    ports:
      - "8003:8003"
    environment:
      - DATABASE_URL=postgresql://postgres:postgres@postgres:5432/orders
      - RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672
      - USER_SERVICE_URL=http://user-service:8001
      - PRODUCT_SERVICE_URL=http://product-service:8002
      - JAEGER_AGENT_HOST=jaeger
      - JAEGER_AGENT_PORT=6831
      - RUST_LOG=info
    depends_on:
      postgres:
        condition: service_healthy
      rabbitmq:
        condition: service_healthy
      jaeger:
        condition: service_started
      user-service:
        condition: service_healthy
      product-service:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8003/health/live"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 20s
    restart: always
    networks:
      - microservices

  # ============================================================================
  # Infrastructure Services
  # ============================================================================

  # PostgreSQL - Primary database for User and Order services
  postgres:
    image: postgres:15-alpine
    container_name: postgres
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_MULTIPLE_DATABASES=users,orders
    volumes:
      - postgres-data:/var/lib/postgresql/data
      - ./init-postgres.sh:/docker-entrypoint-initdb.d/init-postgres.sh
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: always
    networks:
      - microservices

  # MongoDB - Document store for Product service
  mongodb:
    image: mongo:7-alpine
    container_name: mongodb
    ports:
      - "27017:27017"
    environment:
      - MONGO_INITDB_DATABASE=products
    volumes:
      - mongo-data:/data/db
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: always
    networks:
      - microservices

  # RabbitMQ - Message broker for asynchronous communication
  rabbitmq:
    image: rabbitmq:3.12-management-alpine
    container_name: rabbitmq
    ports:
      - "5672:5672"   # AMQP port
      - "15672:15672" # Management UI
    environment:
      - RABBITMQ_DEFAULT_USER=guest
      - RABBITMQ_DEFAULT_PASS=guest
    volumes:
      - rabbitmq-data:/var/lib/rabbitmq
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: always
    networks:
      - microservices

  # Jaeger - Distributed tracing
  jaeger:
    image: jaegertracing/all-in-one:1.52
    container_name: jaeger
    ports:
      - "5775:5775/udp"   # Zipkin compact thrift
      - "6831:6831/udp"   # Jaeger compact thrift
      - "6832:6832/udp"   # Jaeger binary thrift
      - "5778:5778"       # Serve configs
      - "16686:16686"     # Jaeger UI
      - "14250:14250"     # gRPC
      - "14268:14268"     # HTTP collector
      - "14269:14269"     # Admin port
      - "4317:4317"       # OTLP gRPC
      - "4318:4318"       # OTLP HTTP
    environment:
      - COLLECTOR_OTLP_ENABLED=true
      - LOG_LEVEL=info
    restart: always
    networks:
      - microservices

# ============================================================================
# Volumes for persistent data
# ============================================================================
volumes:
  postgres-data:
    driver: local
  mongo-data:
    driver: local
  rabbitmq-data:
    driver: local

# ============================================================================
# Network configuration
# ============================================================================
networks:
  microservices:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
