# ==============================================================================
# ConvertX-CN 官方 Docker Image
# 版本：v0.1.11
# ==============================================================================
#
# 📦 Image 說明：
#   - 這是 ConvertX-CN 官方 Docker Hub Image 的生產 Dockerfile
#   - 已內建完整功能，無需額外擴充
#   - ⚠️ 所有模型已在 build 階段預下載，runtime 不依賴網路
#
# 🌍 內建語言支援：
#   - OCR: 英文、繁體中文、簡體中文、日文、韓文、德文、法文
#   - Locale: en_US, zh_TW, zh_CN, ja_JP, ko_KR, de_DE, fr_FR
#   - 字型: Noto CJK, Liberation, 標楷體
#   - LaTeX: CJK、德文、法文、阿拉伯語、希伯來語
#
# 🤖 預下載模型清單：
#   - PDFMathTranslate: DocLayout-YOLO ONNX（佈局分析）
#   - BabelDOC: 資源透過顯式 Python 腳本下載，禁止 warmup
#   - MinerU: PDF-Extract-Kit-1.0（Pipeline 模型）
#     包含：DocLayout-YOLO, YOLOv8 MFD, UniMERNet, PaddleOCR, LayoutReader, SLANet
#
# 📊 Image 大小：約 8-12 GB（含模型）
#
# ⚠️ Base Image：使用 debian:bookworm（穩定版）
#    - 確保 Multi-Arch (amd64/arm64) 構建穩定性
#    - 避免 trixie (testing) 套件同步不穩定問題
#
# 🔒 OFFLINE-FIRST 設計原則：
#   1. 所有下載行為只發生在 Docker build 階段
#   2. Runtime 完全不依賴外部網路
#   3. 禁止任何隱式下載（warmup、first-import、lazy-load）
#   4. 所有 cache 在同一 RUN 內清除，避免 layer 膨脹
#
# ==============================================================================

FROM debian:bookworm-slim AS base
LABEL org.opencontainers.image.source="https://github.com/pi-docket/ConvertX-CN"
LABEL org.opencontainers.image.description="ConvertX-CN - 精簡版檔案轉換服務"
LABEL org.opencontainers.image.version="0.1.11"
WORKDIR /app

# 配置 APT 重試機制（解決 Multi-Arch Build 時的網路不穩定問題）
RUN echo 'Acquire::Retries "5";' > /etc/apt/apt.conf.d/80-retries \
    && echo 'Acquire::http::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \
    && echo 'Acquire::https::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \
    && echo 'Acquire::ftp::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \
    && echo 'DPkg::Lock::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries

# install bun
RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    unzip \
    ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# if architecture is arm64, use the arm64 version of bun
RUN ARCH=$(uname -m) && \
    if [ "$ARCH" = "aarch64" ]; then \
    curl -fsSL -o bun-linux-aarch64.zip https://github.com/oven-sh/bun/releases/download/bun-v1.3.6/bun-linux-aarch64.zip; \
    else \
    curl -fsSL -o bun-linux-x64-baseline.zip https://github.com/oven-sh/bun/releases/download/bun-v1.3.6/bun-linux-x64-baseline.zip; \
    fi

RUN unzip -j bun-linux-*.zip -d /usr/local/bin && \
    rm bun-linux-*.zip && \
    chmod +x /usr/local/bin/bun

# install dependencies into temp directory
# this will cache them and speed up future builds
FROM base AS install
RUN mkdir -p /temp/dev
COPY package.json bun.lock /temp/dev/
RUN cd /temp/dev && bun install --frozen-lockfile

# install with --production (exclude devDependencies)
RUN mkdir -p /temp/prod
COPY package.json bun.lock /temp/prod/
RUN cd /temp/prod && bun install --frozen-lockfile --production

FROM base AS prerelease
WORKDIR /app
COPY --from=install /temp/dev/node_modules node_modules
COPY . .

