# -*- mode: python ; coding: utf-8 -*-
"""
PyInstaller 打包配置文件 — GEO Tool

打包模式：单文件 (EXE)，兼容 macOS / Windows
"""

import sys
from pathlib import Path

# PyInstaller 工具函数：收集包元数据和资源
from PyInstaller.utils.hooks import copy_metadata, collect_data_files, collect_all

block_cipher = None

# ── 资源文件列表 ──────────────────────────────────────────────
# 格式: (源路径, 目标路径 in MEIPASS)
# 目录会被递归包含
datas = [
    ("geo_tool.py", "."),
    ("config.json", "."),
    ("geo_data.db", "."),
    (".streamlit", ".streamlit"),
    ("modules", "modules"),
    ("platform_sync", "platform_sync"),
]

# ── 收集包的 dist-info/METADATA ──────────────────────────────
# 很多包在运行时通过 importlib.metadata.version(name) 获取版本号，
# PyInstaller 单文件模式不会自动包含这些元数据，需显式收集。
_METADATA_PACKAGES = [
    "streamlit",
    "pandas",
    "plotly",
    "langchain_core",
    "langchain_deepseek",
    "langchain_openai",
    "langchain_groq",
    "langchain_moonshot",
    "langchain_community",
    "dashscope",
    "httpx",
    "pyperclip",
    "watchdog",
    "importlib_metadata",
]
for _pkg in _METADATA_PACKAGES:
    try:
        datas += copy_metadata(_pkg)
    except Exception:
        pass  # 包未安装时静默跳过

# ── Streamlit 全量收集（子模块 + 数据 + 动态库）────────────
# Streamlit 大量使用动态 import（scriptrunner.magic_funcs 等），
# 必须用 collect_all 确保所有子模块都被找到。
try:
    _st_datas, _st_binaries, _st_hidden = collect_all("streamlit")
    datas += _st_datas
    binaries += _st_binaries
    hiddenimports += _st_hidden
except Exception:
    pass

# ── 其他包的静态 / 数据文件 ──────────────────────────────────
_DATAFILE_PACKAGES = [
    "plotly",          # plotly.min.js
    "altair",          # vega-lite schemas
    "pandas",          # JSON schemas
    "pyarrow",         # dataset discovery files
    "langchain_core",  # prompt templates
]
for _pkg in _DATAFILE_PACKAGES:
    try:
        datas += collect_data_files(_pkg)
    except Exception:
        pass

# ── 显式隐式导入 ──────────────────────────────────────────────
# PyInstaller 可能无法自动发现的动态 / 延迟导入
hiddenimports = [
    # ---- 应用模块 ----
    "modules",
    "modules.data_storage",
    "modules.keyword_tool",
    "modules.roi_analyzer",
    "modules.knowledge_base",
    "modules.keyword_mining",
    "modules.semantic_expander",
    "modules.topic_cluster",
    "modules.content_scorer",
    "modules.eeat_enhancer",
    "modules.fact_density_enhancer",
    "modules.optimization_techniques",
    "modules.schema_generator",
    "modules.technical_config_generator",
    "modules.multimodal_prompt",
    "modules.workflow_automation",
    "modules.negative_monitor",
    "modules.resource_recommender",
    "modules.config_optimizer",
    "modules.content_metrics",
    "modules.keyword_data_enhancer",
    "modules.content_uniqueness",
    "modules.ai_search_verifier",
    "modules.llm_factory",
    "modules.chat_doubao",
    "modules.ui",
    "modules.ui.state",
    "modules.ui.theme",
    "modules.ui.components",
    "modules.ui.tab_keywords",
    "modules.ui.tab_autowrite",
    "modules.ui.tab_optimize",
    "modules.ui.tab_validation",
    "modules.ui.tab_history",
    "modules.ui.tab_reports",
    "modules.ui.tab_workflow",
    "modules.ui.tab_resources",
    "modules.ui.tab_platform_sync",
    "modules.ui.tab_config_optimizer",
    "modules.ui.tab_knowledge",
    "modules.services",
    "modules.services.schema_service",
    "modules.services.tech_config_service",
    "platform_sync",
    "platform_sync.base_publisher",
    "platform_sync.github_publisher",
    "platform_sync.copy_manager",
    # ---- LangChain 生态系统 ----
    "langchain_core",
    "langchain_core.prompts",
    "langchain_core.output_parsers",
    "langchain_core.language_models",
    "langchain_deepseek",
    "langchain_openai",
    "langchain_groq",
    "langchain_moonshot",
    "langchain_community",
    "langchain_community.chat_models",
    "dashscope",
    # ---- 数据 / 可视化 ----
    "pandas",
    "plotly",
    "plotly.express",
    "plotly.graph_objects",
    # ---- 其他依赖 ----
    "pyperclip",
    "httpx",
    "watchdog",
    "sqlite3",
    "importlib.metadata",
    "tomli_w",
    # ---- Streamlit 内部依赖（动态子模块多，显式声明）----
    "altair",
    "pydeck",
]

# ── 排除不必要的包（减小体积） ──────────────────────────────────
excludes = [
    "tkinter",
    "matplotlib",
    "scipy",
    "PIL",
    "cv2",
    "notebook",
    "jupyter",
    "jedi",
    "ipython",
    "setuptools",
    "pdb",
    "unittest",
]

# ── Analysis ──────────────────────────────────────────────────
a = Analysis(
    ["run_bundle.py"],
    pathex=[],
    binaries=[],
    datas=datas,
    hiddenimports=hiddenimports,
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=excludes,
    noarchive=False,
    optimize=0,
)

pyz = PYZ(a.pure)

# ── 单文件可执行 ──────────────────────────────────────────────
# 不同平台自动选择合适输出：
#   macOS → geo_tool_app (Unix executable)
#   Windows → geo_tool_app.exe
exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name="geo_tool_app",
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    # macOS .app 产物额外配置（仅在 --windowed / console=False 时生效）
    # bundle_identifier=None,
    # info_plist=None,
)
