#!/usr/bin/env bash
# Builds the libav.js variant `oldfmt` — FFmpeg's demuxers and decoders for legacy video (AVI, MPEG-PS,
# ASF / WMV, FLV, DV, MPEG-4 Part 2 in MP4) plus the bwdif deinterlacer, as WebAssembly — and puts the
# single-thread artifacts the page loads into public/wasm/<LIBAV_OLDFMT_DIR>/ with their checksums
# (README.md in this directory: versions, sources, licence, the size cap).
#
# Runs on Linux (or WSL) where Emscripten is installed: emsdk at $EMSDK_DIR (default
# ~/zevorld/tools/emsdk). Needs git, curl, make, node / npm and about 2 GB for FFmpeg's tree; about 1.5
# minutes on 24 cores. The site serves a copy of this script and config.json beside the licences
# (public/licenses/libav-oldfmt/; a unit test keeps the copies equal).
#
#   scripts/wasm/libav-oldfmt/build.sh [out-dir]
#
# Without an out-dir the artifacts land in public/wasm/<LIBAV_OLDFMT_DIR>/ of the checkout the script
# is in (copy them to the Mac's checkout from there). Nothing here downloads anything but libav.js's
# own tag and the FFmpeg release it pins.
set -euo pipefail

HERE=$(cd "$(dirname "$0")" && pwd)
ROOT=$(cd "$HERE/../../.." && pwd)
# The libav.js release (its Makefile pins the FFmpeg release: 6.10.9.0 builds FFmpeg 9.0).
LIBAVJS_VERSION=6.10.9.0
# The directory the page loads from (src/lib/video-studio/upscaler/libav.ts LIBAV_OLDFMT_DIR): the
# libav.js version and this recipe's revision. A changed component list or libav.js release is a new
# revision — a new URL, so no cached copy of the old build is ever taken for the new one.
DIR=libav-${LIBAVJS_VERSION}-oldfmt-r2
OUT=${1:-$ROOT/public/wasm/$DIR}
WORK=${WORK:-$HOME/zevorld/data/lab/libav-oldfmt-build}
EMSDK_DIR=${EMSDK_DIR:-$HOME/zevorld/tools/emsdk}

# shellcheck disable=SC1091
source "$EMSDK_DIR/emsdk_env.sh" >/dev/null 2>&1
emcc --version | head -1

mkdir -p "$WORK"
cd "$WORK"
[ -d libav.js ] || git clone --depth 1 --branch "v$LIBAVJS_VERSION" https://github.com/Yahweasel/libav.js.git
cd libav.js
[ -d node_modules ] || npm ci --no-audit --no-fund

# The variant's component list (the fragment names of libav.js's configs/; config.json here).
(cd configs && ./mkconfig.js oldfmt "$(tr -d '\n ' < "$HERE/config.json")")

# Only what the page loads: the ES-module frontend and the single-thread WebAssembly build. `make
# build-oldfmt` would also make the asm.js, threaded and debug builds, and the debug build's
# source-map step fails in a deep build directory (formats design §6.3, pitfall 2).
FRONTEND=dist/libav-$LIBAVJS_VERSION-oldfmt.mjs
FACTORY=dist/libav-$LIBAVJS_VERSION-oldfmt.wasm.mjs
WASM=dist/libav-$LIBAVJS_VERSION-oldfmt.wasm.wasm
time make -j"$(nproc)" "$FRONTEND" "$FACTORY"

mkdir -p "$OUT"
cp "$FRONTEND" "$FACTORY" "$WASM" "$OUT/"
cd "$OUT"
# The checksums the repository keeps (checksums.json here) and a unit test compares with the files.
node -e '
const { createHash } = require("node:crypto");
const { readFileSync, statSync } = require("node:fs");
const files = process.argv.slice(1);
const out = {};
for (const name of files)
  out[name] = {
    bytes: statSync(name).size,
    sha256: createHash("sha256").update(readFileSync(name)).digest("hex"),
  };
console.log(JSON.stringify(out, null, 2));
' "$(basename "$FRONTEND")" "$(basename "$FACTORY")" "$(basename "$WASM")"
echo "BUILD-DONE $OUT"
