"""DMS 一体化启动入口（PyInstaller 打包用）。

职责：
1. 设置运行时环境变量（.env、存储目录）
2. 延后导入并启动 Flask 应用

设计约束：
- 必须在 ``import app`` 之前完成环境变量设置，
  因为 app.py 在导入时即调用 ``init_dms(app)`` 读取配置。
- 自实现 .env 解析，避免新增 python-dotenv 依赖。
"""
from __future__ import annotations

import os
import shutil
import sys
from pathlib import Path


def _app_root() -> Path:
    """exe 同级目录（用户可见、可写）。

    - PyInstaller 打包模式：``sys.executable`` 是 exe 文件本身
    - 开发模式：本文件位于 ``backend/launcher.py``，root 在上一级
    """
    if getattr(sys, "frozen", False):
        return Path(sys.executable).resolve().parent
    return Path(__file__).resolve().parent.parent


def _load_dotenv(env_path: Path) -> None:
    """简易 .env 解析器。

    仅做 ``key=value`` 解析，``setdefault`` 不覆盖已有环境变量。
    不依赖 python-dotenv，避免在 requirements.txt 中新增依赖。
    """
    if not env_path.exists():
        return
    with open(env_path, "r", encoding="utf-8") as f:
        for raw in f:
            line = raw.strip()
            if not line or line.startswith("#") or "=" not in line:
                continue
            key, _, value = line.partition("=")
            key = key.strip()
            value = value.strip().strip('"').strip("'")
            os.environ.setdefault(key, value)


def _ensure_runtime_dirs(root: Path) -> None:
    """在 exe 同级创建 dms-storage 子目录骨架，并写入环境变量。"""
    storage = root / "dms-storage"
    storage.mkdir(parents=True, exist_ok=True)
    for sub in (
        "extracted",
        "original",
        "preview",
        "quarantine",
        "recycle",
        "temporary",
    ):
        (storage / sub).mkdir(exist_ok=True)
    # 仅当 DMS_STORAGE_ROOT 未设置或为空时写入默认值。
    # 不能用 setdefault：_load_dotenv 会把 .env 中的空字符串注入环境变量，
    # 使 setdefault 误判为「已设置」，从而导致打包后默认存储路径失效。
    current_storage = os.environ.get("DMS_STORAGE_ROOT", "").strip()
    if not current_storage:
        os.environ["DMS_STORAGE_ROOT"] = str(storage)


def _bootstrap_env() -> Path:
    """准备运行环境，返回 app_root。"""
    root = _app_root()

    env_file = root / ".env"
    env_example = root / ".env.example"

    # 首次启动：从模板复制 .env
    if not env_file.exists() and env_example.exists():
        shutil.copy(env_example, env_file)
        print("=" * 60)
        print("[首次启动] 已生成配置文件：")
        print(f"  {env_file}")
        print("请编辑该文件填入数据库连接（DMS_DATABASE_URL）等信息，")
        print("保存后重新启动本程序。")
        print("=" * 60)

    _load_dotenv(env_file)
    _ensure_runtime_dirs(root)
    return root


def main() -> None:
    root = _bootstrap_env()

    # 延后导入：确保上面的环境变量先生效
    from app import app

    host = os.environ.get("DMS_HOST", "0.0.0.0")
    port = int(os.environ.get("DMS_PORT", "9345"))

    print(f"[DMS] 启动中... 访问地址: http://localhost:{port}")
    print(f"[DMS] 工作目录: {root}")
    print(f"[DMS] 按 Ctrl+C 退出")
    print("-" * 60)

    app.run(host=host, port=port, debug=False, use_reloader=False)


if __name__ == "__main__":
    main()
