# Root docker-compose.yml for TipSharks
# Orchestrates ALL three services and their infrastructure.
#
# Port map:
#   5432: tab-api-ingest PostgreSQL
#   5433: tipsharks-elo-api PostgreSQL
#   6379: Redis
#   27017: MongoDB
#   9090: tab-api-ingest API + metrics
#   8000: tipsharks-elo-api API + Web UI
#   8001: tipsharks-client backend API
#   8082: health-check (aggregator)
#   16686: Jaeger UI
#   9091: Prometheus
#   3000: Grafana

version: "3.8"

networks:
  tipsharks-network:
    driver: bridge

volumes:
  pg-ingest-data:
  pg-elo-data:
  redis-data:
  mongo-data:

services:
  # ==========================================================================
  # Databases
  # ==========================================================================

  postgres-ingest:
    image: postgres:16-alpine
    container_name: tipsharks-postgres-ingest
    restart: unless-stopped
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: racing_db
      POSTGRES_USER: racing
      POSTGRES_PASSWORD: racing123
    volumes:
      - pg-ingest-data:/var/lib/postgresql/data
    networks:
      - tipsharks-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U racing -d racing_db"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  postgres-elo:
    image: postgres:16-alpine
    container_name: tipsharks-postgres-elo
    restart: unless-stopped
    ports:
      - "5433:5432"
    environment:
      POSTGRES_DB: tipsharks
      POSTGRES_USER: tipsharks
      POSTGRES_PASSWORD: tipsharks
    volumes:
      - pg-elo-data:/var/lib/postgresql/data
    networks:
      - tipsharks-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U tipsharks -d tipsharks"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  redis:
    image: redis:7-alpine
    container_name: tipsharks-redis
    restart: unless-stopped
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    networks:
      - tipsharks-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s

  mongo:
    image: mongo:7
    container_name: tipsharks-mongo
    restart: unless-stopped
    ports:
      - "27017:27017"
    volumes:
      - mongo-data:/data/db
    networks:
      - tipsharks-network
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  # ==========================================================================
  # Observability
  # ==========================================================================

  jaeger:
    image: jaegertracing/all-in-one:latest
    container_name: tipsharks-jaeger
    restart: unless-stopped
    ports:
      - "16686:16686"
      - "4318:4318"
    networks:
      - tipsharks-network

  prometheus:
    image: prom/prometheus:latest
    container_name: tipsharks-prometheus
    restart: unless-stopped
    ports:
      - "9091:9090"
    volumes:
      - ./tab-api-ingest/prometheus.yml:/etc/prometheus/prometheus.yml
    networks:
      - tipsharks-network

  grafana:
    image: grafana/grafana:latest
    container_name: tipsharks-grafana
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD: admin
    networks:
      - tipsharks-network

  # ==========================================================================
  # Health check aggregator
  # ==========================================================================

  health-check:
    image: python:3.12-slim
    container_name: tipsharks-health-check
    restart: unless-stopped
    ports:
      - "8082:8082"
    volumes:
      - ./scripts/health-check-server.py:/app/health-check-server.py:ro
    command: python /app/health-check-server.py --port 8082
    networks:
      - tipsharks-network
    depends_on:
      - tab-api-ingest
      - tipsharks-elo-api
      - tipsharks-client-backend

  # ==========================================================================
  # Application services
  # ==========================================================================

  tab-api-ingest:
    build:
      context: ./tab-api-ingest/
      dockerfile: Dockerfile
    container_name: tipsharks-tab-api-ingest
    restart: unless-stopped
    ports:
      - "9090:9090"
    environment:
      DATABASE_URL: postgresql://racing:racing123@postgres-ingest:5432/racing_db
      REDIS_URL: redis://redis:6379
      NODE_ENV: development
      PORT: "9090"
    command: ["npm", "run", "dev"]
    depends_on:
      postgres-ingest:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - tipsharks-network

  tipsharks-elo-api:
    build:
      context: ./tipsharks-elo-api/
      dockerfile: ./infrastructure/docker/Dockerfile.api
    container_name: tipsharks-elo-api
    restart: unless-stopped
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgresql+psycopg://tipsharks:tipsharks@postgres-elo:5432/tipsharks
    command:
      [
        "uvicorn",
        "apps.backend.api.main:app",
        "--host",
        "0.0.0.0",
        "--port",
        "8000",
        "--reload",
      ]
    depends_on:
      postgres-elo:
        condition: service_healthy
    networks:
      - tipsharks-network

  tipsharks-client-backend:
    build:
      context: ./tipsharks-client/backend/
      dockerfile: Dockerfile
    container_name: tipsharks-client-backend
    restart: unless-stopped
    ports:
      - "8001:8001"
    environment:
      MONGO_URL: mongodb://mongo:27017
      DB_NAME: tipsharks_client
    command:
      [
        "uvicorn",
        "server:app",
        "--host",
        "0.0.0.0",
        "--port",
        "8001",
        "--reload",
      ]
    depends_on:
      mongo:
        condition: service_healthy
    networks:
      - tipsharks-network
