# syntax=docker/dockerfile:1

FROM debian:13.3-slim AS mise

SHELL ["/bin/bash", "-euo", "pipefail", "-c"]

ENV MISE_DATA_DIR="/mise"
ENV MISE_CACHE_DIR="/mise/cache"
ENV MISE_INSTALL_PATH="/usr/local/bin/mise"
ENV MISE_NODE_COREPACK=1
ENV PATH="/mise/shims:$PATH"

COPY .config/mise /etc/mise

RUN --mount=type=secret,id=GITHUB_TOKEN,env=GITHUB_TOKEN \
    apt-get update && \
    apt-get install -y --no-install-recommends curl ca-certificates && \
    # renovate: datasource=github-releases depName=jdx/mise
    export MISE_VERSION=2026.7.14 MISE_INSTALL_EXT=tar.gz && curl https://mise.run | sh && \
    mise --version && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    eval "$(mise activate bash)" && \
    mise install --locked node


FROM mise AS base

WORKDIR /app

RUN --mount=type=secret,id=GITHUB_TOKEN,env=GITHUB_TOKEN \
    mise install --locked npm:turbo yq

COPY . .
# `turbo prune` does not include Cargo workspaces, so we create dummy projects for each workspace member
RUN mise trust && \
    turbo prune --scope='@apps/hash-graph' --docker && \
    find $(yq '.workspace.members' -o tsv Cargo.toml | tr '*' ' ') -maxdepth 2 -name Cargo.toml -exec sh -c ' \
    [ -f "/app/out/full/$1" ] || ( \
    mkdir -p "/app/out/full/$(dirname "$1")/src" &&  \
    echo > "/app/out/full/$(dirname "$1")/src/lib.rs" &&  \
    printf "[package]\nname = \"$(yq ".package.name" -p toml -oy $1)\"" > "/app/out/full/$1" \
    )' _ {} \; && \
    cp -R .cargo Cargo.toml Cargo.lock /app/out/full/


FROM mise AS rust

WORKDIR /usr/local/

ENV MISE_CARGO_HOME="/usr/local/cargo" \
    PATH="$PATH:/usr/local/cargo/bin"

COPY rust-toolchain.toml .
RUN --mount=type=secret,id=GITHUB_TOKEN,env=GITHUB_TOKEN \
    mise install --locked yq && \
    echo "Installing Rust toolchain: $(yq '.toolchain.channel' rust-toolchain.toml)" && \
    mise use --global rust[profile=minimal]@$(yq '.toolchain.channel' rust-toolchain.toml) && \
    echo "Rust installation completed. Checking versions:" && \
    mise list rust && \
    rustc --version && \
    cargo --version && \
    rm rust-toolchain.toml


FROM rust AS builder

WORKDIR /usr/local/src/

# Install system packages and tools before copying the JS dependency manifests
# so this layer stays cached across dependency changes and tools are not
# re-downloaded from upstream sources on every dependency bump.
RUN --mount=type=secret,id=GITHUB_TOKEN,env=GITHUB_TOKEN \
    apt-get update && \
    apt-get install -y --no-install-recommends build-essential musl-tools && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    mise install --locked node npm:turbo protoc

COPY --from=base /app/out/json/ .
COPY --from=base /app/out/yarn.lock ./yarn.lock
COPY --from=base /app/out/full/.yarn .yarn
COPY --from=base /app/out/full/turbo.json turbo.json

RUN --mount=type=secret,id=GITHUB_TOKEN,env=GITHUB_TOKEN \
    yarn install --immutable && \
    yarn cache clean

COPY --from=base /app/out/full/ .

ARG PROFILE=production

RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \
    --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \
    --mount=type=cache,target=/usr/local/src/target,sharing=locked \
    if [[ ${PROFILE} == dev ]]; then \
    export RUSTFLAGS="-C debuginfo=line-tables-only" && \
    export PROFILE=dev-llvm; \
    fi && \
    rustup target add "$(uname -m)-unknown-linux-musl" && \
    cargo install --target "$(uname -m)-unknown-linux-musl" --path apps/hash-graph --root /tmp --profile $PROFILE --locked && \
    mkdir -p /out/etc/ssl/certs && \
    cp /tmp/bin/hash-graph /out/hash-graph && \
    cp /etc/ssl/certs/ca-certificates.crt /out/etc/ssl/certs/ca-certificates.crt && \
    echo 'graph:x:61000:60000:hash-graph:/:' > /out/etc/passwd && \
    echo 'hash:x:60000:' > /out/etc/group && \
    install -d -m 0775 -o 61000 -g 60000 /out/logs


FROM scratch AS runner

COPY --from=builder /out/ /

USER graph:hash

ENTRYPOINT ["/hash-graph"]
