FROM rust:1.85.1-slim-bookworm@sha256:9f841bbe9e7d8e37ceb96ed907265a3a0df7f44e3737d0b100e7907a679acb36 AS next-build
WORKDIR /build
COPY vendor/chromaprint-next/chromaprint-next-7a384eee-vendor.tar.gz /build/source.tar.gz
RUN echo "544d141a7314990cbc02325a10c6ed0e6cdda8370ed1d140d6d0b94d998bbe31  /build/source.tar.gz" | sha256sum -c - && tar -xzf /build/source.tar.gz -C /build
WORKDIR /build/project
ENV RUSTFLAGS="" CARGO_ENCODED_RUSTFLAGS="" CARGO_BUILD_JOBS=2
RUN cargo test --release --offline --locked -p chromaprint-next --lib && cargo build --release --offline --locked -p meloyab-chromaprint-next

FROM rust:1.85.1-slim-bookworm@sha256:9f841bbe9e7d8e37ceb96ed907265a3a0df7f44e3737d0b100e7907a679acb36 AS segment-build
WORKDIR /build
COPY vendor/lmdb/lmdb-1.7.5.tar.gz /build/lmdb.tar.gz
COPY meloyab/segment_build.c meloyab/segment_native.c meloyab/landmark.c /build/
RUN echo "f0604751762cb097059d5412444c4057b95f386c7ed958363cf63f453e5108da  /build/lmdb.tar.gz" | sha256sum -c - && tar -xzf /build/lmdb.tar.gz -C /build \
    && cc -O2 -pthread -c -w -I/build/lmdb-1.7.5/lib /build/lmdb-1.7.5/lib/mdb.c -o /build/mdb.o \
    && cc -O2 -pthread -c -w -I/build/lmdb-1.7.5/lib /build/lmdb-1.7.5/lib/midl.c -o /build/midl.o \
    && mkdir -p /build/out && cc -O2 -std=c11 -Wall -Wextra -pthread -I/build/lmdb-1.7.5/lib /build/segment_build.c /build/mdb.o /build/midl.o -o /build/out/_segment_build \
    && cc -O2 -std=c11 -fPIC -shared -Wall -Wextra /build/segment_native.c -o /build/out/_segment_native.so \
    && cc -O2 -std=c11 -fPIC -shared -pthread -Wall -Wextra /build/landmark.c -lm -o /build/out/_landmark.so \
    && chmod 0755 /build/out/_segment_build && chmod 0644 /build/out/_segment_native.so /build/out/_landmark.so

# r90: the Rust search front (standard library only; no crates to vendor).
FROM rust:1.85.1-slim-bookworm@sha256:9f841bbe9e7d8e37ceb96ed907265a3a0df7f44e3737d0b100e7907a679acb36 AS front-build
WORKDIR /build/search-front
COPY native/search-front/Cargo.toml native/search-front/Cargo.lock /build/search-front/
COPY native/search-front/src/ /build/search-front/src/
ENV RUSTFLAGS="" CARGO_ENCODED_RUSTFLAGS="" CARGO_BUILD_JOBS=2
RUN cargo test --release --offline --locked && cargo build --release --offline --locked \
    && /build/search-front/target/release/meloyab-search-front --version

# r91: Rust-controlled libav decoding in the recognition process; no crates.
FROM rust:1.85.1-slim-bookworm@sha256:9f841bbe9e7d8e37ceb96ed907265a3a0df7f44e3737d0b100e7907a679acb36 AS audio-build
RUN apt-get update && apt-get install -y --no-install-recommends pkg-config libavformat-dev libavcodec-dev libavutil-dev libswresample-dev && rm -rf /var/lib/apt/lists/*
WORKDIR /build/audio-decode
COPY native/audio-decode/ /build/audio-decode/
ENV RUSTFLAGS="" CARGO_ENCODED_RUSTFLAGS="" CARGO_BUILD_JOBS=2
RUN cargo build --release --offline --locked

FROM python:3.12-slim-bookworm AS native-build
ENV PIP_NO_CACHE_DIR=1
RUN apt-get update && apt-get install -y --no-install-recommends build-essential patch cmake pkg-config libavcodec-dev libavutil-dev \
    && rm -rf /var/lib/apt/lists/*
RUN pip install setuptools==84.0.0 wheel==0.48.0
WORKDIR /build
COPY scripts/build_chromaprint.py scripts/patch_chromaprint.py scripts/verify_chromaprint_parity.py scripts/upstream_chroma_compare.cpp /build/scripts/
COPY vendor/chromaprint/ /build/vendor/chromaprint/
RUN python scripts/build_chromaprint.py --archive vendor/chromaprint/chromaprint-1.6.2.tar.gz --build-dir /build/upstream --prefix /opt/chromaprint
COPY scripts/prepare_owned_lmdb.py scripts/build_chroma_native.py /build/scripts/
COPY vendor/lmdb /build/vendor/lmdb
COPY meloyab/chroma_exact.c meloyab/chroma_compare.h /build/meloyab/
RUN python scripts/prepare_owned_lmdb.py vendor/lmdb/lmdb-1.7.5.tar.gz /build/lmdb-source \
    && pip wheel --no-deps --no-build-isolation /build/lmdb-source/lmdb-1.7.5 --wheel-dir /wheels \
    && python scripts/build_chroma_native.py --output /native/_chroma_exact.so

FROM python:3.12-slim-bookworm
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PIP_NO_CACHE_DIR=1
RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg libgomp1 ca-certificates \
    && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements-lock.txt ./
RUN pip install -r requirements-lock.txt && python -c "from telethon.crypto import aes; assert aes.cryptg is not None"
COPY --from=native-build /wheels /tmp/native-wheels
RUN pip install --no-index --no-deps --force-reinstall /tmp/native-wheels/lmdb-1.7.5-*.whl \
    && rm -rf /tmp/native-wheels && pip freeze > /app/build-versions.txt
COPY . /app
COPY --from=native-build /opt/chromaprint/lib/ /usr/local/lib/
COPY --from=native-build /opt/chromaprint/bin/ /usr/local/bin/
COPY --from=native-build /opt/chromaprint/chromaprint-build.json /app/chromaprint-build.json
COPY --from=native-build /opt/chromaprint/chromaprint-parity.json /app/chromaprint-parity.json
RUN ldconfig
COPY --from=native-build /native/_chroma_exact.so /app/meloyab/_chroma_exact.so
COPY --from=next-build /build/project/target/release/libmeloyab_chromaprint_next.so /app/meloyab/libchromaprint_next.so
COPY --from=segment-build /build/out/ /app/meloyab/
COPY --from=front-build /build/search-front/target/release/meloyab-search-front /usr/local/bin/meloyab-search-front
COPY --from=audio-build /build/audio-decode/target/release/libmeloyab_audio_decode.so /app/meloyab/libmeloyab_audio_decode.so
RUN python scripts/verify_audio_decode.py > /app/audio-decode-parity.json
RUN python scripts/verify_chromaprint_next.py --output /app/chromaprint-next-parity.json --build-metadata /app/chromaprint-next-build.json
RUN python scripts/retire_acoustid.py --check-image && python scripts/verify_native_build.py && python scripts/source_archive.py \
    && useradd -u 10001 -m meloyab && mkdir -p /data && chown meloyab:meloyab /data
USER 10001:10001
ENV DATA_DIR=/data CPU_THREADS=1 OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1
CMD ["uvicorn", "meloyab.api:create_app", "--factory", "--host", "0.0.0.0", "--port", "8094", "--workers", "1", "--no-access-log", "--timeout-keep-alive", "5"]
