#!/usr/bin/env bash
# ffmpeg REDISTRIBUABLE pour l'app pcr macOS (arm64) — GPL v3, SANS `--enable-nonfree`
# (docs/RD/VIRTUAL_WEBCAM.md §13, BUGS_ENHANCEMENTS [licences/packaging]).
#
# Le binaire téléchargé tout fait (eugeneware/ffmpeg-static b6.0) est compilé avec --enable-nonfree :
# interdit de redistribution. Ici on compile ffmpeg et ses bibliothèques depuis les sources officielles,
# en statique, avec SEULEMENT ce que le pcr utilise (apps/pcr-server : libx264, libopus, aac, libsrt,
# rtsp/flv/mpegts/lavfi, avfoundation, VideoToolbox) :
#   openssl (Apache-2.0) → srt (MPL-2.0) ; x264 (GPL-2.0+) ; opus (BSD-3) ; ffmpeg (GPL-3.0+ via --enable-version3)
#
# Sortie : resources/pack/mac-arm64/ffmpeg/ffmpeg + THIRD-PARTY-LICENSES/ (textes de licence + SOURCES.txt
# = versions, URL, configure exact) — le tout est livré dans l'app (extraResources). Les archives sources
# téléchargées + ce script sont rassemblés dans resources/pack/.cache/ffmpeg-sources-<version>/ pour
# publication (obligation GPL : sources correspondantes, cf. docs/DEPLOYMENT.md).
#
#   scripts/package/build-ffmpeg-mac.sh            # build complet (~10-15 min sur M4 Pro)
#   scripts/package/build-ffmpeg-mac.sh --check    # vérifie seulement le binaire présent
#
# Prérequis : Xcode CLT, nasm (x264), cmake (srt), pkg-config — `brew install nasm cmake pkg-config`.
set -euo pipefail

ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
PACK="$ROOT/resources/pack"
OUT="$PACK/mac-arm64/ffmpeg"
WORK="$PACK/.cache/ffmpeg-build"
PREFIX="$WORK/prefix"
JOBS="$(sysctl -n hw.ncpu)"

# Versions épinglées (stables au 02/10/2026 — ffmpeg 8.1.1 = celle qui tourne en dev sur le pcr, 9.0.2 existe)
FFMPEG_VERSION="${FFMPEG_VERSION:-8.1.1}"
OPUS_VERSION="${OPUS_VERSION:-1.6.1}"
SRT_VERSION="${SRT_VERSION:-1.5.7}"
OPENSSL_VERSION="${OPENSSL_VERSION:-3.6.5}"
X264_REF="${X264_REF:-stable}"   # branche/commit videolan ; le commit résolu est écrit dans SOURCES.txt

SRC_FFMPEG="https://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.xz"
SRC_OPUS="https://ftp.osuosl.org/pub/xiph/releases/opus/opus-$OPUS_VERSION.tar.gz"
SRC_SRT="https://github.com/Haivision/srt/archive/refs/tags/v$SRT_VERSION.tar.gz"
SRC_OPENSSL="https://github.com/openssl/openssl/releases/download/openssl-$OPENSSL_VERSION/openssl-$OPENSSL_VERSION.tar.gz"
SRC_X264="https://code.videolan.org/videolan/x264.git"

step() { echo "=== $(date +%H:%M:%S) $*"; }

check_binary() {
  local bin="$OUT/ffmpeg"
  [ -x "$bin" ] || { echo "✗ $bin absent"; return 1; }
  local banner; banner="$("$bin" -hide_banner -L 2>&1 | head -1)"
  echo "licence : $banner"
  if "$bin" -hide_banner -buildconf 2>&1 | grep -q -- "--enable-nonfree"; then echo "✗ binaire NONFREE"; return 1; fi
  echo "$banner" | grep -q "GPL version 3" || { echo "✗ pas GPL v3"; return 1; }
  local missing=0
  for enc in libx264 libopus aac h264_videotoolbox; do
    "$bin" -hide_banner -encoders 2>/dev/null | grep -q " $enc " || { echo "✗ encodeur manquant : $enc"; missing=1; }
  done
  for dec in h264 hevc aac opus; do
    "$bin" -hide_banner -decoders 2>/dev/null | grep -q " $dec " || { echo "✗ décodeur manquant : $dec"; missing=1; }
  done
  "$bin" -hide_banner -protocols 2>/dev/null | grep -q "srt" || { echo "✗ protocole srt manquant"; missing=1; }
  "$bin" -hide_banner -devices 2>/dev/null | grep -q "avfoundation" || { echo "✗ périphérique avfoundation manquant"; missing=1; }
  for mux in rtsp flv mpegts lavfi; do
    "$bin" -hide_banner -formats 2>/dev/null | grep -qE "^ +[DE ]+ +$mux( |$)" || { echo "✗ format manquant : $mux"; missing=1; }
  done
  "$bin" -hide_banner -filters 2>/dev/null | grep -q " aresample " || { echo "✗ filtre aresample manquant"; missing=1; }
  if ! otool -L "$bin" | grep -qvE "^$bin:|/usr/lib/|/System/Library/"; then echo "liaison : système seulement (statique pour les libs tierces) ✓"; else
    echo "⚠ dépendances dynamiques hors système :"; otool -L "$bin" | grep -vE "^$bin:|/usr/lib/|/System/Library/"; missing=1; fi
  [ "$missing" = 0 ] && echo "✓ ffmpeg $FFMPEG_VERSION redistribuable (GPL v3, sans nonfree)"
  return $missing
}

