# Multi-stage, multi-arch build for record-asr.
#
#   docker build -t record-asr .
#   docker buildx build --platform linux/amd64,linux/arm64 -t record-asr:latest --push .
#
# buildx builds each platform NATIVELY (the builder image matches the target
# arch), so cgo links the correct prebuilt .so for that arch and NO cross
# compiler is needed — unlike the bare `make build-arm64` path.

# ---- builder ----
FROM golang:1.22-bookworm AS builder

WORKDIR /src
# Allow overriding the Go module proxy, e.g. for restricted networks:
#   docker build --build-arg GOPROXY=https://goproxy.cn,direct -t record-asr .
ARG GOPROXY=https://proxy.golang.org,direct
ENV GOPROXY=${GOPROXY}
# Cache module downloads (incl. the large sherpa-onnx-go .so) separately from
# source so code changes don't re-download deps.
COPY go.mod go.sum ./
RUN go mod download

COPY . .

# Build, then copy the prebuilt .so that match THIS builder's arch into /out/lib.
# The glob avoids hard-coding the sherpa-onnx-go-linux version.
RUN set -eux; \
    CGO_ENABLED=1 go build -trimpath -o /out/record-asr .; \
    arch="$(go env GOARCH)"; \
    case "$arch" in \
      amd64) libd=x86_64-unknown-linux-gnu;; \
      arm64) libd=aarch64-unknown-linux-gnu;; \
      *) echo "unsupported arch: $arch" >&2; exit 1;; \
    esac; \
    mkdir -p /out/lib; \
    cp "$(go env GOMODCACHE)/github.com/k2-fsa/sherpa-onnx-go-linux@"*/lib/"$libd"/*.so /out/lib/

# ---- models: download SenseVoice int8 + silero VAD at BUILD time ----
# These are arch-independent ONNX files, so the same download serves every
# platform. Baking them into the image means the container starts instantly
# and needs no network at runtime. (One-time ~230MB cost per build.)
FROM debian:bookworm-slim AS models
RUN apt-get update \
 && apt-get install -y --no-install-recommends ca-certificates curl bzip2 \
 && rm -rf /var/lib/apt/lists/*
# Extract ONLY model.int8.onnx + tokens.txt from the release tarball (skip the
# test wavs / float model) to keep the layer lean. --strip-components=1 flattens
# the top archive dir so files land directly in /models/sensevoice/.
RUN mkdir -p /models/sensevoice \
 && curl -fsSL -o /tmp/sv.tar.bz2 \
      "https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-sense-voice-zh-en-ja-ko-yue-int8-2024-07-17.tar.bz2" \
 && tar -xjf /tmp/sv.tar.bz2 -C /models/sensevoice \
      --strip-components=1 --wildcards --no-anchored 'model.int8.onnx' 'tokens.txt' \
 && rm -f /tmp/sv.tar.bz2 \
 && curl -fsSL -o /models/silero_vad.onnx \
      "https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/silero_vad.onnx" \
 && test -s /models/sensevoice/model.int8.onnx \
 && test -s /models/sensevoice/tokens.txt \
 && test -s /models/silero_vad.onnx \
 && ls -lh /models/sensevoice /models/silero_vad.onnx

# ---- runtime (glibc; sherpa-onnx .so are glibc-built, so NOT alpine/musl) ----
FROM debian:bookworm-slim

# APT_MIRROR: optionally swap deb.debian.org for a faster regional mirror, e.g.
#   docker build --build-arg APT_MIRROR=mirrors.tuna.tsinghua.edu.cn -t record-asr .
# Defaults to the upstream deb.debian.org (no swap). ffmpeg (~250MB of codec
# libs) decodes m4a/aac/opus/wma — beep is pure-Go for wav/mp3/flac/ogg only.
ARG APT_MIRROR=
RUN set -eux; \
    if [ -n "$APT_MIRROR" ]; then \
      f=/etc/apt/sources.list.d/debian.sources; \
      if [ -f "$f" ]; then sed -i "s|deb.debian.org|$APT_MIRROR|g; s|security.debian.org|$APT_MIRROR|g" "$f"; \
      else sed -i "s|deb.debian.org|$APT_MIRROR|g; s|security.debian.org|$APT_MIRROR|g" /etc/apt/sources.list; fi; \
    fi; \
    apt-get update \
 && apt-get install -y --no-install-recommends ca-certificates curl ffmpeg \
 && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY --from=builder /out/record-asr /app/record-asr
COPY --from=builder /out/lib /app/lib
COPY --from=models /models /models

# Defaults; override via -e / compose. Models are baked in at /models, so
# startup skips the download entirely. Only /app/data (tasks + uploads) is a
# volume; it never holds models.
ENV ASR_ADDR=:8080 \
    ASR_DATA_DIR=/app/data \
    ASR_MODEL_DIR=/models \
    ASR_DOWNLOAD_TIMEOUT=1800 \
    LD_LIBRARY_PATH=/app/lib

VOLUME /app/data
EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
  CMD curl -fsS http://127.0.0.1:8080/healthz || exit 1

ENTRYPOINT ["/app/record-asr"]

