"""
WorkerPoolMixin - Mixin für Worker-Pool-Verwaltung.

Dieses Mixin enthält alle Methoden zur Verwaltung der Saxon- und FOP-Worker-Pools
für das MainWindow.
"""

import logging

from PySide6.QtWidgets import QMessageBox

from conf import app_settings, XsltVersion
from transform import TransformationJob, get_saxon_worker_pool, set_saxon_worker_pool, get_fop_worker_pool, set_fop_worker_pool
from saxon_pool import SaxonWorkerPool
from saxon_pool_s9api import SaxonWorkerPoolS9Api

logger = logging.getLogger(__name__)


class WorkerPoolMixin:
    """
    Mixin für Worker-Pool-Verwaltung.

    Dieses Mixin wird von MainWindow verwendet und erwartet folgende Attribute:
    - self.project: Das aktuelle Projekt
    """

    def _initialize_saxon_worker_pool(self):
        """Initialisiert den Saxon-Worker-Pool für schnelle Transformationen."""
        try:
            # Shutdown vorherigen Pool falls vorhanden
            self._shutdown_saxon_worker_pool()

            # Prüfe ob SaxonWorkerPool aktiviert ist
            if not app_settings.use_saxon_worker_pool:
                logger.info("SaxonWorkerPool deaktiviert - Verwende Fallback-Modus (subprocess)")
                return

            if not self.project:
                logger.warning("Kein Projekt geladen, Saxon-Worker-Pool nicht initialisiert")
                return

            # Hole Tool-Konfigurationen
            java_vm = next((vm for vm in app_settings.java_vms if vm.id == self.project.java_vm_id), None)
            saxon_jar = next((jar for jar in app_settings.saxon_jars if jar.id == self.project.saxon_jar_id), None)

            if not java_vm or not saxon_jar:
                logger.warning("Java VM oder Saxon JAR nicht gefunden, Pool nicht initialisiert")
                return

            # Erstelle Worker-Pool (wähle richtige Variante basierend auf XSLT-Version)
            num_workers = app_settings.max_workers
            log_dir = self.project.project_dir / "tmp"

            # Wähle die richtige Worker-Pool-Implementierung
            if app_settings.saxon_xslt_version == XsltVersion.XSLT_1_0:
                # JAXP-basierte Variante für XSLT 1.0
                pool = SaxonWorkerPool(
                    num_workers=num_workers,
                    java_vm_path=java_vm.path_to_binary_file,
                    saxon_jar_path=saxon_jar.path_to_jar_file,
                    classpath_cache=TransformationJob._classpath_cache,
                    log_dir=log_dir,
                )
                pool_type = "JAXP (XSLT 1.0)"
            else:
                # s9api-basierte Variante für XSLT 2.0/3.0
                pool = SaxonWorkerPoolS9Api(
                    num_workers=num_workers,
                    java_vm_path=java_vm.path_to_binary_file,
                    saxon_jar_path=saxon_jar.path_to_jar_file,
                    classpath_cache=TransformationJob._classpath_cache,
                    log_dir=log_dir,
                )
                pool_type = "s9api (XSLT 2.0/3.0)"

            # Setze globalen Pool
            set_saxon_worker_pool(pool)

            logger.info(
                f"Saxon-Worker-Pool initialisiert: {num_workers} Worker mit {pool_type} "
                f"(erwartet: {num_workers}x schneller für Saxon-Transformationen)"
            )

        except Exception as e:
            logger.error(f"Fehler beim Initialisieren des Saxon-Worker-Pools: {e}")
            logger.info("Fallback auf subprocess-Modus")
            # Kein Pool ist OK - Fallback auf subprocess

    def _shutdown_saxon_worker_pool(self):
        """Beendet den Saxon-Worker-Pool sauber."""
        try:
            pool = get_saxon_worker_pool()
            if pool:
                logger.info("Beende Saxon-Worker-Pool...")
                pool.shutdown()
                set_saxon_worker_pool(None)
                logger.info("Saxon-Worker-Pool beendet")

        except Exception as e:
            logger.error(f"Fehler beim Beenden des Saxon-Worker-Pools: {e}")

    def _initialize_fop_worker_pool(self):
        """Initialisiert den FOP-Worker-Pool für schnelle PDF-Generierung."""
        try:
            # Shutdown vorherigen Pool falls vorhanden
            self._shutdown_fop_worker_pool()

            # Prüfe ob FopWorkerPool aktiviert ist
            if not app_settings.use_fop_worker_pool:
                logger.info("FopWorkerPool deaktiviert - Verwende Fallback-Modus (subprocess)")
                return

            if not self.project:
                logger.warning("Kein Projekt geladen, FOP-Worker-Pool nicht initialisiert")
                return

            # Hole Tool-Konfigurationen
            java_vm = next((vm for vm in app_settings.java_vms if vm.id == self.project.java_vm_id), None)
            apache_fop = next((fop for fop in app_settings.apache_fops if fop.id == self.project.apache_fop_id), None)

            if not java_vm or not apache_fop:
                logger.warning("Java VM oder Apache FOP nicht gefunden, Pool nicht initialisiert")
                return

            # FOP-Konfigurationsdatei (falls vorhanden)
            fop_config_file = None
            if self.project.fop_config_dir:
                fop_config_file = self.project.fop_config_dir / "fop.xconf"
            else:
                default_config = apache_fop.path_to_dir / "conf" / "fop.xconf"
                if default_config.exists():
                    fop_config_file = default_config

            # Importiere FopWorkerPool
            from fop_pool import FopWorkerPool

            # Erstelle Worker-Pool
            num_workers = app_settings.max_workers
            log_dir = self.project.project_dir / "tmp"
            pool = FopWorkerPool(
                num_workers=num_workers,
                java_vm_path=java_vm.path_to_binary_file,
                apache_fop_dir=apache_fop.path_to_dir,
                fop_config_file=fop_config_file,
                log_dir=log_dir,
            )

            # Setze globalen Pool
            set_fop_worker_pool(pool)

            logger.info(
                f"FOP-Worker-Pool initialisiert: {num_workers} Worker "
                f"(erwartet: {num_workers}x schneller für PDF-Generierung)"
            )

        except Exception as e:
            logger.error(f"Fehler beim Initialisieren des FOP-Worker-Pools: {e}")
            logger.info("Fallback auf subprocess-Modus")
            # Kein Pool ist OK - Fallback auf subprocess

    def _shutdown_fop_worker_pool(self):
        """Beendet den FOP-Worker-Pool sauber."""
        try:
            pool = get_fop_worker_pool()
            if pool:
                logger.info("Beende FOP-Worker-Pool...")
                pool.shutdown()
                set_fop_worker_pool(None)
                logger.info("FOP-Worker-Pool beendet")

        except Exception as e:
            logger.error(f"Fehler beim Beenden des FOP-Worker-Pools: {e}")

    def _show_worker_pool_metrics(self):
        """Zeigt den Worker-Pool-Metriken-Dialog an."""
        try:
            from ui.WorkerPoolMetricsDialog import WorkerPoolMetricsDialog

            dialog = WorkerPoolMetricsDialog(self)
            dialog.exec()
        except Exception as e:
            logger.error(f"Fehler beim Öffnen des Metriken-Dialogs: {e}")
            QMessageBox.critical(self, "Fehler", f"Fehler beim Öffnen des Metriken-Dialogs:\n{str(e)}")
