# ==============================================================================
# ConvertX-CN 官方 Docker Image
# 版本：v0.1.12
# ==============================================================================
#
# 📦 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: DocLayout-YOLO + 字型資源（顯式下載，無 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 設計原則：
#    - 所有下載行為僅發生在 Docker build 階段
#    - Runtime 完全離線運行，不依賴任何網路請求
#    - 禁止任何 CLI warmup / 隱性下載行為
#    - 所有 cache 在同一 RUN 內清除，避免 layer diff 膨脹
#
# ==============================================================================

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 - 精簡版檔案轉換服務"
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 下載二進位檔案）
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 需從源碼編譯或跳過
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
# 注意：Inkscape 1.0+ 使用 --export-type/--export-filename 語法，支援 headless 執行，不需要 xvfb
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/*

# ==============================================================================
# 🔥 階段 12-UNIFIED：Python 工具安裝 + 模型下載（單一 RUN 原則）
# ==============================================================================
#
# ⚠️ 關鍵設計原則：
#   1. 所有 pipx install 和模型下載必須在同一個 RUN 中完成
#   2. 所有 cache 在同一個 RUN 結尾清除
#   3. 禁止任何 CLI warmup / 隱性下載行為
#   4. 僅使用顯式 HuggingFace snapshot_download 下載模型
#
# ⬇️ 此 RUN 包含所有 Docker build 階段下載：
#   - Python 工具：markitdown, pdf2zh, babeldoc, mineru
#   - 模型：DocLayout-YOLO ONNX, MinerU Pipeline 模型
#   - 字型：GoNotoKurrent, Source Han Serif
#   - Runtime 不會再下載任何資源
#
# ==============================================================================
ENV PATH="/root/.local/bin:${PATH}"
ENV PIPX_HOME="/root/.local/pipx"
ENV PIPX_BIN_DIR="/root/.local/bin"
# 禁止 pip 隱性下載（強制離線模式在安裝完成後啟用）
ENV PIP_NO_CACHE_DIR=1
# HuggingFace 環境變數（安裝時允許下載，安裝完成後設為離線）
ENV HF_HOME="/root/.cache/huggingface"

RUN set -eux && \
  echo "===========================================================" && \
  echo "🚀 階段 12-UNIFIED：Python 工具 + 模型統一安裝" && \
  echo "===========================================================" && \
  echo "⬇️ 此 RUN 包含所有 Docker build 階段下載" && \
  echo "   Runtime 不會再下載任何資源" && \
  echo "===========================================================" && \
  \
  # ========================================
  # [1/8] 安裝 huggingface_hub（用於顯式模型下載）
  # ========================================
  echo "" && \
  echo "📦 [1/8] 安裝 huggingface_hub..." && \
  pip3 install --no-cache-dir --break-system-packages huggingface_hub && \
  \
  # ========================================
  # [2/8] 安裝 markitdown（文件轉換工具）
  # ⬇️ Docker build 階段安裝，無隱性下載
  # ========================================
  echo "" && \
  echo "📦 [2/8] 安裝 markitdown[all]..." && \
  pipx install "markitdown[all]" && \
  \
  # ========================================
  # [3/8] 安裝 pdf2zh（PDFMathTranslate 引擎）
  # ⬇️ Docker build 階段安裝
  # ⚠️ 模型將在後續步驟顯式下載，此處僅安裝程式
  # ========================================
  echo "" && \
  echo "📦 [3/8] 安裝 pdf2zh..." && \
  pipx install "pdf2zh" && \
  \
  # ========================================
  # [4/8] 安裝 babeldoc（BabelDOC 引擎）
  # ⬇️ Docker build 階段安裝
  # ⚠️ 資源將在後續步驟顯式下載，禁止使用 --warmup
  # ========================================
  echo "" && \
  echo "📦 [4/8] 安裝 babeldoc..." && \
  (pipx install "babeldoc" || echo "⚠️ babeldoc 安裝失敗，跳過...") && \
  \
  # ========================================
  # [5/8] 安裝 mineru（MinerU 引擎）
  # ⬇️ Docker build 階段安裝
  # ⚠️ 模型將在後續步驟顯式下載，此處僅安裝程式
  # ========================================
  echo "" && \
  echo "📦 [5/8] 安裝 mineru[all]..." && \
  (pipx install "mineru[all]" || echo "⚠️ mineru 安裝失敗（可能是 arm64 相容性問題），跳過...") && \
  \
  # ========================================
  # [6/8] 顯式下載 PDFMathTranslate/BabelDOC ONNX 模型
  # ⬇️ Docker build 階段下載 DocLayout-YOLO ONNX 模型
  #    必須放到 /root/.cache/babeldoc/models/ 目錄
  #    因為 pdf2zh 使用 babeldoc.assets.get_doclayout_onnx_model_path()
  #    Runtime 不會再下載任何資源
  # ========================================
  echo "" && \
  echo "📥 [6/8] 下載 PDFMathTranslate/BabelDOC DocLayout-YOLO ONNX 模型..." && \
  mkdir -p /root/.cache/babeldoc/models && \
  # 直接下載 ONNX 模型到 babeldoc 期望的路徑
  curl -fSL -o /root/.cache/babeldoc/models/doclayout_yolo_docstructbench_imgsz1024.onnx \
    "https://huggingface.co/wybxc/DocLayout-YOLO-DocStructBench-onnx/resolve/main/doclayout_yolo_docstructbench_imgsz1024.onnx" && \
  echo "✅ ONNX 模型下載完成" && \
  ls -lh /root/.cache/babeldoc/models/*.onnx && \
  \
  # ========================================
  # [6.1/8] 下載 PDFMathTranslate 多語言字型
  # ⬇️ Docker build 階段下載字型檔案
  #    Runtime 不會再下載任何資源
  # ========================================
  echo "" && \
  echo "📥 [6.1/8] 下載 PDFMathTranslate 多語言字型..." && \
  mkdir -p /app && \
  curl -fSL -o /app/GoNotoKurrent-Regular.ttf \
  "https://github.com/satbyy/go-noto-universal/releases/download/v7.0/GoNotoKurrent-Regular.ttf" && \
  curl -fSL -o /app/SourceHanSerifCN-Regular.ttf \
  "https://github.com/timelic/source-han-serif/releases/download/main/SourceHanSerifCN-Regular.ttf" && \
  curl -fSL -o /app/SourceHanSerifTW-Regular.ttf \
  "https://github.com/timelic/source-han-serif/releases/download/main/SourceHanSerifTW-Regular.ttf" && \
  curl -fSL -o /app/SourceHanSerifJP-Regular.ttf \
  "https://github.com/timelic/source-han-serif/releases/download/main/SourceHanSerifJP-Regular.ttf" && \
  curl -fSL -o /app/SourceHanSerifKR-Regular.ttf \
  "https://github.com/timelic/source-han-serif/releases/download/main/SourceHanSerifKR-Regular.ttf" && \
  echo "✅ 字型下載完成" && \
  ls -lh /app/*.ttf && \
  \
  # ========================================
  # [7/8] 準備 BabelDOC 資源
  # ⬇️ 複製字型到 BabelDOC cache 目錄
  #    ONNX 模型已在 [6/8] 下載完成
  #    Runtime 不會再下載任何資源
  # ========================================
  echo "" && \
  echo "📥 [7/8] 準備 BabelDOC 資源..." && \
  mkdir -p /root/.cache/babeldoc/fonts && \
  mkdir -p /root/.cache/babeldoc/cmap && \
  mkdir -p /root/.cache/babeldoc/tiktoken && \
  \
  # 複製字型到 BabelDOC 目錄（避免 runtime 下載）
  echo "   複製字型到 BabelDOC 目錄..." && \
  cp /app/GoNotoKurrent-Regular.ttf /root/.cache/babeldoc/fonts/ 2>/dev/null || true && \
  cp /app/SourceHanSerifCN-Regular.ttf /root/.cache/babeldoc/fonts/ 2>/dev/null || true && \
  cp /app/SourceHanSerifTW-Regular.ttf /root/.cache/babeldoc/fonts/ 2>/dev/null || true && \
  cp /app/SourceHanSerifJP-Regular.ttf /root/.cache/babeldoc/fonts/ 2>/dev/null || true && \
  cp /app/SourceHanSerifKR-Regular.ttf /root/.cache/babeldoc/fonts/ 2>/dev/null || true && \
  \
  # 下載 BabelDOC 需要的額外資源（如果有的話）
  echo "   下載 BabelDOC 額外資源..." && \
  (python3 -c "from huggingface_hub import snapshot_download; import os; os.environ['HF_HOME']='/root/.cache/huggingface'; snapshot_download(repo_id='funstory-ai/babeldoc-assets', local_dir='/root/.cache/babeldoc/assets', local_dir_use_symlinks=False); print('BabelDOC assets downloaded')" || echo "BabelDOC assets not available, skipping...") && \
  \
  # 驗證模型已正確下載
  echo "   驗證 BabelDOC 模型..." && \
  ls -lh /root/.cache/babeldoc/models/ && \
  echo "✅ BabelDOC 資源準備完成" && \
  \
  # ========================================
  # [8/8] 顯式下載 MinerU Pipeline 模型
  # ⬇️ Docker build 階段顯式下載 MinerU 所需模型
  #    使用 mineru-models-download CLI（如果可用）
  #    或使用 HuggingFace 顯式下載
  #    Runtime 不會再下載任何資源
  # ========================================
  echo "" && \
  echo "📥 [8/8] 下載 MinerU Pipeline 模型..." && \
  ARCH=$(uname -m) && \
  if [ "$ARCH" = "aarch64" ]; then \
  echo "⚠️ ARM64 架構：MinerU 可能不完全支援，嘗試下載模型..."; \
  fi && \
  \
  # 方法 1：使用官方 CLI（如果可用）
  if command -v mineru-models-download >/dev/null 2>&1; then \
  echo "使用 mineru-models-download CLI..." && \
  mineru-models-download -s huggingface -m pipeline 2>&1 || true && \
  echo "mineru.json 內容：" && \
  cat /root/mineru.json 2>/dev/null || echo "(未生成)"; \
  else \
  echo "mineru-models-download 不可用，使用顯式 HuggingFace 下載..." && \
  mkdir -p /root/.cache/mineru/models && \
  (python3 -c "from huggingface_hub import snapshot_download; import os; os.environ['HF_HOME']='/root/.cache/huggingface'; snapshot_download(repo_id='opendatalab/PDF-Extract-Kit-1.0', local_dir='/root/.cache/mineru/models/PDF-Extract-Kit-1.0', local_dir_use_symlinks=False); print('PDF-Extract-Kit-1.0 downloaded')" || echo "MinerU model download failed") && \
  python3 -c "import json; config={'models-dir':{'pipeline':'/root/.cache/mineru/models/PDF-Extract-Kit-1.0','vlm':''},'model-source':'local','latex-delimiter-config':{'display':{'left':'@@','right':'@@'},'inline':{'left':'@','right':'@'}}}; f=open('/root/mineru.json','w'); json.dump(config,f,indent=2); f.close(); print('mineru.json generated')"; \
  fi && \
  echo "✅ MinerU 模型下載步驟完成" && \
  \
  # ========================================
  # 🔥 最終 Cache 清理（關鍵！避免 overlayfs diff 爆炸）
  # ========================================
  # ⚠️ 此清理必須在同一個 RUN 內執行
  #    否則 cache 會進入 layer diff，導致 image 膨脹
  # ========================================
  echo "" && \
  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 && \
  \
  # 通用 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 [ -d "/root/.cache/babeldoc" ]; then \
  echo "   ✅ BabelDOC 資源目錄存在"; \
  du -sh /root/.cache/babeldoc 2>/dev/null || true; \
  ls -la /root/.cache/babeldoc/ 2>/dev/null || true; \
  else \
  echo "   ⚠️ BabelDOC 資源目錄不存在"; \
  fi && \
  echo "" && \
  \
  echo "🔹 MinerU 模型目錄：" && \
  if [ -f /root/mineru.json ]; then \
  echo "   ✅ mineru.json 存在"; \
  cat /root/mineru.json; \
  MINERU_PIPELINE_DIR=$(python3 -c "import json; f=open('/root/mineru.json'); d=json.load(f); print(d.get('models-dir',{}).get('pipeline',''))" 2>/dev/null || echo ""); \
  if [ -n "$MINERU_PIPELINE_DIR" ] && [ -d "$MINERU_PIPELINE_DIR" ]; then \
  echo "   ✅ MinerU Pipeline 模型目錄存在: $MINERU_PIPELINE_DIR"; \
  du -sh "$MINERU_PIPELINE_DIR" 2>/dev/null || true; \
  else \
  echo "   ⚠️ MinerU Pipeline 模型目錄不存在或未設定"; \
  fi; \
  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 "✅ 階段 12-UNIFIED 完成：所有 Python 工具 + 模型已安裝" && \
  echo "   所有 cache 已清理，layer diff 最小化" && \
  echo "   Runtime 不會再下載任何資源" && \
  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"
# 禁止 BabelDOC 自動下載（強制使用預下載資源）
ENV BABELDOC_OFFLINE="1"

# MinerU 環境變數
# 強制使用本地模型，禁止 runtime 下載
ENV MINERU_MODEL_SOURCE="local"

# HuggingFace 離線模式（禁止 runtime 下載）
# ⚠️ 此變數在所有模型下載完成後設定
ENV HF_HUB_OFFLINE="1"
ENV TRANSFORMERS_OFFLINE="1"

# ==============================================================================
# 最終清理（模型下載完成後）
# ==============================================================================
# ⚠️ 此清理步驟獨立於模型下載 RUN，僅清理文件檔案
#    模型相關 cache 已在上一個 RUN 中清除
# ==============================================================================
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（向量追蹤工具）
# ==============================================================================
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 -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 翻譯服務設定
# ==============================================================================
# ⚠️ 重要：PDFMathTranslate 的翻譯功能需要網路連接！
#    - DocLayout-YOLO ONNX 模型（已離線預下載）：用於佈局分析
#    - 翻譯服務（需要網路）：將文字翻譯成目標語言
#
# 支援的翻譯服務：
#   - google: Google Translate（免費，需網路）
#   - bing: Microsoft Bing Translator（免費，需網路）
#   - deepl: DeepL（需 API Key，需網路）
#   - ollama: 本地 Ollama LLM（可離線，需額外設定）
#
# 若要完全離線翻譯，請使用 ollama 並設定 OLLAMA_HOST
# ==============================================================================
ENV PDFMATHTRANSLATE_SERVICE="google"

# ==============================================================================
# 🔒 Runtime 模型離線模式設定
# ==============================================================================
# ⚠️ 這些設定禁止 runtime 下載「模型」，但不影響翻譯 API 調用
#    PDFMathTranslate 使用的 Google/Bing 翻譯是線上 API，不是模型下載
# ==============================================================================

# HuggingFace 模型離線（禁止下載新模型）
ENV HF_HUB_OFFLINE="1"
ENV TRANSFORMERS_OFFLINE="1"
ENV HF_DATASETS_OFFLINE="1"

# 禁止 pip 安裝新套件
ENV PIP_NO_INDEX="1"

# MinerU 強制使用本地模型
ENV MINERU_MODEL_SOURCE="local"

# BabelDOC 模型離線模式
ENV BABELDOC_OFFLINE="1"

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