# ENV NODE_ENV=production
RUN bun run build

# copy production dependencies and source code into final image
FROM base AS release

# ==============================================================================
# 依賴安裝（分段安裝，優化 Multi-Arch Build 穩定性）
# ==============================================================================
#
# ✅ 核心轉換工具：完整保留
# ✅ TexLive：完整 CJK + 德法 + 阿拉伯/希伯來語
# ✅ OCR：7 種主要語言
# ✅ 字型：Noto CJK + Liberation + 標楷體
# ✅ OpenCV：電腦視覺轉換支援
# ✅ 額外影片編解碼器
# ✅ PDFMathTranslate：PDF 翻譯引擎
#
# 📝 分段安裝說明：
#   - 將套件拆分為多個 RUN 層，避免 QEMU 模擬時記憶體不足
#   - 每段安裝後清理 apt cache，減少中間層大小
#   - 最終 squash 時會合併為單一層
#
# ==============================================================================

# 配置 APT 重試機制（解決 Multi-Arch Build 時的網路不穩定問題）
RUN echo 'Acquire::Retries "5";' > /etc/apt/apt.conf.d/80-retries \
    && echo 'Acquire::http::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \
    && echo 'Acquire::https::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \
    && echo 'Acquire::ftp::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries \
    && echo 'APT::Get::Assume-Yes "true";' >> /etc/apt/apt.conf.d/80-retries \
    && echo 'DPkg::Lock::Timeout "120";' >> /etc/apt/apt.conf.d/80-retries

