#!/bin/bash
# Build the pinned, LGPL-only delivery encoder as one static arm64 executable:
# Packaging/TranscodeHelper/dist/MomentumTranscodeHelper
#
# NO --enable-gpl. x264, x265 and every other GPL-only library are excluded on
# purpose: cinemaOS is proprietary, so a GPL component in the bundle would be a
# licence violation. H.264 and HEVC come from VideoToolbox hardware instead,
# which is faster anyway.
#
# Every source is fetched by pinned URL and verified against the SHA-256 in
# PROVENANCE.json before a single byte is compiled. A hash mismatch is fatal.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILD_ROOT="${MOMENTUM_TRANSCODE_BUILD_ROOT:-$SCRIPT_DIR/.build}"
PREFIX="$BUILD_ROOT/prefix"
SRC="$BUILD_ROOT/src"
DIST="$SCRIPT_DIR/dist"
PROVENANCE="$SCRIPT_DIR/PROVENANCE.json"
JOBS="$(sysctl -n hw.ncpu)"

export PATH="/opt/homebrew/bin:$PATH"
export PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig"
export MACOSX_DEPLOYMENT_TARGET=13.0
export SOURCE_DATE_EPOCH=1721001600

say() { printf '▸ %s\n' "$*"; }
die() { printf '✗ %s\n' "$*" >&2; exit 1; }

[[ "$(uname -m)" == "arm64" ]] || die "the transcode helper must be built on native arm64"
[[ -f "$PROVENANCE" ]] || die "missing $PROVENANCE"

for tool in nasm pkg-config cmake meson ninja curl shasum; do
    command -v "$tool" >/dev/null || die "missing build tool: $tool (brew install $tool)"
done

mkdir -p "$PREFIX" "$SRC" "$DIST"

# Read one pinned field out of PROVENANCE.json without assuming jq is present.
pin() { # name field
    python3 -c "
import json,sys
p=json.load(open('$PROVENANCE'))
for s in p['sources']:
    if s['name']=='$1': print(s['$2']); break
else: sys.exit('no pinned source named $1')
"
}

fetch() { # name dir
    local name="$1" dir="$2" url sha actual
    [[ -d "$SRC/$dir" ]] && return 0
    url="$(pin "$name" url)"; sha="$(pin "$name" sha256)"
    say "fetch $name"
    curl -sSL --fail "$url" -o "$SRC/$dir.tar.gz" || die "download failed: $url"
    actual="$(shasum -a 256 "$SRC/$dir.tar.gz" | cut -d' ' -f1)"
    [[ "$actual" == "$sha" ]] || die "$name hash mismatch
  expected $sha
  actual   $actual
  Refusing to build unverified source."
    mkdir -p "$SRC/$dir"
    tar xzf "$SRC/$dir.tar.gz" -C "$SRC/$dir" --strip-components=1
    rm -f "$SRC/$dir.tar.gz"
}

if [[ ! -f "$PREFIX/lib/libopus.a" ]]; then
    fetch opus opus; say "build opus"
    (cd "$SRC/opus" && ./configure --prefix="$PREFIX" --disable-shared --enable-static \
        --disable-doc --disable-extra-programs >/dev/null && make -j"$JOBS" >/dev/null && make install >/dev/null)
fi

if [[ ! -f "$PREFIX/lib/libmp3lame.a" ]]; then
    fetch lame lame; say "build lame"
    (cd "$SRC/lame" && ./configure --prefix="$PREFIX" --disable-shared --enable-static \
        --disable-frontend >/dev/null 2>&1 && make -j"$JOBS" >/dev/null 2>&1 && make install >/dev/null)
fi

if [[ ! -f "$PREFIX/lib/libvpx.a" ]]; then
    fetch libvpx vpx; say "build libvpx"
    (cd "$SRC/vpx" && ./configure --prefix="$PREFIX" --disable-shared --enable-static \
        --disable-examples --disable-tools --disable-docs --disable-unit-tests \
        --enable-vp8 --enable-vp9 --enable-vp9-highbitdepth >/dev/null \
        && make -j"$JOBS" >/dev/null 2>&1 && make install >/dev/null)
fi

if [[ ! -f "$PREFIX/lib/libSvtAv1Enc.a" ]]; then
    fetch SVT-AV1 svtav1; say "build SVT-AV1"
    (cd "$SRC/svtav1" && cmake -S . -B build -DCMAKE_INSTALL_PREFIX="$PREFIX" \
        -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_APPS=OFF -DBUILD_TESTING=OFF >/dev/null \
        && cmake --build build -j"$JOBS" >/dev/null 2>&1 && cmake --install build >/dev/null)
fi

if [[ ! -f "$PREFIX/lib/libdav1d.a" ]]; then
    fetch dav1d dav1d; say "build dav1d"
    (cd "$SRC/dav1d" && meson setup build --prefix="$PREFIX" --default-library=static \
        --buildtype=release -Denable_tools=false -Denable_tests=false >/dev/null \
        && ninja -C build >/dev/null 2>&1 && ninja -C build install >/dev/null)
fi

if [[ ! -f "$PREFIX/lib/libopenjp2.a" ]]; then
    fetch openjpeg openjpeg; say "build openjpeg"
    (cd "$SRC/openjpeg" && cmake -S . -B build -DCMAKE_INSTALL_PREFIX="$PREFIX" \
        -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_CODEC=OFF >/dev/null \
        && cmake --build build -j"$JOBS" >/dev/null 2>&1 && cmake --install build >/dev/null)
fi

fetch ffmpeg ffmpeg
say "configure ffmpeg (LGPL only)"
cd "$SRC/ffmpeg"
./configure \
    --prefix="$PREFIX" \
    --arch=arm64 --enable-neon \
    --disable-shared --enable-static \
    --enable-version3 \
    --disable-doc --disable-ffplay --disable-debug \
    --enable-ffmpeg --enable-ffprobe \
    --enable-videotoolbox --enable-audiotoolbox \
    --enable-libopus --enable-libmp3lame --enable-libvpx \
    --enable-libsvtav1 --enable-libdav1d --enable-libopenjpeg \
    --extra-cflags="-I$PREFIX/include" --extra-ldflags="-L$PREFIX/lib" \
    --pkg-config-flags="--static" > "$BUILD_ROOT/configure.log" 2>&1 \
    || { tail -40 "$BUILD_ROOT/configure.log"; die "ffmpeg configure failed"; }

say "compile ffmpeg"
make -j"$JOBS" > "$BUILD_ROOT/make.log" 2>&1 || { tail -40 "$BUILD_ROOT/make.log"; die "ffmpeg build failed"; }
make install >/dev/null

cp "$PREFIX/bin/ffmpeg" "$DIST/MomentumTranscodeHelper"
chmod 755 "$DIST/MomentumTranscodeHelper"

# Fail closed rather than ship a helper that turns out to carry GPL code.
if "$DIST/MomentumTranscodeHelper" -version 2>/dev/null | grep -q -- "--enable-gpl"; then
    rm -f "$DIST/MomentumTranscodeHelper"
    die "built helper reports --enable-gpl; refusing to ship a GPL component in a proprietary bundle"
fi
[[ "$(lipo -archs "$DIST/MomentumTranscodeHelper")" == "arm64" ]] \
    || die "helper is not a pure arm64 binary"

say "helper: $DIST/MomentumTranscodeHelper"
"$DIST/MomentumTranscodeHelper" -version | head -1
shasum -a 256 "$DIST/MomentumTranscodeHelper"
