"""
DOOBAT - Service de nettoyage
Suppression automatique des anciens PDF.
Copyright 2026 Vincent Gallet - Vincesoft
"""

import logging
import os
import time
from configparser import ConfigParser

logger = logging.getLogger("doobat.cleanup")


class CleanupService:
    """
    Supprime automatiquement les fichiers PDF générés
    dont l'âge dépasse le seuil configuré (par défaut 7 jours).
    """

    def __init__(self, config: ConfigParser):
        self._pdf_dir = config.get("PDF", "output_dir", fallback="pdf")
        self._max_age_days = config.getint("PDF", "max_age_days", fallback=7)
        logger.info(
            f"CleanupService initialisé : dir={self._pdf_dir}, "
            f"max_age={self._max_age_days} jours"
        )

    def cleanup_old_pdfs(self) -> int:
        """
        Supprime les fichiers PDF de plus de max_age_days jours.
        Retourne le nombre de fichiers supprimés.
        """
        if not os.path.isdir(self._pdf_dir):
            logger.warning(f"Dossier PDF introuvable : {self._pdf_dir}")
            return 0

        max_age_seconds = self._max_age_days * 86400
        now = time.time()
        deleted = 0

        try:
            for filename in os.listdir(self._pdf_dir):
                if not filename.lower().endswith(".pdf"):
                    continue

                # Protection anti path traversal
                filepath = os.path.realpath(
                    os.path.join(self._pdf_dir, filename)
                )
                pdf_dir_real = os.path.realpath(self._pdf_dir)
                if not filepath.startswith(pdf_dir_real + os.sep):
                    logger.warning(f"Path traversal détecté, ignoré : {filename}")
                    continue

                try:
                    file_age = now - os.path.getmtime(filepath)
                    if file_age > max_age_seconds:
                        os.remove(filepath)
                        deleted += 1
                        logger.debug(
                            f"PDF supprimé : {filename} "
                            f"(âge: {file_age / 3600:.1f}h)"
                        )
                except OSError as e:
                    logger.warning(f"Impossible de supprimer {filename} : {e}")

        except OSError as e:
            logger.error(f"Erreur listage dossier PDF : {e}")

        if deleted > 0:
            logger.info(f"Nettoyage PDF terminé : {deleted} fichier(s) supprimé(s)")
        return deleted

    def get_pdf_stats(self) -> dict:
        """Retourne des statistiques sur les fichiers PDF générés."""
        if not os.path.isdir(self._pdf_dir):
            return {"count": 0, "total_size_mb": 0.0, "oldest_days": 0.0}

        now = time.time()
        count = 0
        total_size = 0
        oldest_age = 0.0

        try:
            for filename in os.listdir(self._pdf_dir):
                if not filename.lower().endswith(".pdf"):
                    continue
                filepath = os.path.join(self._pdf_dir, filename)
                try:
                    stat = os.stat(filepath)
                    count += 1
                    total_size += stat.st_size
                    age = now - stat.st_mtime
                    if age > oldest_age:
                        oldest_age = age
                except OSError:
                    pass
        except OSError as e:
            logger.error(f"Erreur stats PDF : {e}")

        return {
            "count": count,
            "total_size_mb": round(total_size / 1_048_576, 2),
            "oldest_days": round(oldest_age / 86400, 1),
        }