if [ "${1:-}" = "--check" ]; then check_binary; exit $?; fi

for t in nasm cmake pkg-config curl tar xcodebuild; do command -v "$t" >/dev/null || { echo "outil manquant : $t (brew install nasm cmake pkg-config)"; exit 64; }; done
mkdir -p "$WORK/src" "$PREFIX" "$OUT"
export PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig"
export MACOSX_DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET:-12.0}"   # = LSMinimumSystemVersion de l'app

fetch() { # fetch <url> <fichier>
  [ -f "$2" ] && return 0
  echo "  ↓ $1"; curl -fsSL --retry 3 -o "$2.part" "$1" && mv "$2.part" "$2"
}
unpack() { # unpack <archive> <dossier attendu>
  [ -d "$WORK/src/$2" ] || tar xf "$1" -C "$WORK/src"
}

step "sources"
fetch "$SRC_OPENSSL" "$WORK/src/openssl-$OPENSSL_VERSION.tar.gz"; unpack "$WORK/src/openssl-$OPENSSL_VERSION.tar.gz" "openssl-$OPENSSL_VERSION"
fetch "$SRC_SRT" "$WORK/src/srt-$SRT_VERSION.tar.gz"; unpack "$WORK/src/srt-$SRT_VERSION.tar.gz" "srt-$SRT_VERSION"
fetch "$SRC_OPUS" "$WORK/src/opus-$OPUS_VERSION.tar.gz"; unpack "$WORK/src/opus-$OPUS_VERSION.tar.gz" "opus-$OPUS_VERSION"
fetch "$SRC_FFMPEG" "$WORK/src/ffmpeg-$FFMPEG_VERSION.tar.xz"; unpack "$WORK/src/ffmpeg-$FFMPEG_VERSION.tar.xz" "ffmpeg-$FFMPEG_VERSION"
if [ ! -d "$WORK/src/x264" ]; then git clone -q --branch "$X264_REF" --depth 1 "$SRC_X264" "$WORK/src/x264"; fi
X264_COMMIT="$(git -C "$WORK/src/x264" rev-parse HEAD)"

if [ ! -f "$PREFIX/lib/libssl.a" ]; then
  step "openssl $OPENSSL_VERSION (statique)"
  (cd "$WORK/src/openssl-$OPENSSL_VERSION" && ./Configure darwin64-arm64-cc no-shared no-tests no-docs --prefix="$PREFIX" --libdir=lib >/dev/null \
    && make -j"$JOBS" >/dev/null && make install_sw >/dev/null)
