FROM golang:1.22.7-alpine3.20 AS builder

RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash

COPY ./go.mod /app/go.mod
COPY ./go.sum /app/go.sum

WORKDIR /app

RUN echo "go mod cache: $(go env GOMODCACHE)"
RUN echo "go build cache: $(go env GOCACHE)"

RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build go mod download

COPY . /app

# We avoid copying the full .git dir into the build for just some metadata.
# Instead, specify:
# --build-arg GIT_COMMIT=$(git rev-parse HEAD)
# --build-arg GIT_DATE=$(git show -s --format='%ct')
ARG GIT_COMMIT
ARG GIT_DATE

ARG CANNON_VERSION=v0.0.0
ARG OP_PROGRAM_VERSION=v0.0.0

ARG TARGETOS TARGETARCH

# Build the cannon and op-program-client.elf binaries.
RUN --mount=type=cache,target=/root/.cache/go-build cd cannon && make cannon  \
  GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$CANNON_VERSION"
RUN --mount=type=cache,target=/root/.cache/go-build cd op-program && make op-program-client-mips  \
  GOOS=linux GOARCH=mips GOMIPS=softfloat GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_PROGRAM_VERSION"

# Run the op-program-client.elf binary directly through cannon's load-elf subcommand.
RUN /app/cannon/bin/cannon load-elf --type singlethreaded-2 --path /app/op-program/bin/op-program-client.elf --out /app/op-program/bin/prestate.bin.gz --meta "/app/op-program/bin/meta.json"
RUN /app/cannon/bin/cannon load-elf --type multithreaded --path /app/op-program/bin/op-program-client.elf --out /app/op-program/bin/prestate-mt.bin.gz --meta "/app/op-program/bin/meta-mt.json"
RUN /app/cannon/bin/cannon load-elf --type multithreaded64-2 --path /app/op-program/bin/op-program-client64.elf --out /app/op-program/bin/prestate-mt64.bin.gz --meta "/app/op-program/bin/meta-mt64.json"

# Generate the prestate proof containing the absolute pre-state hash.
RUN /app/cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input /app/op-program/bin/prestate.bin.gz --meta "" --proof-fmt '/app/op-program/bin/%d.json' --output ""
RUN mv /app/op-program/bin/0.json /app/op-program/bin/prestate-proof.json

RUN /app/cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input /app/op-program/bin/prestate-mt.bin.gz --meta "" --proof-fmt '/app/op-program/bin/%d-mt.json' --output ""
RUN mv /app/op-program/bin/0-mt.json /app/op-program/bin/prestate-proof-mt.json

RUN /app/cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input /app/op-program/bin/prestate-mt64.bin.gz --meta "" --proof-fmt '/app/op-program/bin/%d-mt64.json' --output ""
RUN mv /app/op-program/bin/0-mt64.json /app/op-program/bin/prestate-proof-mt64.json

# Exports files to the specified output location.
# Writing files to host requires buildkit to be enabled.
# e.g. `BUILDKIT=1 docker build ...`
FROM scratch AS export-stage-proofs
COPY --from=builder /app/op-program/bin/prestate-proof.json .
COPY --from=builder /app/op-program/bin/prestate-proof-mt.json .
COPY --from=builder /app/op-program/bin/prestate-proof-mt64.json .

FROM scratch AS export-stage
COPY --from=builder /app/op-program/bin/op-program-client.elf .
COPY --from=builder /app/op-program/bin/op-program-client64.elf .
COPY --from=builder /app/op-program/bin/meta.json .
COPY --from=builder /app/op-program/bin/prestate.bin.gz .
COPY --from=builder /app/op-program/bin/prestate-proof.json .
COPY --from=builder /app/op-program/bin/meta-mt.json .
COPY --from=builder /app/op-program/bin/prestate-mt.bin.gz .
COPY --from=builder /app/op-program/bin/prestate-proof-mt.json .
COPY --from=builder /app/op-program/bin/meta-mt64.json .
COPY --from=builder /app/op-program/bin/prestate-mt64.bin.gz .
COPY --from=builder /app/op-program/bin/prestate-proof-mt64.json .
