version: '3.9'

services:
  # SurrealDB - Multi-model database
  surrealdb:
    image: surrealdb/surrealdb:latest
    container_name: vapora-surrealdb
    command: start --bind 0.0.0.0:8000 file:///data/database.db
    ports:
      - "8000:8000"
    volumes:
      - surrealdb_data:/data
    environment:
      SURREAL_LOG: debug
      RUST_LOG: debug
    networks:
      - vapora
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  {% if nats.enabled %}
  # NATS JetStream - Message broker for agent coordination
  nats:
    image: nats:latest
    container_name: vapora-nats
    command: -js -m 8222 -D
    ports:
      - "4222:4222"
      - "8222:8222"
    volumes:
      - nats_data:/data
    networks:
      - vapora
    healthcheck:
      test: ["CMD", "nc", "-z", "localhost", "4222"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
  {% endif %}

  {% if llm_router.providers.ollama_enabled %}
  # Ollama - Local LLM provider
  ollama:
    image: ollama/ollama:latest
    container_name: vapora-ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    environment:
      OLLAMA_HOST: "0.0.0.0:11434"
    networks:
      - vapora
    profiles:
      - llm
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"]
      interval: 30s
      timeout: 10s
      retries: 3
    restart: unless-stopped
  {% endif %}

  # VAPORA Backend - REST API and orchestration
  backend:
    build:
      context: .
      dockerfile: crates/vapora-backend/Dockerfile
    container_name: vapora-backend
    ports:
      - "{{ backend.port }}:{{ backend.port }}"
    environment:
      DEPLOYMENT_MODE: "{{ deployment_mode }}"
      WORKSPACE_NAME: "{{ workspace_name }}"
      BACKEND_HOST: "{{ backend.host }}"
      BACKEND_PORT: "{{ backend.port }}"
      BACKEND_WORKERS: "{{ backend.workers }}"
      BACKEND_REQUEST_TIMEOUT: "{{ backend.request_timeout }}"
      DATABASE_URL: "{{ backend.database.url }}"
      DATABASE_USER: "{{ backend.database.username }}"
      DATABASE_PASSWORD: "{{ backend.database.password }}"
      DATABASE_POOL_SIZE: "{{ backend.database.pool_size }}"
      STORAGE_PATH: "{{ backend.storage.path }}"
      LOG_LEVEL: "{{ monitoring.log_level }}"
      JWT_SECRET: "{{ security.jwt_secret }}"
      PROMETHEUS_ENABLED: "{{ monitoring.prometheus_enabled|lower }}"
      {% if nats.enabled %}
      NATS_ENABLED: "true"
      NATS_URL: "{{ nats.url }}"
      {% else %}
      NATS_ENABLED: "false"
      {% endif %}
      CLAUDE_ENABLED: "{{ llm_router.providers.claude_enabled|lower }}"
      OPENAI_ENABLED: "{{ llm_router.providers.openai_enabled|lower }}"
      OLLAMA_ENABLED: "{{ llm_router.providers.ollama_enabled|lower }}"
      OLLAMA_URL: "{{ llm_router.providers.ollama_url }}"
    volumes:
      - vapora_storage:/var/lib/vapora/storage
      - ./vapora.toml:/etc/vapora/config/vapora.toml:ro
    networks:
      - vapora
    depends_on:
      surrealdb:
        condition: service_healthy
      {% if nats.enabled %}
      nats:
        condition: service_healthy
      {% endif %}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:{{ backend.port }}/health"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  # VAPORA Agents - Task orchestration and execution
  agents:
    build:
      context: .
      dockerfile: crates/vapora-agents/Dockerfile
    container_name: vapora-agents
    ports:
      - "{{ agents.port }}:{{ agents.port }}"
    environment:
      AGENTS_HOST: "{{ agents.host }}"
      AGENTS_PORT: "{{ agents.port }}"
      AGENTS_MAX_INSTANCES: "{{ agents.max_instances }}"
      AGENTS_HEARTBEAT_INTERVAL: "{{ agents.heartbeat_interval }}"
      LEARNING_ENABLED: "{{ agents.learning.enabled|lower }}"
      RECENCY_WINDOW_DAYS: "{{ agents.learning.recency_window_days }}"
      KNOWLEDGE_GRAPH_ENABLED: "{{ agents.knowledge_graph.enabled|lower }}"
      KNOWLEDGE_GRAPH_RETENTION_DAYS: "{{ agents.knowledge_graph.retention_days }}"
      {% if agents.nats.enabled %}
      NATS_ENABLED: "true"
      NATS_URL: "nats://nats:4222"
      {% else %}
      NATS_ENABLED: "false"
      {% endif %}
      LOG_LEVEL: "{{ monitoring.log_level }}"
    networks:
      - vapora
    depends_on:
      backend:
        condition: service_healthy
      {% if agents.nats.enabled %}
      nats:
        condition: service_healthy
      {% endif %}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:{{ agents.port }}/health"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  # VAPORA LLM Router - Multi-provider LLM orchestration
  llm-router:
    build:
      context: .
      dockerfile: crates/vapora-llm-router/Dockerfile
    container_name: vapora-llm-router
    ports:
      - "{{ llm_router.port }}:{{ llm_router.port }}"
    environment:
      LLM_ROUTER_HOST: "{{ llm_router.host }}"
      LLM_ROUTER_PORT: "{{ llm_router.port }}"
      COST_TRACKING_ENABLED: "{{ llm_router.cost_tracking.enabled|lower }}"
      BUDGET_ENFORCEMENT_ENABLED: "{{ llm_router.budget_enforcement.enabled|lower }}"
      BUDGET_WINDOW: "{{ llm_router.budget_enforcement.window }}"
      CLAUDE_ENABLED: "{{ llm_router.providers.claude_enabled|lower }}"
      OPENAI_ENABLED: "{{ llm_router.providers.openai_enabled|lower }}"
      GEMINI_ENABLED: "{{ llm_router.providers.gemini_enabled|lower }}"
      OLLAMA_ENABLED: "{{ llm_router.providers.ollama_enabled|lower }}"
      OLLAMA_URL: "{{ llm_router.providers.ollama_url }}"
      ROUTING_STRATEGY: "{{ llm_router.routing.strategy }}"
      LOG_LEVEL: "{{ monitoring.log_level }}"
    networks:
      - vapora
    depends_on:
      backend:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:{{ llm_router.port }}/health"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  # VAPORA Frontend - React/WASM UI
  frontend:
    build:
      context: .
      dockerfile: crates/vapora-frontend/Dockerfile
    container_name: vapora-frontend
    ports:
      - "{{ frontend.port }}:{{ frontend.port }}"
    environment:
      FRONTEND_HOST: "{{ frontend.host }}"
      FRONTEND_PORT: "{{ frontend.port }}"
      API_URL: "http://backend:{{ backend.port }}"
      ENABLE_WASM: "{{ frontend.enable_wasm|lower }}"
    networks:
      - vapora
    depends_on:
      backend:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:{{ frontend.port }}/"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  {% if monitoring.prometheus_enabled %}
  # Prometheus - Metrics collection and alerting
  prometheus:
    image: prom/prometheus:latest
    container_name: vapora-prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=30d'
    networks:
      - vapora
    restart: unless-stopped

  # Grafana - Metrics visualization
  grafana:
    image: grafana/grafana:latest
    container_name: vapora-grafana
    ports:
      - "3001:3000"
    environment:
      GF_SECURITY_ADMIN_PASSWORD: "admin"
      GF_SECURITY_ADMIN_USER: "admin"
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/dashboards:/etc/grafana/provisioning/dashboards:ro
    networks:
      - vapora
    depends_on:
      - prometheus
    restart: unless-stopped
  {% endif %}

volumes:
  surrealdb_data:
    driver: local
  vapora_storage:
    driver: local
  {% if nats.enabled %}
  nats_data:
    driver: local
  {% endif %}
  {% if llm_router.providers.ollama_enabled %}
  ollama_data:
    driver: local
  {% endif %}
  {% if monitoring.prometheus_enabled %}
  prometheus_data:
    driver: local
  grafana_data:
    driver: local
  {% endif %}

networks:
  vapora:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16
