# ============================================================
#  CoderFleet — 统一工作容器镜像
#  包含：Python 3.12 / Node.js 20 / Rust
#        Codex CLI / Claude Code / OpenCode / Hermes / Grok
#        FFmpeg / LibreOffice (headless) / Playwright + Chromium
#  平台：linux/amd64（Apple Silicon 通过 Docker 模拟运行）
# ============================================================

FROM --platform=linux/amd64 ubuntu:24.04

# 避免交互式安装询问
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai

# ── 基础系统工具 ──────────────────────────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
    # 网络工具
    curl wget ca-certificates netcat-openbsd \
    # 开发基础
    git build-essential pkg-config \
    # Python 依赖
    libssl-dev libffi-dev zlib1g-dev libbz2-dev \
    libreadline-dev libsqlite3-dev liblzma-dev \
    # 系统工具
    bash-completion less vim nano \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# ── Node.js 20 (via NodeSource) ───────────────────────────
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
    && apt-get install -y nodejs \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# 验证 Node 版本并安装常用全局包
RUN node --version && npm --version \
    && npm install -g npm@latest

# ── Python 3.12 (via deadsnakes PPA) ─────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
    software-properties-common \
    && add-apt-repository ppa:deadsnakes/ppa \
    && apt-get update && apt-get install -y --no-install-recommends \
    python3.12 python3.12-dev python3.12-venv python3-pip \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# 设置 python3.12 为默认 python3
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1 \
    && update-alternatives --install /usr/bin/python  python  /usr/bin/python3.12 1

# 安装常用 Python 工具
# Ubuntu 24.04 实行 PEP 668，系统 Python 需加 --break-system-packages
RUN pip3 install --no-cache-dir --break-system-packages \
    uv ruff black mypy pexpect

# ── Codex CLI ─────────────────────────────────────────────
RUN npm install -g @openai/codex

# ── Claude Code CLI ───────────────────────────────────────
RUN npm install -g @anthropic-ai/claude-code

# ── OpenCode CLI ──────────────────────────────────────────
RUN npm install -g opencode-ai@latest

# ── Hermes Agent ──────────────────────────────────────────
# ripgrep is required by hermes code-search tools
RUN apt-get update && apt-get install -y --no-install-recommends ripgrep \
    && apt-get clean && rm -rf /var/lib/apt/lists/*
# Install in an isolated venv to avoid conflicts with Debian-managed packages
# (e.g. PyJWT installed by apt has no RECORD file and cannot be uninstalled by pip)
RUN python3 -m venv /opt/hermes-venv \
    && /opt/hermes-venv/bin/pip install --no-cache-dir \
        hermes-agent \
        anthropic \
        openai \
        google-genai \
        mistralai \
    && ln -s /opt/hermes-venv/bin/hermes /usr/local/bin/hermes

# ── Grok Build CLI (xAI) ─────────────────────────────────
# install.sh 把真正的二进制下载到 ~/.grok/downloads/，然后在 ~/.grok/bin/ 建 symlink。
# GROK_BIN_DIR 只是加第三层 symlink，不改变二进制实际位置。
# 以 root 安装后 /root/.grok/ 权限为 700，byclaw 无法穿越 symlink 链访问二进制。
# 解决方案：用 cp -L 把实体二进制复制到 /usr/local/bin/，然后删掉整个 /root/.grok/。
RUN curl -fsSL https://x.ai/cli/install.sh | bash \
    && rm -f /usr/local/bin/grok /usr/local/bin/agent \
    && cp -L /root/.grok/bin/grok /usr/local/bin/grok \
    && chmod 755 /usr/local/bin/grok \
    && (cp -L /root/.grok/bin/agent /usr/local/bin/grok-agent && chmod 755 /usr/local/bin/grok-agent || true) \
    && rm -rf /root/.grok \
    && grok --version

# ── Rust 1.93.0 ───────────────────────────────────────────
ENV RUSTUP_HOME=/usr/local/rustup \
    CARGO_HOME=/usr/local/cargo \
    PATH=/usr/local/cargo/bin:$PATH \
    RUSTUP_DIST_SERVER=https://rsproxy.cn \
    RUSTUP_UPDATE_ROOT=https://rsproxy.cn/rustup
RUN curl --proto '=https' --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh | sh -s -- -y --no-modify-path --default-toolchain 1.93.0 \
    && chmod -R a+w $RUSTUP_HOME $CARGO_HOME \
    && rustc --version

# ── FFmpeg ────────────────────────────────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
    ffmpeg \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# ── LibreOffice（含中文字体与语言包）────────────────────
# 只装 Writer / Calc / Impress / Draw + headless 核心，跳过 Java / Base
RUN apt-get update && apt-get install -y --no-install-recommends \
    libreoffice-writer \
    libreoffice-calc \
    libreoffice-impress \
    libreoffice-draw \
    libreoffice-l10n-zh-cn \
    fonts-wqy-zenhei \
    fonts-noto-cjk \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# ── Playwright + Chromium ─────────────────────────────────
# 1. Python Playwright 包（同时提供 `playwright` CLI）
RUN pip3 install --no-cache-dir --break-system-packages playwright

# 2. 浏览器统一安装到全局共享路径，两种语言运行时共用，避免重复下载
ENV PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers

# 3. 安装 Chromium 系统依赖，再下载 Chromium 二进制
#    playwright install-deps 内部会调用 apt，需要 root
RUN playwright install-deps chromium \
    && playwright install chromium \
    && chmod -R a+rx /opt/playwright-browsers

# 4. Node.js Playwright（复用 PLAYWRIGHT_BROWSERS_PATH，无需重新下载浏览器）
RUN npm install -g playwright

# ── 创建非特权用户 byclaw ─────────────────────────────────
RUN groupadd -r byclaw && useradd -r -g byclaw -m -s /bin/bash byclaw \
    && chown -R byclaw:byclaw /opt/hermes-venv

# ── 工作目录和环境变量 ────────────────────────────────────
RUN mkdir -p /workspace && chown byclaw:byclaw /workspace
WORKDIR /workspace

# 这两个目录由 CoderFleet 按账号挂载，容器内路径固定
# Codex 认证：/home/byclaw/.codex   由 CODEX_HOME 控制
# Claude 认证：/home/byclaw/.claude  由 CLAUDE_CONFIG_DIR 控制
# OpenCode 数据：/home/byclaw/.opencode（运行时按账号挂载并设置 XDG_*_HOME）
ENV CODEX_HOME=/home/byclaw/.codex
ENV CLAUDE_CONFIG_DIR=/home/byclaw/.claude

# ── 启动脚本 ──────────────────────────────────────────────
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

COPY scripts/coderfleet_usage_status.py /usr/local/bin/coderfleet-usage-status
RUN chmod +x /usr/local/bin/coderfleet-usage-status

# ── 切换为非特权用户 ──────────────────────────────────────
USER byclaw

ENTRYPOINT ["/entrypoint.sh"]
CMD ["sleep", "infinity"]
