# syntax=docker/dockerfile:1
#
# The mm sandbox template: Docker Sandboxes' `shell` image with mm installed.
#
# Build it from the REPOSITORY ROOT (the context is the mm sources), or run
# docker-sbx-v3/build.sh, which does exactly that and stamps mm's tag — the
# image tag is that tag without the "v", k33g/mm-sandbox:0.0.2 for v0.0.2:
#
#     docker build -f docker-sbx-v3/template/Dockerfile \
#         --build-arg MM_VERSION=v0.0.2 -t k33g/mm-sandbox:0.0.2 .
#
# The two v3 kits under docker-sbx-v3/kits/ are thin workloads built FROM this
# image: each one sets its own ENTRYPOINT (mm-tui, mm-acp-info), which the
# sandbox runtime reads as the agent's launch command (sbx@1). ENTRYPOINT and
# CMD are therefore deliberately not set here: the template stays agnostic.

ARG GO_VERSION=1.26
ARG SHELL_TEMPLATE=docker/sandbox-templates:shell

# ---- build stage: cross-compile mm for the target platform -----------------
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-bookworm AS build
ARG TARGETOS
ARG TARGETARCH
# What `mm --version` reports: the tag, as 02-build-releases.sh stamps it.
ARG MM_VERSION=dev

WORKDIR /src
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod go mod download
COPY . .
# Same flags as 02-build-releases.sh: no C, no local paths, no symbols, the
# version stamped into internal/version.
RUN --mount=type=cache,target=/go/pkg/mod \
    --mount=type=cache,target=/root/.cache/go-build \
    CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
    go build -trimpath -ldflags "-s -w -X mm/internal/version.stamped=${MM_VERSION}" -o /out/mm .

# ---- template: the shell sandbox plus mm -----------------------------------
FROM ${SHELL_TEMPLATE}

COPY --from=build --chmod=0755 /out/mm /usr/local/bin/mm
# The two kit entry points. mm-tui runs `mm -tui "$@"`; mm-acp-info prints how
# an editor reaches this sandbox and opens a shell (see docker-sbx-v3/README.md).
COPY --chmod=0755 docker-sbx-v3/template/mm-tui docker-sbx-v3/template/mm-acp-info /usr/local/bin/

# tcell (the window mode) needs a terminal type and a UTF-8 locale; the kits
# set them too, this is the fallback for a plain `docker run`.
ENV TERM=xterm-256color \
    COLORTERM=truecolor \
    LANG=C.UTF-8

# The pinned toolchains (/usr/local/go/bin, /usr/local/node/bin) must come
# before /usr/bin so they win over any Go or Node the base image ships.
ENV PATH=/usr/local/go/bin:/usr/local/node/bin:/home/agent/go/bin:$PATH

# Without this, a go.mod whose `go` directive is newer than GO_VERSION makes the
# toolchain download and run a different Go, silently defeating the pin.
ENV GOTOOLCHAIN=local

# ------------------------------------
# Shared curl options for every download below.
#
# ARG, not ENV: this is build-time only and must not leak into the image.
# ------------------------------------
ARG CURL_RETRY="--retry 5 --retry-all-errors --retry-delay 3 --connect-timeout 15"

USER root

# ------------------------------------
# Install Go toolchain and Node.js
# ------------------------------------
ARG GO_VERSION=1.26.0
ARG NODE_VERSION=24.21.0
ARG TARGETARCH

RUN <<EOF
set -eux
apt-get update
apt-get install -y curl build-essential xz-utils
rm -rf /var/lib/apt/lists/*
EOF

RUN <<EOF
set -eux
apt-get remove -y golang-go golang-doc
apt-get autoremove -y
curl ${CURL_RETRY} -C - -fsSL -o /tmp/go.tgz "https://go.dev/dl/go${GO_VERSION}.linux-${TARGETARCH}.tar.gz"
rm -rf /usr/local/go
tar -C /usr/local -xzf /tmp/go.tgz
rm /tmp/go.tgz
/usr/local/go/bin/go version
EOF

RUN <<EOF
set -eux
case "${TARGETARCH}" in
  amd64) node_arch=x64 ;;
  arm64) node_arch=arm64 ;;
  *) echo "unsupported TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;;
esac
curl ${CURL_RETRY} -C - -fsSL -o /tmp/node.tar.xz "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz"
rm -rf /usr/local/node
mkdir -p /usr/local/node
tar -C /usr/local/node --strip-components=1 -xJf /tmp/node.tar.xz
rm /tmp/node.tar.xz
/usr/local/node/bin/node --version
/usr/local/node/bin/npm --version
EOF

# ------------------------------------
# Persist the Go and Node environment for sandbox shells.
# /etc/sandbox-persistent.sh is sourced before every bash command in the sbx.
# ------------------------------------
RUN <<EOF
{
  echo 'export PATH=/usr/local/go/bin:/usr/local/node/bin:/home/agent/go/bin:$PATH'
  echo 'export GOTOOLCHAIN=local'
} >> /etc/sandbox-persistent.sh
EOF

# Switch to agent user for Go tools installation (they go to /home/agent/go/bin)
USER agent

# ------------------------------------
# Install Go developer tools
# ------------------------------------
ARG GOPLS_VERSION=v0.23.0
ARG X_TOOLS_VERSION=v0.49.0
ARG STATICCHECK_VERSION=v0.7.0

# Retried: parallel multi-arch builds occasionally hit DNS timeouts on
# Docker Desktop's resolver. The module cache survives within this RUN,
# so a retry only fetches what's still missing.
RUN for i in 1 2 3 4 5; do \
      go install golang.org/x/tools/gopls@${GOPLS_VERSION} \
      && go install golang.org/x/tools/cmd/goimports@${X_TOOLS_VERSION} \
      && go install honnef.co/go/tools/cmd/staticcheck@${STATICCHECK_VERSION} \
      && exit 0; \
      echo "go install failed (attempt $i), retrying..." >&2; sleep $((i * 5)); \
    done; exit 1

# Prove the binary runs on this platform before the image is tagged.
RUN mm --version && mm-tui --version
