# syntax=docker/dockerfile:1.7
ARG RUST_VERSION=1.98.1
ARG XX_VERSION=1.9.0

# Cross-compilation helpers. Builder stages always run on BUILDPLATFORM, so an
# amd64 host can compile arm64 without running rustc/cargo under QEMU.
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx

FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-trixie AS builder-trixie
COPY --from=xx / /
WORKDIR /src
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
    && apt-get install -y --no-install-recommends clang lld llvm file pkg-config \
    && rm -rf /var/lib/apt/lists/*

# Fetch Rust dependencies before TARGETPLATFORM enters the cache chain, so the
# same registry/git cache is reused by amd64 and arm64 builds.
COPY Cargo.toml ./
RUN --mount=type=cache,id=gree-controller-cargo-registry,target=/usr/local/cargo/registry \
    --mount=type=cache,id=gree-controller-cargo-git,target=/usr/local/cargo/git \
    mkdir -p src \
    && printf 'fn main() {}\n' > src/main.rs \
    && cargo generate-lockfile \
    && cargo fetch --locked \
    && rm -rf src

ARG TARGETPLATFORM
ARG TARGETARCH
# Prepare the target C sysroot and Rust stdlib in a stable layer. Do not call
# the xx-cargo version probe: xx-cargo is a build wrapper and that invocation
# makes Cargo receive a target option without a subcommand.
RUN xx-apt-get update \
    && xx-apt-get install -y --no-install-recommends xx-c-essentials \
    && rm -rf /var/lib/apt/lists/* \
    && rustup target add "$(xx-cargo --print-target-triple)"

COPY build.rs ./
COPY src ./src
COPY web ./web
COPY lang ./lang
COPY presets ./presets
COPY docs/openapi.json ./docs/openapi.json
RUN --mount=type=cache,id=gree-controller-cargo-registry,target=/usr/local/cargo/registry \
    --mount=type=cache,id=gree-controller-cargo-git,target=/usr/local/cargo/git \
    --mount=type=cache,id=gree-controller-target-trixie-${TARGETARCH},target=/src/target \
    set -eux; \
    xx-cargo build --locked --release --target-dir /src/target; \
    binary="/src/target/$(xx-cargo --print-target-triple)/release/gree-controller"; \
    xx-verify "$binary"; \
    mkdir -p /out; \
    cp "$binary" /out/gree-controller

FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-alpine AS builder-alpine
COPY --from=xx / /
WORKDIR /src
RUN apk add --no-cache clang lld llvm file pkgconf

# Keep dependency fetching architecture-independent here as well.
COPY Cargo.toml ./
RUN --mount=type=cache,id=gree-controller-cargo-registry,target=/usr/local/cargo/registry \
    --mount=type=cache,id=gree-controller-cargo-git,target=/usr/local/cargo/git \
    mkdir -p src \
    && printf 'fn main() {}\n' > src/main.rs \
    && cargo generate-lockfile \
    && cargo fetch --locked \
    && rm -rf src

ARG TARGETPLATFORM
ARG TARGETARCH
RUN xx-apk add --no-cache xx-c-essentials \
    && rustup target add "$(xx-cargo --print-target-triple)"

COPY build.rs ./
COPY src ./src
COPY web ./web
COPY lang ./lang
COPY presets ./presets
COPY docs/openapi.json ./docs/openapi.json
RUN --mount=type=cache,id=gree-controller-cargo-registry,target=/usr/local/cargo/registry \
    --mount=type=cache,id=gree-controller-cargo-git,target=/usr/local/cargo/git \
    --mount=type=cache,id=gree-controller-target-alpine-${TARGETARCH},target=/src/target \
    set -eux; \
    xx-cargo build --locked --release --target-dir /src/target; \
    binary="/src/target/$(xx-cargo --print-target-triple)/release/gree-controller"; \
    xx-verify "$binary"; \
    mkdir -p /out; \
    cp "$binary" /out/gree-controller

FROM --platform=$TARGETPLATFORM debian:trixie-slim AS runtime-trixie
ARG BUILD_VERSION=dev
ARG TARGETARCH
LABEL io.hass.version="${BUILD_VERSION}" \
      io.hass.type="app" \
      org.opencontainers.image.base.name="debian:trixie-slim" \
      org.opencontainers.image.description="GREE Controller Home Assistant add-on" \
      org.opencontainers.image.vendor="MateuszG" \
      org.opencontainers.image.title="GREE Controller" \
      org.opencontainers.image.version="${BUILD_VERSION}" \
      org.opencontainers.image.architecture="${TARGETARCH}"
RUN apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates tzdata jq iproute2 curl \
    && rm -rf /var/lib/apt/lists/*
COPY --from=builder-trixie /out/gree-controller /usr/local/bin/gree-controller
COPY ha-addon/run.sh /usr/local/bin/run.sh
RUN chmod 0755 /usr/local/bin/run.sh /usr/local/bin/gree-controller
EXPOSE 8787/tcp
ENTRYPOINT ["/usr/local/bin/run.sh"]

FROM --platform=$TARGETPLATFORM alpine:latest AS runtime-alpine
ARG BUILD_VERSION=dev
ARG TARGETARCH
LABEL io.hass.version="${BUILD_VERSION}" \
      io.hass.type="app" \
      org.opencontainers.image.base.name="alpine:latest" \
      org.opencontainers.image.description="GREE Controller Home Assistant add-on" \
      org.opencontainers.image.vendor="MateuszG" \
      org.opencontainers.image.title="GREE Controller" \
      org.opencontainers.image.version="${BUILD_VERSION}" \
      org.opencontainers.image.architecture="${TARGETARCH}"
RUN apk add --no-cache bash ca-certificates tzdata jq iproute2 curl
COPY --from=builder-alpine /out/gree-controller /usr/local/bin/gree-controller
COPY ha-addon/run.sh /usr/local/bin/run.sh
RUN chmod 0755 /usr/local/bin/run.sh /usr/local/bin/gree-controller
EXPOSE 8787/tcp
ENTRYPOINT ["/usr/local/bin/run.sh"]