fi
if [ ! -f "$PREFIX/lib/libsrt.a" ]; then
  step "srt $SRT_VERSION (statique, openssl)"
  (cd "$WORK/src/srt-$SRT_VERSION" && rm -rf build && mkdir build && cd build \
    && cmake .. -DCMAKE_INSTALL_PREFIX="$PREFIX" -DENABLE_SHARED=OFF -DENABLE_STATIC=ON -DENABLE_APPS=OFF -DENABLE_ENCRYPTION=ON \
         -DUSE_ENCLIB=openssl -DOPENSSL_ROOT_DIR="$PREFIX" -DOPENSSL_USE_STATIC_LIBS=ON -DCMAKE_BUILD_TYPE=Release \
         -DCMAKE_OSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET" >/dev/null \
    && make -j"$JOBS" >/dev/null && make install >/dev/null)
fi
if [ ! -f "$PREFIX/lib/libopus.a" ]; then
  step "opus $OPUS_VERSION (statique)"
  (cd "$WORK/src/opus-$OPUS_VERSION" && ./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/libx264.a" ]; then
  step "x264 $X264_COMMIT (statique)"
  (cd "$WORK/src/x264" && ./configure --prefix="$PREFIX" --enable-static --disable-cli --enable-pic --disable-opencl >/dev/null \
    && make -j"$JOBS" >/dev/null && make install >/dev/null)
fi

step "ffmpeg $FFMPEG_VERSION"
FFMPEG_CONFIGURE=(
  --prefix="$PREFIX" --pkg-config-flags=--static
  --extra-cflags="-I$PREFIX/include" --extra-ldflags="-L$PREFIX/lib" --extra-libs="-lpthread -lm"
  --enable-gpl --enable-version3
  --enable-libx264 --enable-libopus --enable-libsrt --enable-videotoolbox --enable-audiotoolbox
  --enable-static --disable-shared --disable-debug --disable-doc --disable-ffplay --disable-ffprobe
  --disable-sdl2 --disable-xlib --disable-libxcb --disable-vulkan
  --enable-neon --enable-runtime-cpudetect
)
(cd "$WORK/src/ffmpeg-$FFMPEG_VERSION" && make distclean >/dev/null 2>&1 || true)
(cd "$WORK/src/ffmpeg-$FFMPEG_VERSION" && ./configure "${FFMPEG_CONFIGURE[@]}" > "$WORK/ffmpeg-configure.log" 2>&1 \
  || { tail -20 "$WORK/ffmpeg-configure.log"; tail -40 ffbuild/config.log; exit 1; })
(cd "$WORK/src/ffmpeg-$FFMPEG_VERSION" && make -j"$JOBS" > "$WORK/ffmpeg-make.log" 2>&1 || { tail -30 "$WORK/ffmpeg-make.log"; exit 1; })
cp "$WORK/src/ffmpeg-$FFMPEG_VERSION/ffmpeg" "$OUT/ffmpeg"
strip "$OUT/ffmpeg" 2>/dev/null || true
chmod +x "$OUT/ffmpeg"

step "licences + sources correspondantes"
LIC="$OUT/THIRD-PARTY-LICENSES"; rm -rf "$LIC"; mkdir -p "$LIC"
cp "$WORK/src/ffmpeg-$FFMPEG_VERSION/COPYING.GPLv3" "$LIC/ffmpeg-COPYING.GPLv3"
cp "$WORK/src/ffmpeg-$FFMPEG_VERSION/LICENSE.md" "$LIC/ffmpeg-LICENSE.md"
cp "$WORK/src/x264/COPYING" "$LIC/x264-COPYING.GPLv2"
cp "$WORK/src/opus-$OPUS_VERSION/COPYING" "$LIC/opus-COPYING.BSD"
cp "$WORK/src/srt-$SRT_VERSION/LICENSE" "$LIC/srt-LICENSE.MPL-2.0"
cp "$WORK/src/openssl-$OPENSSL_VERSION/LICENSE.txt" "$LIC/openssl-LICENSE.Apache-2.0"
cat > "$LIC/SOURCES.txt" <<EOF
ffmpeg $FFMPEG_VERSION for WebDiffusion PCR (macOS arm64) — built $(date -u +%Y-%m-%dT%H:%M:%SZ) by scripts/package/build-ffmpeg-mac.sh
License of this binary: GNU GPL version 3 or later (ffmpeg --enable-gpl --enable-version3). No "nonfree" component.

Components and sources (the corresponding source archives are published next to the application updates,
see docs/DEPLOYMENT.md § "Licences tierces") :
  ffmpeg  $FFMPEG_VERSION   $SRC_FFMPEG                        GPL-3.0-or-later
  x264    $X264_COMMIT  $SRC_X264 (branch $X264_REF)   GPL-2.0-or-later
  opus    $OPUS_VERSION   $SRC_OPUS                          BSD-3-Clause
  srt     $SRT_VERSION   $SRC_SRT                           MPL-2.0
  openssl $OPENSSL_VERSION   $SRC_OPENSSL                       Apache-2.0

ffmpeg configure: ${FFMPEG_CONFIGURE[*]}
EOF
SRCBUNDLE="$PACK/.cache/ffmpeg-sources-$FFMPEG_VERSION"; rm -rf "$SRCBUNDLE"; mkdir -p "$SRCBUNDLE"
cp "$WORK/src/openssl-$OPENSSL_VERSION.tar.gz" "$WORK/src/srt-$SRT_VERSION.tar.gz" "$WORK/src/opus-$OPUS_VERSION.tar.gz" "$WORK/src/ffmpeg-$FFMPEG_VERSION.tar.xz" "$SRCBUNDLE/"
(cd "$WORK/src" && git -C x264 archive --format=tar.gz --prefix="x264-$X264_COMMIT/" -o "$SRCBUNDLE/x264-$X264_COMMIT.tar.gz" HEAD)
cp "$ROOT/scripts/package/build-ffmpeg-mac.sh" "$LIC/SOURCES.txt" "$SRCBUNDLE/"
echo "sources correspondantes : $SRCBUNDLE"

step "vérification"
check_binary
