# Self-contained local development stack — Postgres + API + scheduler, all on this machine.
#
# Fully decoupled: its own local database (a Docker volume) and its own scheduler, so there
# is no shared DB and no migration coupling with any other instance. Edit code, rebuild, and
# everything (including the background sync) runs right here.
#
#   docker compose -f docker-compose.localdev.yml up -d --build
#
# Browse at http://localhost:8080 — Google login works because the OAuth redirect is
# http://localhost:8080/auth/callback. The API runs `alembic upgrade head` on startup, so it
# applies local migrations to THIS local DB only. Seed the catalog once with a pg_dump from
# another instance if you want real data (see RUNBOOK).

services:
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-siftlode}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-siftlode}
      POSTGRES_DB: ${POSTGRES_DB:-siftlode}
    volumes:
      - pgdata:/var/lib/postgresql/data
    security_opt:
      - apparmor:unconfined
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-siftlode} -d ${POSTGRES_DB:-siftlode}"]
      interval: 5s
      timeout: 5s
      retries: 12
    restart: unless-stopped

  api:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        APP_VERSION: ${APP_VERSION:-dev}
        GIT_SHA: ${GIT_SHA:-unknown}
        BUILD_DATE: ${BUILD_DATE:-}
    env_file: .env
    environment:
      # Own local database (overrides whatever DATABASE_URL is in .env).
      DATABASE_URL: postgresql+psycopg://${POSTGRES_USER:-siftlode}:${POSTGRES_PASSWORD:-siftlode}@db:5432/${POSTGRES_DB:-siftlode}
      # This instance owns its scheduler now (its own DB, so no double-write concern).
      SCHEDULER_ENABLED: "true"
      # Download center: the API serves finished files (it does NOT run the worker loop).
      DOWNLOAD_ROOT: /downloads
      WORKER_ENABLED: "false"
      # Plex HLS remux scratch on fast container-local storage (the /downloads bind-mount is a slow
      # Windows Docker Desktop mount in dev; prod uses fast local disk so it keeps the default).
      PLEX_HLS_DIR: /var/tmp/plex-hls
    depends_on:
      db:
        condition: service_healthy
    # Harmless on Docker Desktop; needed on some nested/hardened Docker hosts.
    security_opt:
      - apparmor:unconfined
    ports:
      - "${APP_PORT:-8080}:8000"
    volumes:
      # Downloaded media lives on the host so you can inspect the generated Plex tree.
      # Gitignored. The worker writes here; the API reads it to serve local downloads.
      - ./downloads:/downloads
      # Plex media, read-only (see the plex_media volume note below). Maps to plex_path_map.
      - plex_media:/plex-media:ro
    restart: unless-stopped

  # Dedicated download worker: same image, runs the yt-dlp job loop instead of the API.
  # It shares the DB (job queue) and the downloads mount with the API.
  worker:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        APP_VERSION: ${APP_VERSION:-dev}
        GIT_SHA: ${GIT_SHA:-unknown}
        BUILD_DATE: ${BUILD_DATE:-}
    command: ["python", "-m", "app.worker"]
    env_file: .env
    environment:
      DATABASE_URL: postgresql+psycopg://${POSTGRES_USER:-siftlode}:${POSTGRES_PASSWORD:-siftlode}@db:5432/${POSTGRES_DB:-siftlode}
      # The worker must not also run the scheduler; the API owns that.
      SCHEDULER_ENABLED: "false"
      DOWNLOAD_ROOT: /downloads
      WORKER_ENABLED: "true"
    depends_on:
      db:
        condition: service_healthy
      bgutil-pot:
        condition: service_started
    security_opt:
      - apparmor:unconfined
    volumes:
      - ./downloads:/downloads
      - plex_media:/plex-media:ro
    restart: unless-stopped

  # PO-token provider: mints YouTube Proof-of-Origin tokens on demand so the worker bypasses
  # bot-detection and gets high-quality formats. The worker reaches it at http://bgutil-pot:4416
  # (DOWNLOAD_POT_BASE_URL). Pin the tag to match the plugin version in requirements.txt.
  bgutil-pot:
    image: brainicism/bgutil-ytdlp-pot-provider:1.3.1
    init: true
    security_opt:
      - apparmor:unconfined
    restart: unless-stopped

volumes:
  pgdata:
  # OPTIONAL (Plex integration dev testing): the Plex media, mounted READ-ONLY from the SMB share
  # so the container can play the physical file locally (this dev box isn't the Plex host). Uses a
  # dedicated read-only samba user via PLEX_SMB_USER/PLEX_SMB_PASS in .env. Only referenced when the
  # Plex module is enabled; harmless otherwise (Docker mounts it lazily on first container use). On
  # prod (LXC on the Plex host) this is a plain host bind-mount instead — no SMB.
  plex_media:
    driver: local
    driver_opts:
      type: cifs
      # Host/share + credentials come from .env (gitignored) so no site-specific values live in
      # the tracked compose: PLEX_SMB_HOST, PLEX_SMB_SHARE, PLEX_SMB_USER, PLEX_SMB_PASS.
      device: "//${PLEX_SMB_HOST:-localhost}/${PLEX_SMB_SHARE:-data}"
      o: "username=${PLEX_SMB_USER:-},password=${PLEX_SMB_PASS:-},ro,vers=3.0,uid=1000,gid=1000,file_mode=0444,dir_mode=0555"
