# All app services load `.env` (secrets, email, Django, DB_* credentials).
# `environment:` entries below override host-oriented values from `.env` so containers
# talk to the `postgres` and `redis` service names on the compose network.

services:
  node:
    image: node:20-alpine
    working_dir: /app
    volumes:
      - .:/app
    entrypoint: ["/bin/sh", "-c"]
    command: "sleep infinity"

  tailwind:
    image: node:20-alpine
    working_dir: /app
    volumes:
      - .:/app
    command: sh -c "npm install && npm run watch:css"

  web:
    build:
      context: .
      dockerfile: docker/Dockerfile
      args:
        REQUIREMENTS_FILE: development.txt
    command: sh -c "python manage.py migrate --noinput && python manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/app
    ports:
      - "${WEB_HOST_PORT:-8000}:8000"
    env_file:
      - .env
    environment:
      DB_HOST: postgres
      DB_PORT: "5432"
      REDIS_URL: redis://redis:6379/0
      CELERY_BROKER_URL: redis://redis:6379/1
      # Celery reads CELERY_* from the OS env and overrides Django settings; keep django-db in containers.
      CELERY_RESULT_BACKEND: django-db
      # Route outbound mail to the mailhog container in dev (overrides .env so localhost-style
      # values don't escape the compose network).
      EMAIL_BACKEND: django.core.mail.backends.console.EmailBackend
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
      mailhog:
        condition: service_started
    # Reach Moodle at its wwwroot host (moodle.local:8081) via the host's
    # published port — Moodle 303-redirects any request whose host != wwwroot,
    # so server-to-server calls must use the same hostname the browser uses.
    extra_hosts:
      - "moodle.local:host-gateway"
      - "iilmp.local:host-gateway"

  celery_worker:
    build:
      context: .
      dockerfile: docker/Dockerfile.celery
    command: celery -A config worker -l info
    volumes:
      - .:/app
    env_file:
      - .env
    environment:
      # Celery image has base.txt only; avoid dev-only INSTALLED_APPS (e.g. django_browser_reload).
      DJANGO_SETTINGS_MODULE: config.settings.base
      DB_HOST: postgres
      DB_PORT: "5432"
      REDIS_URL: redis://redis:6379/0
      CELERY_BROKER_URL: redis://redis:6379/1
      CELERY_RESULT_BACKEND: django-db
      EMAIL_BACKEND: django.core.mail.backends.console.EmailBackend
    # Confirms the worker is up and has registered our tasks. (The REP video
    # transcode task + its ffmpeg/ffprobe checks were removed with the REP LMS.)
    healthcheck:
      test:
        - CMD-SHELL
        - >-
          celery -A config inspect ping -t 5 2>/dev/null | grep -q pong &&
          celery -A config inspect registered -t 5 2>/dev/null | grep -q apps.mel.tracking.scan_delayed_activities
      interval: 30s
      timeout: 15s
      retries: 5
      start_period: 60s
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    extra_hosts:
      - "moodle.local:host-gateway"
      - "iilmp.local:host-gateway"

  celery_beat:
    build:
      context: .
      dockerfile: docker/Dockerfile.celery
    command: celery -A config beat -l info
    volumes:
      - .:/app
    env_file:
      - .env
    environment:
      DJANGO_SETTINGS_MODULE: config.settings.base
      DB_HOST: postgres
      DB_PORT: "5432"
      REDIS_URL: redis://redis:6379/0
      CELERY_BROKER_URL: redis://redis:6379/1
      CELERY_RESULT_BACKEND: django-db
      EMAIL_BACKEND: django.core.mail.backends.console.EmailBackend
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    extra_hosts:
      - "moodle.local:host-gateway"
      - "iilmp.local:host-gateway"

  flower:
    build:
      context: .
      dockerfile: docker/Dockerfile.celery
    command: celery -A config flower --port=5555
    volumes:
      - .:/app
    env_file:
      - .env
    environment:
      DJANGO_SETTINGS_MODULE: config.settings.base
      DB_HOST: postgres
      DB_PORT: "5432"
      REDIS_URL: redis://redis:6379/0
      CELERY_BROKER_URL: redis://redis:6379/1
      CELERY_RESULT_BACKEND: django-db
    ports:
      - "${FLOWER_HOST_PORT:-5555}:5555"
    depends_on:
      redis:
        condition: service_healthy

  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 5s
      retries: 10

  # Dev-only SMTP sink. App containers send mail to `mailhog:1025`; open the web UI
  # on the host at http://127.0.0.1:${MAILHOG_UI_PORT:-8025} to inspect captured
  # messages. Not for production — wire a real SMTP provider via EMAIL_* in prod.
  mailhog:
    image: mailhog/mailhog:v1.0.1
    ports:
      - "${MAILHOG_SMTP_PORT:-1025}:1025"
      - "${MAILHOG_UI_PORT:-8025}:8025"

  postgres:
    image: pgvector/pgvector:pg16
    ports:
      - "${POSTGRES_HOST_PORT:-5432}:5432"
    environment:
      POSTGRES_DB: ${DB_NAME:-iilmp}
      POSTGRES_USER: ${DB_USER:-iilmp}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-iilmp}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""]
      interval: 5s
      timeout: 5s
      retries: 10

  # ── Moodle LMS ────────────────────────────────────────────────────────────
  # Real Moodle running alongside the Django app (the home-grown REP LMS was
  # retired). Moodle needs its OWN MariaDB — it cannot use the pgvector Postgres.
  # Reachable from `web`/`celery` at http://moodle:8080 over the compose network;
  # Moodle reaches IILMP at http://web:8000. Browser-facing URLs use the host
  # port below (http://localhost:${MOODLE_HOST_PORT:-8081}).
  moodle-mariadb:
    image: bitnamilegacy/mariadb:11.8.3
    environment:
      MARIADB_ROOT_PASSWORD: ${MOODLE_DB_ROOT_PASSWORD:-moodleroot}
      MARIADB_DATABASE: ${MOODLE_DB_NAME:-bitnami_moodle}
      MARIADB_USER: ${MOODLE_DB_USER:-bn_moodle}
      MARIADB_PASSWORD: ${MOODLE_DB_PASSWORD:-moodle}
      MARIADB_CHARACTER_SET: utf8mb4
      MARIADB_COLLATE: utf8mb4_unicode_ci
    volumes:
      - moodle_mariadb_data:/bitnami/mariadb
    healthcheck:
      test: ["CMD", "/opt/bitnami/scripts/mariadb/healthcheck.sh"]
      interval: 15s
      timeout: 10s
      retries: 10

  moodle:
    image: bitnamilegacy/moodle:5.0.2
    environment:
      MOODLE_DATABASE_HOST: moodle-mariadb
      MOODLE_DATABASE_PORT_NUMBER: "3306"
      MOODLE_DATABASE_NAME: ${MOODLE_DB_NAME:-bitnami_moodle}
      MOODLE_DATABASE_USER: ${MOODLE_DB_USER:-bn_moodle}
      MOODLE_DATABASE_PASSWORD: ${MOODLE_DB_PASSWORD:-moodle}
      MOODLE_USERNAME: ${MOODLE_ADMIN_USER:-admin}
      MOODLE_PASSWORD: ${MOODLE_ADMIN_PASSWORD:-Admin#12345}
      MOODLE_EMAIL: ${MOODLE_ADMIN_EMAIL:-admin@example.com}
      MOODLE_SITE_NAME: "RUFORUM IILMP Learning"
      # Moodle's wwwroot host. Server-to-server callers (the MEL pull, and SSO
      # token/userinfo) must use this same host or Moodle 303-redirects them, so
      # in dev it's a shared name resolvable from both browser and containers
      # (moodle.local via /etc/hosts + extra_hosts). Point at your public host in prod.
      MOODLE_HOST: ${MOODLE_HOST:-localhost:8081}
    ports:
      # Host 8081 → container 8080. Avoids web:8000, flower:5555, mailhog:8025.
      - "${MOODLE_HOST_PORT:-8081}:8080"
    volumes:
      - moodle_data:/bitnami/moodle
      - moodle_moodledata:/bitnami/moodledata
      # IILMP-branded Boost child theme, bind-mounted so edits are live during dev.
      # Overlays a subdir of the moodle_data volume; survives restarts.
      - ./moodle/theme/iilmp:/bitnami/moodle/theme/iilmp
    depends_on:
      moodle-mariadb:
        condition: service_healthy
    healthcheck:
      # The bitnamilegacy Moodle image ships no curl/wget binary — only php — so
      # probe the login page via php's curl extension (required by Moodle, always
      # present). $$ escapes compose's var-substitution; CMD (exec) form avoids a
      # shell so the php $vars survive.
      test: ["CMD", "php", "-r", "$$c=curl_init('http://localhost:8080/login/index.php');curl_setopt($$c,CURLOPT_NOBODY,true);curl_setopt($$c,CURLOPT_TIMEOUT,8);curl_exec($$c);$$h=curl_getinfo($$c,CURLINFO_HTTP_CODE);exit(($$h>=200&&$$h<400)?0:1);"]
      interval: 30s
      timeout: 10s
      retries: 10
      # Moodle's first-boot install is slow; don't flag unhealthy too early.
      start_period: 180s
    # Reach the IILMP Django app at its ALLOWED_HOSTS name (iilmp.local:8000) via
    # the host's published port — for the SSO token/userinfo exchange (Moodle → IILMP).
    extra_hosts:
      - "iilmp.local:host-gateway"

  # Dev-only TLS terminator so Moodle (which requires HTTPS OAuth2 endpoints) can
  # use IILMP as an OIDC provider. Serves https://iilmp.local via Caddy's internal
  # CA and proxies to web:8000. Not used in prod.
  caddy:
    image: caddy:2-alpine
    ports:
      - "${IILMP_HTTPS_PORT:-443}:443"
    volumes:
      - ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    depends_on:
      web:
        condition: service_started

volumes:
  caddy_data:
  caddy_config:
  postgres_data:
  moodle_mariadb_data:
  moodle_data:
  moodle_moodledata:
