FROM node:26-trixie AS base

ARG TZ
ARG NPM_VERSION
ENV TZ="$TZ"

# Install basic development tools and iptables/ipset
RUN apt-get update && apt-get install -y --no-install-recommends \
  ca-certificates \
  curl \
  less \
  git \
  procps \
  sudo \
  fzf \
  man-db \
  unzip \
  gnupg2 \
  gh \
  iptables \
  ipset \
  iproute2 \
  iputils-ping \
  dnsutils \
  telnet \
  aggregate \
  jq \
  nano \
  vim \
  wget \
  locales \
  rsync \
  ripgrep \
  strace \
  tini \
  && sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \
  && locale-gen \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* \
  && update-ca-certificates

# Hook: root-level customization (e.g. additional apt packages, system configuration)
COPY hooks/base-root.sh /tmp/hook-base-root.sh
RUN if [ -s /tmp/hook-base-root.sh ]; then bash /tmp/hook-base-root.sh; fi \
    && rm -f /tmp/hook-base-root.sh

ENV LANG=en_US.UTF-8 \
    LC_ALL=en_US.UTF-8

# Ensure default node user has access to /usr/local/share
RUN mkdir -p /usr/local/share/npm-global && \
  chown -R node:node /usr/local/share

ARG USERNAME=node

# Persist bash history.
RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
  && mkdir /commandhistory \
  && touch /commandhistory/.bash_history \
  && chown -R $USERNAME /commandhistory

# Set `DEVCONTAINER` environment variable to help with orientation
ENV DEVCONTAINER=true

# Create workspace and config directories and set permissions
RUN mkdir -p /workspace /home/node/.claude && \
  chown -R node:node /workspace /home/node/.claude

WORKDIR /workspace

# Set up non-root user
USER node

# Install global packages
ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global
ENV UV_PROJECT_ENVIRONMENT=/usr/local/share/venv
ENV UV_LINK_MODE=copy
ENV PATH=${NPM_CONFIG_PREFIX}/bin:${UV_PROJECT_ENVIRONMENT}/bin:${PATH}

RUN npm install -g npm@${NPM_VERSION}

ENV SHELL=/bin/bash

# Set the default editor and visual
ENV EDITOR=nano
ENV VISUAL=nano

# Copy and set up firewall and CA cert scripts
COPY init-firewall.sh install-ca-certs.sh setup-claude-mem.sh /usr/local/bin/
COPY docker-entrypoint.sh /
USER root
RUN chmod +x /usr/local/bin/init-firewall.sh /usr/local/bin/install-ca-certs.sh /usr/local/bin/setup-claude-mem.sh && \
  { \
    echo 'Defaults env_keep += "AGENT_TYPE"'; \
    echo 'Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"'; \
    echo 'node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh'; \
    echo 'node ALL=(root) NOPASSWD: /usr/local/bin/install-ca-certs.sh'; \
  } > /etc/sudoers.d/node-firewall && \
  chmod 0440 /etc/sudoers.d/node-firewall

# install additional tools
COPY --from=ghcr.io/astral-sh/uv:0.12.13 /uv /uvx /usr/local/bin/
RUN curl -L https://github.com/mikefarah/yq/releases/download/v4.53.6/yq_linux_amd64 -o /usr/local/bin/yq \
    && chmod a+x /usr/local/bin/yq

# Hook: user-level customization (e.g. npm packages, uv/pip tools)
USER node
COPY --chown=node:node hooks/base-user.sh /tmp/hook-base-user.sh
RUN if [ -s /tmp/hook-base-user.sh ]; then bash /tmp/hook-base-user.sh; fi \
    && rm -f /tmp/hook-base-user.sh

ENTRYPOINT [ "/usr/bin/tini", "--", "/docker-entrypoint.sh" ]
CMD [ "sleep", "infinity" ]

FROM base AS claude-code

ARG CLAUDE_CODE_VERSION
ARG CLAUDE_AGENT_ACP_VERSION
ARG BUN_VERSION
ARG CLAUDE_MEM_VERSION

RUN npm install -g --allow-scripts=@anthropic-ai/claude-code,bun \
    @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION} \
    @agentclientprotocol/claude-agent-acp@${CLAUDE_AGENT_ACP_VERSION} \
    bun@${BUN_VERSION} \
    claude-mem@${CLAUDE_MEM_VERSION}

FROM base AS codex

ARG CODEX_VERSION
ARG CODEX_ACP_VERSION

RUN npm install -g \
    @openai/codex@${CODEX_VERSION} \
    @agentclientprotocol/codex-acp@${CODEX_ACP_VERSION}

FROM base AS opencode

ARG OPENCODE_VERSION

RUN npm install -g --allow-scripts=opencode-ai \
    opencode-ai@${OPENCODE_VERSION}

FROM base AS mistral-vibe

ENV UV_LINK_MODE=copy \
    UV_COMPILE_BYTECODE=1 \
    UV_PROJECT_ENVIRONMENT=/app \
    PATH=/app/bin:${PATH}

USER root

RUN --mount=type=cache,target=/root/.cache \
    --mount=type=bind,source=uv.lock,target=uv.lock \
    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
    UV_PYTHON_INSTALL_DIR=/usr/local/share/uv/python uv sync \
        --python 3.14 \
        --locked \
        --no-dev \
        --no-install-project

ENV UV_PYTHON=/app/bin/python

USER node
