"""
Celery application factory for DocuVault.

Kept deliberately minimal to avoid circular imports (Pitfall 7 from RESEARCH.md):
  - DO NOT import from config (triggers pydantic-settings env-loading side effects)
  - DO NOT import from main or any FastAPI router module
  - Only os + celery imported here

REDIS_URL is read directly from os.environ so that this module can be imported
safely by the Celery worker process without pulling in the FastAPI application
machinery.
"""
import os
from datetime import timedelta as _timedelta

from celery import Celery
from celery.schedules import crontab as _crontab

celery_app = Celery("docuvault")

# Broker + result backend — read REDIS_URL directly from env (not from config.settings)
_redis_url = os.environ.get("REDIS_URL", "redis://redis:6379/0")
celery_app.conf.broker_url = _redis_url
celery_app.conf.result_backend = _redis_url

# JSON-only serialization (safe default; avoids pickle deserialization risks)
celery_app.conf.task_serializer = "json"
celery_app.conf.result_serializer = "json"
celery_app.conf.accept_content = ["json"]

# Route document tasks to the dedicated `documents` queue;
# email tasks to the `email` queue (Phase 2 — D-03);
# audit tasks to the `documents` queue (D-17 — reuse documents worker)
celery_app.conf.task_routes = {
    "tasks.document_tasks.*": {"queue": "documents"},
    "tasks.email_tasks.*": {"queue": "email"},
    "tasks.audit_tasks.*": {"queue": "documents"},
}

# Celery beat schedule:
#   cleanup-abandoned-uploads — every 30 minutes (D-06)
#   audit-log-daily-export    — midnight UTC daily (D-17)
celery_app.conf.beat_schedule = {
    "cleanup-abandoned-uploads": {
        "task": "tasks.document_tasks.cleanup_abandoned_uploads",
        "schedule": _timedelta(minutes=30),
    },
    "audit-log-daily-export": {
        "task": "tasks.audit_tasks.audit_log_daily_export",
        "schedule": _crontab(hour=0, minute=0),
    },
}
celery_app.conf.timezone = "UTC"

# Autodiscover tasks under the `tasks/` package
celery_app.autodiscover_tasks(["tasks"], force=True)
