# Docker Compose Template for Local Development
#
# This file defines services for local development:
# - FastAPI application (with hot reload)
# - PostgreSQL database
# - Redis (cache and message broker)
# - Celery worker (background jobs)
#
# Usage:
#   Start:  docker-compose up -d
#   Stop:   docker-compose down
#   Logs:   docker-compose logs -f
#   Rebuild: docker-compose up -d --build

version: '3.8'

services:
  # ============================================================================
  # PostgreSQL Database
  # ============================================================================
  db:
    image: postgres:15-alpine
    container_name: yourapp_db
    restart: unless-stopped

    # Environment variables
    environment:
      POSTGRES_USER: ${DB_USER:-postgres}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
      POSTGRES_DB: ${DB_NAME:-yourapp_dev}
      # Performance tuning
      POSTGRES_MAX_CONNECTIONS: 100
      POSTGRES_SHARED_BUFFERS: 256MB

    # Port mapping (PostgreSQL default: 5432)
    ports:
      - "${DB_PORT:-5432}:5432"

    # Persist data
    volumes:
      - postgres_data:/var/lib/postgresql/data
      # Optional: Add custom PostgreSQL config
      # - ./docker/postgres/postgresql.conf:/etc/postgresql/postgresql.conf

    # Health check
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres}"]
      interval: 10s
      timeout: 5s
      retries: 5

    # Logging
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  # ============================================================================
  # Redis (Cache and Message Broker)
  # ============================================================================
  redis:
    image: redis:7-alpine
    container_name: yourapp_redis
    restart: unless-stopped

    # Command with persistence
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru

    # Port mapping (Redis default: 6379)
    ports:
      - "${REDIS_PORT:-6379}:6379"

    # Persist data
    volumes:
      - redis_data:/data

    # Health check
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

    # Logging
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  # ============================================================================
  # FastAPI Application (Development Mode)
  # ============================================================================
  app:
    # Build from local Dockerfile
    build:
      context: .
      dockerfile: Dockerfile
      target: development  # Use development stage if multi-stage build

    container_name: yourapp_api
    restart: unless-stopped

    # Command with hot reload
    command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

    # Port mapping
    ports:
      - "${APP_PORT:-8000}:8000"

    # Environment variables
    environment:
      # Application
      ENVIRONMENT: local
      DEBUG: "true"
      SECRET_KEY: ${SECRET_KEY:-dev-secret-key-change-in-production}

      # Database (use service name as host)
      DATABASE_URL: postgresql://${DB_USER:-postgres}:${DB_PASSWORD:-postgres}@db:5432/${DB_NAME:-yourapp_dev}
      DB_HOST: db
      DB_PORT: 5432
      DB_USER: ${DB_USER:-postgres}
      DB_PASSWORD: ${DB_PASSWORD:-postgres}
      DB_NAME: ${DB_NAME:-yourapp_dev}

      # Redis (use service name as host)
      REDIS_URL: redis://redis:6379/0

      # Celery
      CELERY_BROKER_URL: redis://redis:6379/0
      CELERY_RESULT_BACKEND: redis://redis:6379/1

      # API
      API_V1_PREFIX: /api/v1
      CORS_ORIGINS: '["http://localhost:3000","http://localhost:5173"]'

      # External APIs (set in .env file)
      SHOPIFY_API_KEY: ${SHOPIFY_API_KEY:-}
      SHOPIFY_API_SECRET: ${SHOPIFY_API_SECRET:-}

      # AWS (if needed)
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-}
      AWS_REGION: ${AWS_REGION:-eu-west-1}

    # Mount source code for hot reload
    volumes:
      - .:/app
      # Don't override these directories
      - /app/.venv
      - /app/__pycache__

    # Wait for database and redis
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy

    # Health check
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

    # Logging
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  # ============================================================================
  # Celery Worker (Background Jobs)
  # ============================================================================
  worker:
    # Use same image as app
    build:
      context: .
      dockerfile: Dockerfile
      target: development

    container_name: yourapp_worker
    restart: unless-stopped

    # Command to start Celery worker
    command: celery -A app.worker worker --loglevel=info --concurrency=2

    # Environment variables (same as app)
    environment:
      ENVIRONMENT: local
      DEBUG: "true"
      DATABASE_URL: postgresql://${DB_USER:-postgres}:${DB_PASSWORD:-postgres}@db:5432/${DB_NAME:-yourapp_dev}
      REDIS_URL: redis://redis:6379/0
      CELERY_BROKER_URL: redis://redis:6379/0
      CELERY_RESULT_BACKEND: redis://redis:6379/1
      SECRET_KEY: ${SECRET_KEY:-dev-secret-key-change-in-production}

      # External APIs
      SHOPIFY_API_KEY: ${SHOPIFY_API_KEY:-}
      SHOPIFY_API_SECRET: ${SHOPIFY_API_SECRET:-}
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-}

    # Mount source code for hot reload
    volumes:
      - .:/app
      - /app/.venv

    # Wait for database and redis
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy

    # Logging
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  # ============================================================================
  # Celery Beat (Scheduled Tasks) - Optional
  # ============================================================================
  # beat:
  #   build:
  #     context: .
  #     dockerfile: Dockerfile
  #     target: development
  #
  #   container_name: yourapp_beat
  #   restart: unless-stopped
  #
  #   command: celery -A app.worker beat --loglevel=info
  #
  #   environment:
  #     ENVIRONMENT: local
  #     CELERY_BROKER_URL: redis://redis:6379/0
  #     CELERY_RESULT_BACKEND: redis://redis:6379/1
  #
  #   volumes:
  #     - .:/app
  #
  #   depends_on:
  #     redis:
  #       condition: service_healthy

  # ============================================================================
  # Flower (Celery Monitoring) - Optional
  # ============================================================================
  # flower:
  #   build:
  #     context: .
  #     dockerfile: Dockerfile
  #     target: development
  #
  #   container_name: yourapp_flower
  #   restart: unless-stopped
  #
  #   command: celery -A app.worker flower --port=5555
  #
  #   ports:
  #     - "5555:5555"
  #
  #   environment:
  #     CELERY_BROKER_URL: redis://redis:6379/0
  #     CELERY_RESULT_BACKEND: redis://redis:6379/1
  #
  #   depends_on:
  #     redis:
  #       condition: service_healthy

  # ============================================================================
  # Frontend (React/Vite) - Optional
  # ============================================================================
  # frontend:
  #   build:
  #     context: ./frontend
  #     dockerfile: Dockerfile.dev
  #
  #   container_name: yourapp_frontend
  #   restart: unless-stopped
  #
  #   command: npm run dev -- --host 0.0.0.0
  #
  #   ports:
  #     - "5173:5173"
  #
  #   environment:
  #     VITE_API_BASE_URL: http://localhost:8000
  #
  #   volumes:
  #     - ./frontend:/app
  #     - /app/node_modules
  #
  #   depends_on:
  #     - app

  # ============================================================================
  # MailHog (Email Testing) - Optional
  # ============================================================================
  # mailhog:
  #   image: mailhog/mailhog:latest
  #   container_name: yourapp_mailhog
  #   restart: unless-stopped
  #
  #   ports:
  #     - "1025:1025"  # SMTP
  #     - "8025:8025"  # Web UI
  #
  #   logging:
  #     driver: "json-file"
  #     options:
  #       max-size: "10m"
  #       max-file: "3"

