"""delete_file=true 로 요청된 문서의 NAS 원본을 grace 후 물리삭제 (R7 retention sweep).

purge_requested_at 마커 기준(deleted_at 아님 — 일반 soft-delete/숨김은 파일 보존, undelete
가능). grace(30일) 경과 + 파일 존재 시 unlink + AUDIT 로그. 파일 존재 체크로 멱등
(재실행 시 이미 삭제된 건 skip). 요청 경로(DELETE)엔 동기 비가역 op 0 — 모두 이 cron 으로.
"""
import asyncio
import logging
from datetime import datetime, timedelta, timezone
from pathlib import Path

from sqlalchemy import select

from core.config import settings
from core.database import async_session
from models.document import Document

logger = logging.getLogger("purge_sweep")

PURGE_GRACE_DAYS = 30


def _unlink_if_exists(p: Path) -> bool:
    """파일이 있으면 unlink (blocking — caller 가 to_thread). 존재 여부 반환(멱등)."""
    if p.exists():
        p.unlink()
        return True
    return False


async def run() -> int:
    """purge 요청 + grace 경과 문서의 NAS 원본 물리삭제. 삭제 건수 반환."""
    cutoff = datetime.now(timezone.utc) - timedelta(days=PURGE_GRACE_DAYS)
    async with async_session() as session:
        rows = (
            await session.execute(
                select(Document.id, Document.file_path, Document.purge_requested_at).where(
                    Document.purge_requested_at.is_not(None),
                    Document.purge_requested_at < cutoff,
                    Document.file_path.is_not(None),
                )
            )
        ).all()

    purged = 0
    for doc_id, file_path, requested_at in rows:
        nas_path = Path(settings.nas_mount_path) / file_path
        try:
            existed = await asyncio.to_thread(_unlink_if_exists, nas_path)
            if existed:
                purged += 1
                # AUDIT — 물리삭제 기록 (가시화). doc_id / 경로 / 요청일 / grace.
                logger.warning(
                    "PURGE doc_id=%s file=%s requested_at=%s grace_days=%s",
                    doc_id,
                    file_path,
                    requested_at.isoformat() if requested_at else None,
                    PURGE_GRACE_DAYS,
                )
        except OSError as e:
            logger.error("PURGE 실패 doc_id=%s file=%s: %s", doc_id, file_path, e)

    if purged:
        logger.info("[purge_sweep] NAS 원본 %d건 물리삭제 (grace %d일)", purged, PURGE_GRACE_DAYS)
    return purged
