# -*- mode: python ; coding: utf-8 -*-

import os
from PyInstaller.utils.hooks import (
    collect_data_files,
    collect_dynamic_libs,
    collect_submodules,
)


def _safe_collect_submodules(name: str):
    try:
        return collect_submodules(name)
    except Exception:
        return []


def _safe_collect_data_files(name: str):
    try:
        return collect_data_files(name)
    except Exception:
        return []


def _safe_collect_dynamic_libs(name: str):
    try:
        return collect_dynamic_libs(name)
    except Exception:
        return []


project_root = r"e:\code\vismatch-main\vismatch-main"
test_dir = os.path.join(project_root, "test")
script_path = os.path.join(test_dir, "StripStitch.py")

# Find the actual vismatch installation location (usually in site-packages)
import vismatch as _vismatch_pkg
vismatch_sitepkg_root = os.path.dirname(_vismatch_pkg.__file__)


hiddenimports = []
hiddenimports += _safe_collect_submodules("vismatch")
hiddenimports += _safe_collect_submodules("rasterio")
hiddenimports += _safe_collect_submodules("rasterio._base")
hiddenimports += _safe_collect_submodules("rasterio._io")
hiddenimports += _safe_collect_submodules("affine")
hiddenimports += _safe_collect_submodules("cv2")
hiddenimports += ["tif_caijain"]

hiddenimports += _safe_collect_submodules("pyproj")
hiddenimports += _safe_collect_submodules("scipy")
hiddenimports += _safe_collect_submodules("skimage")
hiddenimports += _safe_collect_submodules("SimpleITK")
hiddenimports += _safe_collect_submodules("pirt")
hiddenimports += _safe_collect_submodules("loguru")

# MatchAnything's src module - need to collect from third_party directory
# Add the src module path to pathex so PyInstaller can find it during analysis
matchanything_src_dir = os.path.join(vismatch_sitepkg_root, "third_party", "MatchAnything", "imcui", "third_party", "MatchAnything")
if os.path.isdir(matchanything_src_dir):
    # Add to pathex for analysis
    pass  # Will be added to pathex in Analysis
    # Also try to collect src submodules if they exist
    try:
        hiddenimports += _safe_collect_submodules("src")
    except Exception:
        pass


datas = []
datas += _safe_collect_data_files("vismatch")
datas += _safe_collect_data_files("rasterio")
datas += _safe_collect_data_files("pyproj")

# vismatch 的 third_party 下包含大量运行时动态 add_to_path 的源码（例如 matchanything 依赖的 src.*）。
# 这些 .py 文件不会被 collect_data_files 收集，需作为 datas 复制到 dist 里，并保持相对路径结构，
# 使得运行时 THIRD_PARTY_DIR = Path(vismatch.__file__).parent/"third_party" 可找到它们.
# Use the actual vismatch installation location (site-packages) instead of project root
# NOTE: Analysis() expects hook-style 2-tuples (source_dir, dest_dir), not Tree() TOC 3-tuples.
third_party_dir = os.path.join(vismatch_sitepkg_root, "third_party")
if os.path.isdir(third_party_dir):
    datas.append((third_party_dir, os.path.join("vismatch", "third_party")))

# Include HuggingFace model weights for offline use (~/.cache/huggingface/hub/)
hf_cache_dir = os.path.join(os.path.expanduser("~"), ".cache", "huggingface", "hub")
if os.path.isdir(hf_cache_dir):
    for model_dir in os.listdir(hf_cache_dir):
        if "vismatch" in model_dir.lower():
            full_model_path = os.path.join(hf_cache_dir, model_dir)
            if os.path.isdir(full_model_path):
                datas.append((full_model_path, os.path.join("hub", model_dir)))


binaries = []
binaries += _safe_collect_dynamic_libs("rasterio")
binaries += _safe_collect_dynamic_libs("pyproj")
binaries += _safe_collect_dynamic_libs("cv2")

# Build pathex - include MatchAnything src directory for proper import analysis
pathex = [project_root, test_dir]
matchanything_src_dir = os.path.join(vismatch_sitepkg_root, "third_party", "MatchAnything", "imcui", "third_party", "MatchAnything")
if os.path.isdir(matchanything_src_dir):
    pathex.append(matchanything_src_dir)
    # Also add ROMA if it exists
    roma_dir = os.path.join(vismatch_sitepkg_root, "third_party", "MatchAnything", "imcui", "third_party", "MatchAnything", "third_party", "ROMA")
    if os.path.isdir(roma_dir):
        pathex.append(roma_dir)

a = Analysis(
    [script_path],
    pathex=pathex,
    binaries=binaries,
    datas=datas,
    hiddenimports=hiddenimports,
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    noarchive=False,
)

pyz = PYZ(a.pure)

exe = EXE(
    pyz,
    a.scripts,
    [],
    exclude_binaries=True,
    name="StripStitch",
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=False,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

coll = COLLECT(
    exe,
    a.binaries,
    a.zipfiles,
    a.datas,
    strip=False,
    upx=False,
    upx_exclude=[],
    name="StripStitch",
)
