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

import os
import platform
from PyInstaller.utils.hooks import collect_submodules

block_cipher = None

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(SPEC)))
PEERDROP_PKG = os.path.join(ROOT, 'peerdrop')

IPFS_LITE = os.path.join(os.path.dirname(ROOT), 'ipfs-lite', 'py-ipfs-lite')
LIBP2P = os.path.join(os.path.dirname(ROOT), 'py-libp2p')

hidden_imports = [
    'trio',
    'click',
    'msgpack',
    'multiaddr',
    'multiaddr.codecs',
    'multiaddr.codecs.ip4',
    'multiaddr.codecs.ip6',
    'multiaddr.codecs.cid',
    'multiaddr.codecs.certhash',
    'multiaddr.codecs.domain',
    'multiaddr.codecs.fspath',
    'multiaddr.codecs.garlic32',
    'multiaddr.codecs.garlic64',
    'multiaddr.codecs.http_path',
    'multiaddr.codecs.ipcidr',
    'multiaddr.codecs.memory',
    'multiaddr.codecs.onion',
    'multiaddr.codecs.onion3',
    'multiaddr.codecs.uint16be',
    'multiaddr.codecs.utf8',
    'coincurve',
    'coincurve._cffi_backend',
    'cffi',
    'cffi._cffi_backend',
    '_cffi_backend',
    'PySide6',
    'PySide6.QtCore',
    'PySide6.QtGui',
    'PySide6.QtWidgets',
    'PySide6.QtNetwork',
]

extra_binaries = []
extra_datas = []

import importlib.util
_pyside6_spec = importlib.util.find_spec('PySide6')
if _pyside6_spec and _pyside6_spec.origin:
    _pyside6_dir = os.path.dirname(_pyside6_spec.origin)
    _qt_dir = os.path.join(_pyside6_dir, 'Qt')

    # On Linux, ship every Qt plugin (.so) and Qt shared library so the app
    # never fails to find a platform/style/image plugin at runtime. On macOS
    # this blanket walk is neither possible (Qt ships .framework bundles) nor
    # needed: PyInstaller's bindepend auto-collects the linked frameworks and
    # the per-module PySide6 hooks collect the required plugins/translations.
    if platform.system() != 'Darwin':
        for root, dirs, files in os.walk(os.path.join(_qt_dir, 'plugins')):
            for f in files:
                if f.endswith('.so'):
                    src = os.path.join(root, f)
                    rel = os.path.relpath(root, _qt_dir)
                    dest = os.path.join('PySide6', 'Qt', rel)
                    extra_binaries.append((src, dest))

        _qt_lib = os.path.join(_qt_dir, 'lib')
        if os.path.isdir(_qt_lib):
            for f in os.listdir(_qt_lib):
                if f.endswith('.so') or '.so.' in f:
                    src = os.path.join(_qt_lib, f)
                    if os.path.isfile(src):
                        extra_binaries.append((src, os.path.join('PySide6', 'Qt', 'lib')))

    # Collect PySide6 .pyi stubs as data
    for f in os.listdir(_pyside6_dir):
        if f.endswith('.pyi'):
            src = os.path.join(_pyside6_dir, f)
            extra_datas.append((src, 'PySide6'))

a = Analysis(
    [os.path.join(PEERDROP_PKG, 'interfaces', 'gui', 'app.py')],
    pathex=[ROOT, IPFS_LITE, LIBP2P],
    binaries=extra_binaries,
    datas=extra_datas,
    hiddenimports=hidden_imports,
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

a.hiddenimports += collect_submodules('py_ipfs_lite')
a.hiddenimports += collect_submodules('libp2p')
a.hiddenimports += collect_submodules('coincurve')
a.hiddenimports += collect_submodules('cffi')
a.hiddenimports += collect_submodules('multiaddr')
# PeerDrop only uses QtCore/QtGui/QtWidgets/QtNetwork (listed in
# hidden_imports above). PySide6 ships as .so/.framework binaries, so
# collect_submodules('PySide6') would add nothing useful; the per-module
# PySide6 hooks collect the required plugins/translations and bindepend
# pulls the linked Qt frameworks (e.g. the platform plugin's QtDBus,
# QtPrintSupport, QtSvg) transitively.

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    [],
    exclude_binaries=True,
    name='peerdrop-gui',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=False,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon=None,
)

coll = COLLECT(
    exe,
    a.binaries,
    a.zipfiles,
    a.datas,
    strip=False,
    upx=False,
    upx_exclude=[],
    name='peerdrop-gui',
)

# On macOS, additionally produce a double-clickable .app bundle.
if platform.system() == 'Darwin':
    app = BUNDLE(
        exe,
        a.binaries,
        a.zipfiles,
        a.datas,
        name='PeerDrop.app',
        icon=None,
        bundle_identifier='io.peerdrop.app',
    )
