# PyInstaller spec — GUI V6 (build-prep G3-D).
#
# Produit `Anonymisation.exe` (V6), source de l'installateur Inno
# `installer/Anonymisation.iss` qui génère la cible finale `Anonymisation-Setup.exe`.
#
# Entrée directe : Pseudonymisation_Gui_V6.py (expose main() + --self-test).
# Ne construit AUCUN artefact ici : la génération réelle se fait sur Windows.

import os
from pathlib import Path


block_cipher = None

project_dir = Path(globals().get("SPECPATH", os.getcwd())).resolve()


def _data_entry(relative_path: str, target_dir: str | None = None):
    src = project_dir / relative_path
    if not src.exists():
        return None
    return (str(src), target_dir or relative_path)


datas = []
for relative_path, target_dir in [
    ("config", "config"),
    ("data/bdpm", "data/bdpm"),
    ("data/edsnlp", "data/edsnlp"),
    ("data/finess", "data/finess"),
    ("data/insee", "data/insee"),
    ("models/camembert-bio-deid/onnx", "models/camembert-bio-deid/onnx"),
    ("detectors", "detectors"),
    ("scripts", "scripts"),
    ("assets", "assets"),
]:
    entry = _data_entry(relative_path, target_dir)
    if entry is not None:
        datas.append(entry)

for relative_path in [
    "data/stopwords_manuels.txt",
    "data/villes_blacklist.txt",
    "data/dpi_labels_blacklist.txt",
    "data/companion_blacklist.txt",
]:
    entry = _data_entry(relative_path, "data")
    if entry is not None:
        datas.append(entry)

onnxtr_cache_dir = Path(os.environ.get("ONNXTR_CACHE_DIR", Path.home() / ".cache" / "onnxtr"))
required_onnxtr_weights = [
    "db_resnet50-69ba0015.onnx",
    "crnn_vgg16_bn-743599aa.onnx",
]
missing_onnxtr_weights = []
for filename in required_onnxtr_weights:
    src = onnxtr_cache_dir / "models" / filename
    if src.exists():
        datas.append((str(src), "models/onnxtr/models"))
    else:
        missing_onnxtr_weights.append(str(src))
if missing_onnxtr_weights:
    raise FileNotFoundError(
        "Poids OCR OnnxTR manquants pour le build frozen : "
        + ", ".join(missing_onnxtr_weights)
        + ". Précharger OnnxTR (lancer une OCR une fois) ou définir ONNXTR_CACHE_DIR avant PyInstaller."
    )


hiddenimports = [
    # Entrée + package GUI V6
    "Pseudonymisation_Gui_V6",
    "gui_v6",
    "gui_v6.app",
    "gui_v6.theme",
    "gui_v6.license_client",
    "gui_v6.license_store",
    "gui_v6.machine_id",
    "gui_v6.engine_bridge",
    "gui_v6.config_state",
    "gui_v6.version",
    "gui_v6._build_version",
    "gui_v6.processing_runner",
    "gui_v6.tabs",
    "gui_v6.tabs.tab_about",
    "gui_v6.tabs.tab_config",
    "gui_v6.tabs.tab_usage",
    # UI customtkinter
    "customtkinter",
    "darkdetect",
    # Réseau licence
    "requests",
    # Moteur + modules support (inchangés vs V5)
    "anonymizer_core_refactored_onnx",
    "admin_mode",
    "admin_rules",
    "config_defaults",
    "profile_defaults",
    "gui_batch_paths",
    "manual_masking",
    "pdf_mask_designer",
    "format_converter",
    "ner_manager_onnx",
    "camembert_ner_manager",
    "eds_pseudo_manager",
    "gliner_manager",
    "vlm_manager",
    "build_info",
    # OCR OnnxTR (ONNX Runtime, remplace docTR — sans torch ni doctr)
    "onnxtr",
    "onnxtr.io",
    "onnxtr.models",
    "onnxtr.models.detection",
    "onnxtr.models.recognition",
    "onnxtr.utils",
    "onnxtr.utils.data",
    # Dépendances transitives OnnxTR (hiddenimports défensifs vs omission PyInstaller)
    "pyclipper",
    "scipy.cluster.hierarchy",
    "scipy.special",
    "cv2",
    "edsnlp",
    "edsnlp.pipes",
    "edsnlp.pipes.ner",
    "edsnlp.pipes.ner.pseudo",
    "spacy",
    "spacy.lang.fr",
    "gliner",
    "onnxruntime",
    "transformers",
    "tokenizers",
    "pdfplumber",
    "fitz",
    "PIL",
    "yaml",
    "loguru",
    "regex",
]

# P0-3 (Plan 3) : exclusion dure de la pile torch. Le core fait un
# `import torch` lazy (try/except no-op) dans _configure_torch_threads que
# l'analyse statique suivrait ; en frozen l'ImportError est attendue et gérée.
EXCLUDED_TORCH_STACK = [
    "torch",
    "torchvision",
    "optimum",
    "doctr",
]


a = Analysis(
    [str(project_dir / "Pseudonymisation_Gui_V6.py")],
    pathex=[str(project_dir)],
    datas=datas,
    hiddenimports=hiddenimports,
    excludes=EXCLUDED_TORCH_STACK,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

splash = Splash(
    str(project_dir / "assets" / "splash.png"),
    binaries=a.binaries,
    datas=a.datas,
    text_pos=(60, 195),
    text_size=10,
    text_color="white",
    minify_script=True,
    always_on_top=False,
)

exe = EXE(
    pyz,
    a.scripts,
    splash,
    splash.binaries,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name="Anonymisation",
    debug=False,
    strip=False,
    upx=False,
    console=False,
    icon=str(project_dir / "assets" / "icons" / "app.ico"),
)