# 階段 1：基礎系統工具
RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends \
    locales \
    ca-certificates \
    curl \
    && rm -rf /var/lib/apt/lists/*

# 階段 2：核心轉換工具（小型）
# 注意：dasel 和 resvg 在 bookworm 中不存在，後續用二進位檔案安裝
RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends \
    assimp-utils \
    dcraw \
    dvisvgm \
    ghostscript \
    graphicsmagick \
    mupdf-tools \
    poppler-utils \
    potrace \
    && rm -rf /var/lib/apt/lists/*

# 階段 2.1：安裝 dasel（從 GitHub 下載二進位檔案）
# ⬇️ Docker build 階段下載，runtime 不會再下載
RUN ARCH=$(uname -m) && \
    if [ "$ARCH" = "aarch64" ]; then \
    DASEL_ARCH="linux_arm64"; \
    else \
    DASEL_ARCH="linux_amd64"; \
    fi && \
    curl -sSLf "https://github.com/TomWright/dasel/releases/download/v2.8.1/dasel_${DASEL_ARCH}" -o /usr/local/bin/dasel && \
    chmod +x /usr/local/bin/dasel

# 階段 2.2：安裝 resvg（從 GitHub 下載二進位檔案）
# 注意：resvg 官方只提供 x86_64 版本，ARM64 需從源碼編譯或跳過
# ⬇️ Docker build 階段下載，runtime 不會再下載
RUN ARCH=$(uname -m) && \
    if [ "$ARCH" = "aarch64" ]; then \
    echo "⚠️ resvg 沒有 ARM64 預編譯版本，跳過安裝（可改用 ImageMagick 或 Inkscape 替代）"; \
    else \
    curl -sSLf "https://github.com/linebender/resvg/releases/download/v0.44.0/resvg-linux-x86_64.tar.gz" -o /tmp/resvg.tar.gz && \
    tar -xzf /tmp/resvg.tar.gz -C /tmp/ && \
    mv /tmp/resvg /usr/local/bin/resvg && \
    chmod +x /usr/local/bin/resvg && \
    rm -rf /tmp/resvg.tar.gz; \
    fi

# 階段 3：影音處理工具
RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends \
    ffmpeg \
    libavcodec-extra \
    libva2 \
    && rm -rf /var/lib/apt/lists/*

# 階段 4：圖像處理工具
# 注意：bookworm 使用 imagemagick（版本 6），trixie 才有 imagemagick-7
RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends \
    imagemagick \
    inkscape \
    libheif-examples \
    libjxl-tools \
    libvips-tools \
    && rm -rf /var/lib/apt/lists/*

# 階段 5：文件處理工具
RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends \
    calibre \
    libemail-outlook-message-perl \
    pandoc \
    && rm -rf /var/lib/apt/lists/*

# 階段 6：LibreOffice（最大的套件，單獨安裝）
RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends \
    libreoffice \
    && rm -rf /var/lib/apt/lists/*

# 階段 7：TexLive 基礎
RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends \
    texlive-base \
    texlive-latex-base \
    texlive-latex-recommended \
    texlive-fonts-recommended \
    texlive-xetex \
    latexmk \
    lmodern \
    && rm -rf /var/lib/apt/lists/*

# 階段 8：TexLive 語言包
RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends \
    texlive-lang-cjk \
    texlive-lang-german \
    texlive-lang-french \
    texlive-lang-arabic \
    texlive-lang-other \
    && rm -rf /var/lib/apt/lists/*

# 階段 9：OCR 支援
RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends \
    tesseract-ocr \
    tesseract-ocr-eng \
    tesseract-ocr-chi-tra \
    tesseract-ocr-chi-sim \
    tesseract-ocr-jpn \
    tesseract-ocr-kor \
    tesseract-ocr-deu \
    tesseract-ocr-fra \
    && rm -rf /var/lib/apt/lists/*

# 階段 10：字型
RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends \
    fonts-noto-cjk \
    fonts-noto-core \
    fonts-noto-color-emoji \
    fonts-liberation \
    && rm -rf /var/lib/apt/lists/*

# 階段 11：Python 依賴
RUN apt-get update --fix-missing && apt-get install -y --no-install-recommends \
    python3 \
    python3-pip \
    python3-numpy \
    python3-tinycss2 \
    python3-opencv \
    pipx \
    && rm -rf /var/lib/apt/lists/*

# ==============================================================================
# 🔧 Python 工具安裝策略
# ==============================================================================
#
# ⚠️ 重要原則：
#   1. pipx install 只安裝 CLI 工具本身
#   2. 模型/資源下載必須在後續單獨的 RUN 中顯式執行
#   3. 禁止依賴 --warmup 或 first-import 隱式下載
#   4. 所有 cache 必須在同一 RUN 內清除
#
# ==============================================================================

# 階段 12：安裝 Python 基礎工具
# ⬇️ 此步驟只安裝 huggingface_hub 用於後續模型下載
#    runtime 不會再使用此套件下載任何資源
RUN pip3 install --no-cache-dir --break-system-packages huggingface_hub \
    && rm -rf /root/.cache/pip /tmp/*

# 階段 12-A：安裝 markitdown（文件轉換工具）
# 注意：markitdown[all] 可能依賴 transformers，但不會在 import 時下載模型
# ⬇️ 此步驟為 Docker build 階段安裝，runtime 不會再下載
RUN pipx install "markitdown[all]" \
    && rm -rf /root/.cache/pip /root/.local/pipx/.cache /tmp/*

# 階段 12-B：安裝 pdf2zh（PDFMathTranslate 引擎）
# 注意：pdf2zh 的模型將在後續階段顯式下載
# ⬇️ 此步驟為 Docker build 階段安裝，runtime 不會再下載
RUN pipx install "pdf2zh" \
    && rm -rf /root/.cache/huggingface /root/.cache/pip /root/.local/pipx/.cache /tmp/*

# 階段 12-C：安裝 babeldoc（BabelDOC 引擎）
# ⚠️ 注意：不使用 --warmup，資源將在後續階段顯式下載
# ⬇️ 此步驟為 Docker build 階段安裝，runtime 不會再下載
RUN (pipx install "babeldoc" || echo "⚠️ babeldoc 安裝失敗，跳過...") \
    && rm -rf /root/.cache/huggingface /root/.cache/pip /root/.local/pipx/.cache /tmp/*

# 階段 12-D：安裝 mineru（MinerU PDF 解析引擎）
# ⚠️ 注意：mineru[all] 依賴大量 HuggingFace 套件，但安裝時不應下載模型
#    模型下載將在後續階段顯式執行
# ⬇️ 此步驟為 Docker build 階段安裝，runtime 不會再下載
RUN (pipx install "mineru[all]" || echo "⚠️ mineru 安裝失敗（可能是 arm64 相容性問題），跳過...") \
    && rm -rf /root/.cache/huggingface /root/.cache/pip /root/.cache/torch /root/.local/pipx/.cache /tmp/*

# Add pipx bin directory to PATH（必須在模型下載前設定）
ENV PATH="/root/.local/bin:${PATH}"

# ==============================================================================
# 🔥 模型預下載區塊（Docker Build 階段）
# ==============================================================================
#
# ⚠️ 核心原則（OFFLINE-FIRST）：
#   1. 所有模型必須在 build 階段下載完成
#   2. Runtime 完全不依賴外部網路
#   3. 禁止任何隱式下載行為（warmup、lazy-load、first-import）
#   4. 使用顯式 Python 腳本下載，而非 CLI warmup
#   5. 所有 cache 必須在同一 RUN 內清除
#
# 📦 預下載的模型清單：
#   1. PDFMathTranslate / pdf2zh
#      - DocLayout-YOLO ONNX 模型（佈局分析）
#   2. MinerU / magic-pdf
#      - DocLayout-YOLO（佈局分析）
#      - YOLOv8 MFD（公式偵測）
#      - UniMERNet（公式辨識）
#      - PaddleOCR（文字辨識）
#      - LayoutReader（閱讀順序）
#      - SLANet / UNet（表格辨識）
#   3. BabelDOC
#      - 翻譯服務不需要本地模型（使用 API）
#      - 字型和資源透過顯式下載
#
# ==============================================================================
# 🔧 BuildKit 優化說明：
# ==============================================================================
# 解決 "no space left on device" 的核心策略：
#
# 1. 【單一 RUN 原則】
#    所有模型下載 + cache 清理必須在同一個 RUN 中完成
#    這樣 BuildKit 在計算 layer diff 時，只會看到「最終狀態」
#    而不是「下載的 blob cache + 複製的模型」兩份資料
#
# 2. 【HuggingFace cache 必須刪除】
#    snapshot_download 會在 ~/.cache/huggingface/hub 下建立：
#    - blobs/：實際的模型檔案（用 SHA256 命名）
#    - snapshots/：指向 blobs 的 symlink 或複製
#    當 local_dir_use_symlinks=False 時，檔案會被「複製」到目標目錄
#    如果不刪除 cache，同一份模型會以兩份大小進入 layer diff
#
# 3. 【避免 overlayfs 重複壓縮】
#    exporting layers 時，BuildKit 會：
#    - 計算每層的 diff（新增/修改的檔案）
#    - 壓縮 diff 並寫入 /var/lib/buildkit/runc-overlayfs/
#    如果 cache 沒刪，diff 會包含 cache + 目標目錄，壓縮時空間翻倍
#
# ==============================================================================

# ------------------------------------------------------------------------------
# 階段 14-UNIFIED：所有模型下載 + 快取清理（單一 RUN 避免 layer 爆炸）
# ------------------------------------------------------------------------------
# 🔑 關鍵：這個 RUN 必須包含所有下載操作，並在結尾清理所有 cache
#         這樣 overlayfs 的 diff 只包含「最終需要的模型檔案」
#         而不是「cache 結構 + 模型副本」
#
# ⬇️ 以下為 Docker build 階段下載所有模型
#    runtime 不會再下載任何資源
# ------------------------------------------------------------------------------
RUN set -eux && \
    echo "===========================================================" && \
    echo "🚀 開始統一模型下載（單一 RUN 優化 BuildKit layer）" && \
    echo "===========================================================" && \
    \
    # ========================================
    # [1/5] PDFMathTranslate DocLayout-YOLO ONNX 模型
    # ========================================
    # ⬇️ Docker build 階段下載 DocLayout-YOLO ONNX 模型
    #    這是 pdf2zh 用於 PDF 版面分析的核心模型
    #    runtime 不會再下載此資源
    echo "" && \
    echo "📥 [1/5] 下載 DocLayout-YOLO ONNX 模型..." && \
    mkdir -p /models/pdfmathtranslate && \
    python3 -c " \
    import os; \
    os.environ['HF_HUB_DISABLE_PROGRESS_BARS'] = '0'; \
    from huggingface_hub import snapshot_download; \
    snapshot_download( \
    repo_id='wybxc/DocLayout-YOLO-DocStructBench-onnx', \
    local_dir='/models/pdfmathtranslate', \
    allow_patterns=['*.onnx'], \
    local_dir_use_symlinks=False \
    )" && \
    echo "✅ DocLayout-YOLO ONNX 下載完成" && \
    ls -lh /models/pdfmathtranslate/*.onnx 2>/dev/null || ls -lh /models/pdfmathtranslate/ && \
    \
    # 🔥 立即清理 HuggingFace cache（關鍵！避免 blob 重複進入 layer）
    rm -rf /root/.cache/huggingface && \
    \
    # ========================================
    # [2/5] BabelDOC 資源（顯式下載，禁止 warmup）
    # ========================================
    # ⚠️ 重要：不使用 babeldoc --warmup，因為：
    #    1. --warmup 內部使用 async HTTP，在 QEMU 下不穩定
    #    2. --warmup 可能失敗但不報錯
    #    3. 我們需要完全可控的下載流程
    #
    # BabelDOC 翻譯服務使用外部 API（Google/DeepL/OpenAI）
    # 本地只需要字型和基礎資源，這些已透過 apt 安裝
    # ⬇️ Docker build 階段準備 BabelDOC 快取目錄
    #    runtime 使用 API 翻譯，不需要本地模型
    echo "" && \
    echo "📥 [2/5] 準備 BabelDOC 資源..." && \
    mkdir -p /root/.cache/babeldoc && \
    if command -v babeldoc >/dev/null 2>&1; then \
    echo "✅ BabelDOC 已安裝，翻譯將使用外部 API（Google/DeepL/OpenAI）"; \
    echo "   本地不需要下載翻譯模型"; \
    else \
    echo "⚠️ BabelDOC 未安裝，跳過"; \
    fi && \
    echo "✅ BabelDOC 步驟完成" && \
    \
    # ========================================
    # [3/5] PDFMathTranslate 多語言字型
    # ========================================
    # ⬇️ Docker build 階段下載 PDFMathTranslate 所需字型
    #    這些字型用於 PDF 翻譯時保持正確的文字渲染
    #    runtime 不會再下載此資源
    echo "" && \
    echo "📥 [3/5] 下載 PDFMathTranslate 多語言字型..." && \
    mkdir -p /app && \
    curl -fSL --retry 3 --retry-delay 5 -o /app/GoNotoKurrent-Regular.ttf \
    "https://github.com/satbyy/go-noto-universal/releases/download/v7.0/GoNotoKurrent-Regular.ttf" && \
    curl -fSL --retry 3 --retry-delay 5 -o /app/SourceHanSerifCN-Regular.ttf \
    "https://github.com/timelic/source-han-serif/releases/download/main/SourceHanSerifCN-Regular.ttf" && \
    curl -fSL --retry 3 --retry-delay 5 -o /app/SourceHanSerifTW-Regular.ttf \
    "https://github.com/timelic/source-han-serif/releases/download/main/SourceHanSerifTW-Regular.ttf" && \
    curl -fSL --retry 3 --retry-delay 5 -o /app/SourceHanSerifJP-Regular.ttf \
    "https://github.com/timelic/source-han-serif/releases/download/main/SourceHanSerifJP-Regular.ttf" && \
    curl -fSL --retry 3 --retry-delay 5 -o /app/SourceHanSerifKR-Regular.ttf \
    "https://github.com/timelic/source-han-serif/releases/download/main/SourceHanSerifKR-Regular.ttf" && \
    echo "✅ 字型下載完成" && \
    \
    # ========================================
    # [4/5] MinerU Pipeline 模型（顯式下載）
    # ========================================
    # ⬇️ Docker build 階段下載 MinerU Pipeline 模型
    #    包含：DocLayout-YOLO, YOLOv8 MFD, UniMERNet, PaddleOCR, LayoutReader, SLANet
    #    runtime 不會再下載任何資源
    echo "" && \
    echo "📥 [4/5] 下載 MinerU Pipeline 模型..." && \
    ARCH=$(uname -m) && \
    MINERU_MODELS_DIR="/models/mineru" && \
    mkdir -p "$MINERU_MODELS_DIR" && \
    if [ "$ARCH" = "aarch64" ]; then \
    echo "⚠️ ARM64 架構：MinerU 可能不完全支援，嘗試下載模型..."; \
    fi && \
    if command -v mineru >/dev/null 2>&1; then \
    echo "使用顯式 Python 腳本下載 MinerU 模型..."; \
    python3 -c " \
    import os, json; \
    os.environ['HF_HUB_DISABLE_PROGRESS_BARS'] = '0'; \
    from huggingface_hub import snapshot_download; \
    # PDF-Extract-Kit-1.0 Pipeline 模型
    models_dir = '/models/mineru'; \
    print('下載 PDF-Extract-Kit-1.0 模型...'); \
    try: \
    snapshot_download( \
    repo_id='opendatalab/PDF-Extract-Kit-1.0', \
    local_dir=os.path.join(models_dir, 'PDF-Extract-Kit-1.0'), \
    local_dir_use_symlinks=False \
    ); \
    print('✅ PDF-Extract-Kit-1.0 下載完成'); \
    except Exception as e: \
    print(f'⚠️ PDF-Extract-Kit-1.0 下載失敗: {e}'); \
    # 建立 mineru.json 設定檔
    config = { \
    'models-dir': { \
    'pipeline': os.path.join(models_dir, 'PDF-Extract-Kit-1.0'), \
    'vlm': '' \
    }, \
    'model-source': 'local', \
    'latex-delimiter-config': { \
    'display': {'left': '\$\$', 'right': '\$\$'}, \
    'inline': {'left': '\$', 'right': '\$'} \
    } \
    }; \
    with open('/root/mineru.json', 'w') as f: \
    json.dump(config, f, indent=2); \
    print('✅ mineru.json 已建立'); \
    " || echo "⚠️ MinerU 模型下載失敗，將在 runtime 時嘗試下載"; \
    else \
    echo "⚠️ mineru 命令不可用，跳過模型下載"; \
    echo '{"models-dir":{"pipeline":"","vlm":""},"model-source":"huggingface","latex-delimiter-config":{"display":{"left":"$$","right":"$$"},"inline":{"left":"$","right":"$"}}}' > /root/mineru.json; \
    fi && \
    echo "✅ MinerU 模型下載步驟完成" && \
    \
    # 🔥 再次清理 HuggingFace cache（MinerU 也會產生）
    rm -rf /root/.cache/huggingface && \
    \
    # ========================================
    # [5/5] 最終驗證
    # ========================================
    echo "" && \
    echo "📥 [5/5] 驗證模型完整性..." && \
    echo "" && \
    \
    # ========================================
    # 🔥 最終 Cache 清理（關鍵！避免 overlayfs diff 爆炸）
    # ========================================
    echo "===========================================================" && \
    echo "🧹 清理所有下載快取（降低 layer diff 大小）" && \
    echo "===========================================================" && \
    # HuggingFace Hub cache（最大宗！包含所有 blob）
    rm -rf /root/.cache/huggingface && \
    # pip / Python build cache
    rm -rf /root/.cache/pip && \
    rm -rf /root/.cache/uv && \
    # pipx cache
    rm -rf /root/.local/pipx/.cache && \
    # torch cache（可能由 MinerU 產生）
    rm -rf /root/.cache/torch && \
    # 通用 cache 目錄
    rm -rf /tmp/* && \
    rm -rf /var/tmp/* && \
    # Python bytecode cache（可選，節省少量空間）
    find /root/.local -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true && \
    find /usr -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true && \
    \
    echo "" && \
    echo "===========================================================" && \
    echo "📋 模型檔案驗證" && \
    echo "===========================================================" && \
    echo "" && \
    echo "🔹 PDFMathTranslate 模型：" && \
    ONNX_COUNT=$(find /models/pdfmathtranslate -name "*.onnx" 2>/dev/null | wc -l) && \
    if [ "$ONNX_COUNT" -gt 0 ]; then \
    echo "   ✅ 找到 $ONNX_COUNT 個 ONNX 模型："; \
    ls -lh /models/pdfmathtranslate/*.onnx 2>/dev/null || find /models/pdfmathtranslate -name "*.onnx" -exec ls -lh {} \;; \
    else \
    echo "   ❌ /models/pdfmathtranslate 中沒有 ONNX 模型"; \
    fi && \
    echo "" && \
    echo "🔹 PDFMathTranslate 字型：" && \
    ls -lh /app/*.ttf 2>/dev/null || echo "   ⚠️ 無字型檔案" && \
    echo "" && \
    echo "🔹 BabelDOC 狀態：" && \
    if command -v babeldoc >/dev/null 2>&1; then \
    echo "   ✅ BabelDOC 已安裝（使用外部 API 翻譯）"; \
    else \
    echo "   ⚠️ BabelDOC 未安裝"; \
    fi && \
    echo "" && \
    echo "🔹 MinerU 模型目錄：" && \
    if [ -d "/models/mineru/PDF-Extract-Kit-1.0" ]; then \
    echo "   ✅ MinerU Pipeline 模型已下載"; \
    du -sh /models/mineru/PDF-Extract-Kit-1.0 2>/dev/null || true; \
    else \
    echo "   ⚠️ MinerU 模型目錄不存在（可能需要 runtime 下載）"; \
    fi && \
    echo "" && \
    echo "🔹 mineru.json 設定：" && \
    if [ -f /root/mineru.json ]; then \
    cat /root/mineru.json; \
    else \
    echo "   ⚠️ mineru.json 不存在"; \
    fi && \
    echo "" && \
    echo "🔹 確認 HuggingFace cache 已清除：" && \
    if [ -d "/root/.cache/huggingface" ]; then \
    echo "   ❌ 警告：HuggingFace cache 仍存在！"; \
    du -sh /root/.cache/huggingface 2>/dev/null || true; \
    else \
    echo "   ✅ HuggingFace cache 已清除"; \
    fi && \
    echo "" && \
    echo "===========================================================" && \
    echo "✅ 模型下載完成，所有快取已清理" && \
    echo "==========================================================="

# ==============================================================================
# 環境變數設定
# ==============================================================================

# PDFMathTranslate 環境變數
ENV PDFMATHTRANSLATE_MODELS_PATH="/models/pdfmathtranslate"
ENV NOTO_FONT_PATH="/app/GoNotoKurrent-Regular.ttf"

# BabelDOC 環境變數
ENV BABELDOC_CACHE_PATH="/root/.cache/babeldoc"
ENV BABELDOC_SERVICE="google"

# MinerU 環境變數
# 強制使用本地模型，禁止 runtime 下載
ENV MINERU_MODELS_PATH="/models/mineru"

# HuggingFace 離線模式（禁止 runtime 下載）
# ⚠️ 這是 OFFLINE-FIRST 設計的核心
ENV HF_HUB_OFFLINE="1"
ENV TRANSFORMERS_OFFLINE="1"

# ==============================================================================
# 最終清理（模型下載完成後）
# ==============================================================================
RUN rm -rf /usr/share/doc/texlive* \
    && rm -rf /usr/share/texlive/texmf-dist/doc \
    && rm -rf /usr/share/doc/* \
    && rm -rf /usr/share/man/* \
    && rm -rf /usr/share/info/*

# ==============================================================================
# 設定 locale（支援中文 PDF 避免亂碼）
# ==============================================================================
RUN sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
    sed -i 's/# zh_TW.UTF-8 UTF-8/zh_TW.UTF-8 UTF-8/' /etc/locale.gen && \
    sed -i 's/# zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen && \
    sed -i 's/# ja_JP.UTF-8 UTF-8/ja_JP.UTF-8 UTF-8/' /etc/locale.gen && \
    sed -i 's/# ko_KR.UTF-8 UTF-8/ko_KR.UTF-8 UTF-8/' /etc/locale.gen && \
    sed -i 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/' /etc/locale.gen && \
    sed -i 's/# fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/' /etc/locale.gen && \
    locale-gen

# 預設使用 zh_TW.UTF-8 確保中文 PDF 正確顯示
ENV LANG=zh_TW.UTF-8
ENV LC_ALL=zh_TW.UTF-8

# ==============================================================================
# 安裝自訂字型（標楷體等台灣常用字型）
# ==============================================================================
RUN mkdir -p /usr/share/fonts/truetype/custom
COPY fonts/ /usr/share/fonts/truetype/custom/
RUN fc-cache -fv

# ==============================================================================
# Install VTracer binary（向量追蹤工具）
# ⬇️ Docker build 階段下載，runtime 不會再下載
# ==============================================================================
RUN ARCH=$(uname -m) && \
    if [ "$ARCH" = "aarch64" ]; then \
    VTRACER_ASSET="vtracer-aarch64-unknown-linux-musl.tar.gz"; \
    else \
    VTRACER_ASSET="vtracer-x86_64-unknown-linux-musl.tar.gz"; \
    fi && \
    curl -L --retry 3 --retry-delay 5 -o /tmp/vtracer.tar.gz "https://github.com/visioncortex/vtracer/releases/download/0.6.4/${VTRACER_ASSET}" && \
    tar -xzf /tmp/vtracer.tar.gz -C /tmp/ && \
    mv /tmp/vtracer /usr/local/bin/vtracer && \
    chmod +x /usr/local/bin/vtracer && \
    rm /tmp/vtracer.tar.gz

COPY --from=install /temp/prod/node_modules node_modules
COPY --from=prerelease /app/public/ /app/public/
COPY --from=prerelease /app/dist /app/dist

# 複製模型驗證腳本
COPY scripts/verify-models.sh /app/scripts/verify-models.sh
RUN chmod +x /app/scripts/verify-models.sh

RUN mkdir data

EXPOSE 3000/tcp

# ==============================================================================
# 環境變數
# ==============================================================================
# Calibre 需要
ENV QTWEBENGINE_CHROMIUM_FLAGS="--no-sandbox"
# Pandoc PDF 引擎（使用 pdflatex 以獲得最佳相容性）
ENV PANDOC_PDF_ENGINE=pdflatex
# Node 環境
ENV NODE_ENV=production
# PDFMathTranslate 預設翻譯服務（可透過環境變數覆寫）
ENV PDFMATHTRANSLATE_SERVICE="google"

ENTRYPOINT [ "bun", "run", "dist/src/index.js" ]
