"""FC-3d: cleanup_old_download_events task tests.

Asserts: (1) old terminal events are deleted, (2) recent terminal
events survive, (3) pending/running events survive regardless of age.
"""
from datetime import UTC, datetime, timedelta

import pytest
from sqlalchemy import create_engine, select
from sqlalchemy.orm import sessionmaker

import backend.app.tasks.maintenance  # noqa: F401 — side-effect: register task
from backend.app.celery_app import celery
from backend.app.config import get_config
from backend.app.models import Artist, DownloadEvent, ImportSettings, Source

pytestmark = pytest.mark.integration


def _sync_session():
    cfg = get_config()
    engine = create_engine(cfg.database_url_sync, future=True, pool_pre_ping=True)
    return sessionmaker(engine, expire_on_commit=False)()


def test_cleanup_deletes_old_terminal_events_only():
    """The maintenance task opens its own sync session and commits, so we
    seed via a separate sync session and rely on the autouse
    _reset_db_after_integration TRUNCATE to clean up afterward.
    """
    from backend.app.tasks.maintenance import cleanup_old_download_events

    s = _sync_session()
    try:
        # Force retention to 30 days for the test.
        settings = s.execute(
            select(ImportSettings).where(ImportSettings.id == 1)
        ).scalar_one()
        settings.download_event_retention_days = 30
        s.commit()

        artist = Artist(name="cleanup-a", slug="cleanup-a")
        s.add(artist)
        s.flush()
        source = Source(
            artist_id=artist.id, platform="patreon",
            url="https://cleanup-x", enabled=True,
        )
        s.add(source)
        s.flush()

        old_cutoff = datetime.now(UTC) - timedelta(days=60)
        recent = datetime.now(UTC) - timedelta(days=5)

        old_ok = DownloadEvent(
            source_id=source.id, status="ok",
            started_at=old_cutoff, finished_at=old_cutoff,
        )
        old_err = DownloadEvent(
            source_id=source.id, status="error",
            started_at=old_cutoff, finished_at=old_cutoff,
            error="x",
        )
        old_skip = DownloadEvent(
            source_id=source.id, status="skipped",
            started_at=old_cutoff, finished_at=old_cutoff,
        )
        old_pending = DownloadEvent(
            source_id=source.id, status="pending",
            started_at=old_cutoff,
        )
        old_running = DownloadEvent(
            source_id=source.id, status="running",
            started_at=old_cutoff,
        )
        recent_ok = DownloadEvent(
            source_id=source.id, status="ok",
            started_at=recent, finished_at=recent,
        )
        for ev in (old_ok, old_err, old_skip, old_pending, old_running, recent_ok):
            s.add(ev)
        s.commit()
        ids = {
            "old_ok": old_ok.id,
            "old_err": old_err.id,
            "old_skip": old_skip.id,
            "old_pending": old_pending.id,
            "old_running": old_running.id,
            "recent_ok": recent_ok.id,
        }
    finally:
        s.close()

    deleted = cleanup_old_download_events()
    assert deleted == 3

    s2 = _sync_session()
    try:
        survivors = set(s2.execute(
            select(DownloadEvent.id).where(DownloadEvent.id.in_(list(ids.values())))
        ).scalars().all())
    finally:
        s2.close()
    assert survivors == {ids["old_pending"], ids["old_running"], ids["recent_ok"]}


def test_cleanup_task_is_registered():
    assert "backend.app.tasks.maintenance.cleanup_old_download_events" in celery.tasks
