FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim

# Install Node.js 20 for script execution
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl ca-certificates gnupg git bubblewrap openssh-client && \
    mkdir -p /etc/apt/keyrings && \
    curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
    echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" > /etc/apt/sources.list.d/nodesource.list && \
    apt-get update && \
    apt-get install -y --no-install-recommends nodejs && \
    apt-get purge -y gnupg && \
    apt-get autoremove -y && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Install Python dependencies first (cached layer)
COPY pyproject.toml README.md LICENSE ./
RUN mkdir -p facio && touch facio/__init__.py && \
    uv pip install --system --no-cache ".[api,discord,langsmith,pdf,docs,browser]" && \
    rm -rf facio

# Copy the full source and install
COPY facio/ facio/
RUN uv pip install --system --no-cache ".[api,discord,langsmith,pdf,docs,browser]"

# Browser-automation runtime (Camoufox/Firefox stealth + system deps).
# Chromium is intentionally NOT installed to keep the image small; pull it
# at runtime with ``playwright install chromium`` when tools.browser.backend
# is set to "playwright".
#
# We also install Xvfb + Mesa software-rasterizer so Camoufox can run with
# ``headless="virtual"``: this gives Firefox a virtual display in which a
# real WebGL context can be created (required to defeat bot-detection
# probes that flag missing WebGL contexts).
RUN apt-get update && \
    PLAYWRIGHT_BROWSERS_PATH=/opt/pw-browsers playwright install --with-deps firefox && \
    apt-get install -y --no-install-recommends \
        libx11-xcb1 libxcb1 libx11-6 libxcursor1 libxi6 libxrender1 \
        libxss1 libxshmfence1 libdbus-glib-1-2 libxt6 fonts-liberation \
        xvfb libgl1-mesa-dri libegl1-mesa libgles2-mesa libglu1-mesa \
        libglx-mesa0 mesa-utils && \
    apt-get autoremove -y && \
    rm -rf /var/lib/apt/lists/*

# Create non-root user and config directory. Also make the standard Python
# site-packages and global-install dirs writable by facio, so `pip install X`
# and `npm install -g X` work like on a normal dev box — no --user flags,
# no PYTHONUSERBASE gymnastics, and the installed packages are immediately
# importable via the default sys.path.
RUN useradd -m -u 1000 -s /bin/bash facio && \
    mkdir -p /home/facio/.facio /usr/lib/node_modules /opt/pw-browsers && \
    chown -R facio:facio /home/facio /app \
        /usr/local/lib/python3.12/site-packages \
        /usr/local/bin \
        /usr/lib/node_modules \
        /opt/pw-browsers

COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN sed -i 's/\r$//' /usr/local/bin/entrypoint.sh && chmod +x /usr/local/bin/entrypoint.sh

USER facio
ENV HOME=/home/facio
ENV PLAYWRIGHT_BROWSERS_PATH=/opt/pw-browsers

# Pre-fetch Camoufox as the same non-root user that runs facio. Camoufox
# resolves its binary path via the user's cache directory, so fetching as root
# would still force a first-use download under /home/facio at runtime.
RUN python -m camoufox fetch

# Gateway default port
EXPOSE 18790

ENTRYPOINT ["entrypoint.sh"]
CMD ["status"]