# ==============================================================================
# VOLUMES
# ==============================================================================
volumes:
  # PostgreSQL data
  postgres_data:
    driver: local

  # Redis data
  redis_data:
    driver: local

# ==============================================================================
# NETWORKS (optional)
# ==============================================================================
# networks:
#   default:
#     name: yourapp_network
#     driver: bridge

# ==============================================================================
# USAGE INSTRUCTIONS
# ==============================================================================
#
# 1. Copy this file to your project root as docker-compose.yml
#
# 2. Create .env file with your configuration:
#    DB_USER=postgres
#    DB_PASSWORD=postgres
#    DB_NAME=yourapp_dev
#    SECRET_KEY=your-secret-key
#    SHOPIFY_API_KEY=your-key
#    SHOPIFY_API_SECRET=your-secret
#
# 3. Start services:
#    docker-compose up -d
#
# 4. View logs:
#    docker-compose logs -f
#    docker-compose logs -f app     # Just app logs
#    docker-compose logs -f worker  # Just worker logs
#
# 5. Run migrations:
#    docker-compose exec app alembic upgrade head
#
# 6. Access services:
#    API:        http://localhost:8000
#    API Docs:   http://localhost:8000/docs
#    Database:   localhost:5432
#    Redis:      localhost:6379
#    Flower:     http://localhost:5555 (if enabled)
#    MailHog UI: http://localhost:8025 (if enabled)
#
# 7. Run commands in container:
#    docker-compose exec app python scripts/seed_data.py
#    docker-compose exec app pytest
#    docker-compose exec db psql -U postgres -d yourapp_dev
#
# 8. Stop services:
#    docker-compose down
#
# 9. Stop and remove volumes (WARNING: deletes data):
#    docker-compose down -v
#
# 10. Rebuild after Dockerfile changes:
#     docker-compose up -d --build
#
# ==============================================================================
# TROUBLESHOOTING
# ==============================================================================
#
# Port already in use:
#   - Change port in .env file or docker-compose.yml
#   - Or stop the conflicting service
#
# Container won't start:
#   - Check logs: docker-compose logs [service_name]
#   - Check health: docker-compose ps
#   - Remove and recreate: docker-compose down && docker-compose up -d
#
# Database connection fails:
#   - Ensure db service is healthy: docker-compose ps
#   - Check DATABASE_URL matches db service credentials
#   - Wait a few seconds for db to fully initialize
#
# Hot reload not working:
#   - Ensure volumes are mounted correctly
#   - Check file permissions
#   - Try rebuilding: docker-compose up -d --build
#
# Out of disk space:
#   - Clean up: docker system prune -a
#   - Remove old volumes: docker volume prune