#!/usr/bin/env bash
# ffmpeg REDISTRIBUABLE pour l'app pcr Linux x64 — GPL v3, SANS `--enable-nonfree` — bâti dans un conteneur
# Debian 12 (bookworm, glibc 2.36) sous docker/OrbStack depuis le Mac, 100 % statique (-static : aucune dépendance
# à la glibc de la machine cible, comme les builds johnvansickle qu'il remplace). Décision Jérôme du 02/10
# (docs/RD/VIRTUAL_WEBCAM.md §13, BUGS_ENHANCEMENTS [licences/packaging]) : les sources correspondantes sont publiées.
#
# Même recette que build-ffmpeg-mac.sh / build-ffmpeg-win.sh (ce que le pcr utilise) :
#   openssl (Apache-2.0) → srt (MPL-2.0) ; x264 (GPL-2.0+) ; opus (BSD-3) ; nv-codec-headers (MIT) ;
#   ffmpeg (GPL-3.0+ via --enable-version3) — v4l2 natif pour les sources directes ; pas d'ALSA (dépendance dynamique).
#
# Sortie : resources/pack/linux-x64/ffmpeg/{ffmpeg,ffprobe} + THIRD-PARTY-LICENSES/ (textes + SOURCES.txt) ; lot de
# sources complété dans resources/pack/.cache/ffmpeg-sources-<v>/ (scripts/package/publish-ffmpeg-sources.sh).
#
#   scripts/package/build-ffmpeg-linux.sh            # build complet (~25 min : amd64 émulé/Rosetta sur Apple silicon)
#   scripts/package/build-ffmpeg-linux.sh --check    # vérifie le binaire présent en l'EXÉCUTANT dans le conteneur
#   (--inside : usage interne, exécuté DANS le conteneur)
set -euo pipefail

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}"
NVHDR_REF="${NVHDR_REF:-n13.0.19.1}"
IMAGE="${FFMPEG_LINUX_IMAGE:-debian:bookworm-slim}"

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"
SRC_NVHDR="https://github.com/FFmpeg/nv-codec-headers.git"

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

############################################################################################################
# DANS le conteneur : /work = resources/pack/.cache/ffmpeg-build (archives dans /work/src), sortie /work/linux/out
############################################################################################################
if [ "${1:-}" = "--inside" ]; then
  export DEBIAN_FRONTEND=noninteractive
  step "outils (apt)"
  apt-get update -qq >/dev/null && apt-get install -qq -y --no-install-recommends \
    build-essential nasm cmake pkg-config perl git curl ca-certificates xz-utils file > /dev/null
  WORK=/work; SRC="$WORK/src"; BUILD="$WORK/linux"; PREFIX="$BUILD/prefix"; OUT="$BUILD/out"
  JOBS="$(nproc)"
  mkdir -p "$BUILD/src" "$PREFIX" "$OUT"
  export PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig"; unset PKG_CONFIG_PATH
  unpack_fresh() { [ -d "$BUILD/src/$2" ] || tar xf "$1" -C "$BUILD/src"; }
  unpack_fresh "$SRC/openssl-$OPENSSL_VERSION.tar.gz" "openssl-$OPENSSL_VERSION"
  unpack_fresh "$SRC/srt-$SRT_VERSION.tar.gz" "srt-$SRT_VERSION"
  unpack_fresh "$SRC/opus-$OPUS_VERSION.tar.gz" "opus-$OPUS_VERSION"
  unpack_fresh "$SRC/ffmpeg-$FFMPEG_VERSION.tar.xz" "ffmpeg-$FFMPEG_VERSION"
  # ⚠ jamais `cp -R $SRC/x264` : ce clone porte les .depend du build IN-TREE du Mac (chemins MacOSX.sdk) → make casse
  # (vécu 02/10) ; on part d'une archive propre produite par git archive côté Mac.
  [ -d "$BUILD/src/x264" ] || (mkdir -p "$BUILD/src/x264" && tar xzf "$SRC/x264-src.tar.gz" -C "$BUILD/src/x264")
  X264_COMMIT="$(cat "$SRC/x264-commit.txt")"

  if [ ! -f "$PREFIX/lib/libssl.a" ]; then
    step "openssl $OPENSSL_VERSION (statique)"
    (cd "$BUILD/src/openssl-$OPENSSL_VERSION" && ./Configure linux-x86_64 no-shared no-tests no-docs --prefix="$PREFIX" --libdir=lib > "$BUILD/openssl.log" 2>&1 \
      && make -j"$JOBS" >> "$BUILD/openssl.log" 2>&1 && make install_sw >> "$BUILD/openssl.log" 2>&1) || { tail -20 "$BUILD/openssl.log"; exit 1; }
  fi
  if [ ! -f "$PREFIX/lib/libsrt.a" ]; then
    step "srt $SRT_VERSION (statique, openssl)"
    (cd "$BUILD/src/srt-$SRT_VERSION" && rm -rf build && mkdir build && cd build \
      && cmake .. -DCMAKE_INSTALL_PREFIX="$PREFIX" -DCMAKE_BUILD_TYPE=Release -DENABLE_SHARED=OFF -DENABLE_STATIC=ON \
           -DENABLE_APPS=OFF -DENABLE_ENCRYPTION=ON -DUSE_ENCLIB=openssl -DOPENSSL_ROOT_DIR="$PREFIX" -DOPENSSL_USE_STATIC_LIBS=ON \
           -DUSE_OPENSSL_PC=OFF -DOPENSSL_INCLUDE_DIR="$PREFIX/include" -DOPENSSL_SSL_LIBRARY="$PREFIX/lib/libssl.a" \
           -DOPENSSL_CRYPTO_LIBRARY="$PREFIX/lib/libcrypto.a" > "$BUILD/srt.log" 2>&1 \
      && make -j"$JOBS" >> "$BUILD/srt.log" 2>&1 && make install >> "$BUILD/srt.log" 2>&1) || { tail -30 "$BUILD/srt.log"; exit 1; }
    # ⚠ srt.pc recopie les libs implicites du toolchain (-lgcc_s -lgcc -lc) : en lien statique, -lgcc_s n'existe pas
    # en .a (vécu 02/10 sur Windows, même origine) — on ne garde que -lstdc++ -lm.
    perl -pi -e 's/ -l(gcc_s|gcc|c)(?=\s|$)//g' "$PREFIX/lib/pkgconfig/srt.pc"
  fi
  if [ ! -f "$PREFIX/lib/libopus.a" ]; then
    step "opus $OPUS_VERSION (statique)"
    (cd "$BUILD/src/opus-$OPUS_VERSION" && ./configure --prefix="$PREFIX" --disable-shared --enable-static --disable-doc --disable-extra-programs > "$BUILD/opus.log" 2>&1 \
      && make -j"$JOBS" >> "$BUILD/opus.log" 2>&1 && make install >> "$BUILD/opus.log" 2>&1) || { tail -20 "$BUILD/opus.log"; exit 1; }
  fi
  if [ ! -f "$PREFIX/lib/libx264.a" ]; then
    step "x264 $X264_COMMIT (statique)"
    (cd "$BUILD/src/x264" && ./configure --prefix="$PREFIX" --enable-static --disable-cli --enable-pic --disable-opencl > "$BUILD/x264.log" 2>&1 \
      && make -j"$JOBS" >> "$BUILD/x264.log" 2>&1 && make install >> "$BUILD/x264.log" 2>&1) || { tail -20 "$BUILD/x264.log"; exit 1; }
  fi
  if [ ! -f "$PREFIX/lib/pkgconfig/ffnvcodec.pc" ]; then
    step "nv-codec-headers $NVHDR_REF"
    (cd "$SRC/nv-codec-headers" && make install PREFIX="$PREFIX" > "$BUILD/nvhdr.log" 2>&1) || { tail "$BUILD/nvhdr.log"; exit 1; }
  fi

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

  LIC="$OUT/THIRD-PARTY-LICENSES"; rm -rf "$LIC"; mkdir -p "$LIC"
  cp "$FF/COPYING.GPLv3" "$LIC/ffmpeg-COPYING.GPLv3"; cp "$FF/LICENSE.md" "$LIC/ffmpeg-LICENSE.md"
  cp "$BUILD/src/x264/COPYING" "$LIC/x264-COPYING.GPLv2"; cp "$BUILD/src/opus-$OPUS_VERSION/COPYING" "$LIC/opus-COPYING.BSD"
  cp "$BUILD/src/srt-$SRT_VERSION/LICENSE" "$LIC/srt-LICENSE.MPL-2.0"; cp "$BUILD/src/openssl-$OPENSSL_VERSION/LICENSE.txt" "$LIC/openssl-LICENSE.Apache-2.0"
  awk '/\/\*/{f=1} f{print} /\*\//{if(f)exit}' "$SRC/nv-codec-headers/include/ffnvcodec/nvEncodeAPI.h" > "$LIC/nv-codec-headers-LICENSE.MIT"   # 1er bloc de commentaire = notice MIT
  cat > "$LIC/SOURCES.txt" <<EOF
ffmpeg $FFMPEG_VERSION for WebDiffusion PCR (Linux x86_64) — built $(date -u +%Y-%m-%dT%H:%M:%SZ) by scripts/package/build-ffmpeg-linux.sh
in $IMAGE ($(. /etc/os-release && echo "$PRETTY_NAME"), gcc $(gcc -dumpversion)). License of this binary: GNU GPL version 3 or later
(ffmpeg --enable-gpl --enable-version3). No "nonfree" component. Fully static (no glibc/library dependency at runtime).

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
  nv-codec-headers  $NVHDR_REF  $SRC_NVHDR (headers only)         MIT

ffmpeg configure: ${FFMPEG_CONFIGURE[*]}
EOF
  echo "INSIDE_DONE"
  exit 0
fi

############################################################################################################
# SUR LE MAC
############################################################################################################
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
PACK="$ROOT/resources/pack"
OUT="$PACK/linux-x64/ffmpeg"
WORK="$PACK/.cache/ffmpeg-build"
SRC="$WORK/src"
command -v docker >/dev/null || { echo "docker absent (OrbStack)"; exit 64; }
docker_run() { docker run --rm --platform linux/amd64 "$@"; }

check_binary() {
  local bin="$OUT/ffmpeg" missing=0
  [ -x "$bin" ] || { echo "✗ $bin absent"; return 1; }
  [ -x "$OUT/ffprobe" ] || { echo "✗ ffprobe absent (media-upload le dérive de FFMPEG_BIN)"; missing=1; }
  local kind; kind="$(file -b "$bin")"
  grep -q "ELF 64-bit.*x86-64" <<<"$kind" || { echo "✗ pas un ELF x86-64 : $kind"; return 1; }
  grep -q "statically linked\|static-pie" <<<"$kind" || { echo "✗ pas statique : $kind"; missing=1; }
  # Exécution réelle dans le conteneur (émulation amd64) — ⚠ capturer avant de grepper (pipefail + grep -q = SIGPIPE).
  local lic conf encs decs protos devs fmts filts
  lic="$(docker_run -v "$OUT:/f:ro" "$IMAGE" /f/ffmpeg -hide_banner -L 2>&1 | tr '\n' ' ')"
  grep -qi "General Public License.*version 3" <<<"$lic" || { echo "✗ pas GPL v3"; return 1; }
  grep -qi "nonfree" <<<"$lic" && { echo "✗ bannière nonfree"; return 1; }
  conf="$(docker_run -v "$OUT:/f:ro" "$IMAGE" /f/ffmpeg -hide_banner -buildconf 2>&1)"
  grep -q -- "--enable-nonfree" <<<"$conf" && { echo "✗ binaire NONFREE"; return 1; }
  encs="$(docker_run -v "$OUT:/f:ro" "$IMAGE" /f/ffmpeg -hide_banner -encoders 2>/dev/null)"
  decs="$(docker_run -v "$OUT:/f:ro" "$IMAGE" /f/ffmpeg -hide_banner -decoders 2>/dev/null)"
  protos="$(docker_run -v "$OUT:/f:ro" "$IMAGE" /f/ffmpeg -hide_banner -protocols 2>/dev/null)"
  devs="$(docker_run -v "$OUT:/f:ro" "$IMAGE" /f/ffmpeg -hide_banner -devices 2>/dev/null)"
  fmts="$(docker_run -v "$OUT:/f:ro" "$IMAGE" /f/ffmpeg -hide_banner -formats 2>/dev/null)"
  filts="$(docker_run -v "$OUT:/f:ro" "$IMAGE" /f/ffmpeg -hide_banner -filters 2>/dev/null)"
  for enc in libx264 libopus aac h264_nvenc; do grep -q " $enc " <<<"$encs" || { echo "✗ encodeur manquant : $enc"; missing=1; }; done
  for dec in h264 hevc aac opus; do grep -q " $dec " <<<"$decs" || { echo "✗ décodeur manquant : $dec"; missing=1; }; done
  for pr in srt rtmp https tls; do grep -q "$pr" <<<"$protos" || { echo "✗ protocole manquant : $pr"; missing=1; }; done
  grep -q "video4linux2" <<<"$devs" || { echo "✗ périphérique v4l2 manquant"; missing=1; }
  for mux in rtsp flv mpegts lavfi mp4; do grep -qE "^ +[DEd ]+ +$mux( |$)" <<<"$fmts" || { echo "✗ format manquant : $mux"; missing=1; }; done
  for f in scale fps aresample; do grep -q " $f " <<<"$filts" || { echo "✗ filtre manquant : $f"; missing=1; }; done
  [ -f "$OUT/THIRD-PARTY-LICENSES/SOURCES.txt" ] || { echo "✗ THIRD-PARTY-LICENSES/SOURCES.txt absent"; missing=1; }
  [ "$missing" = 0 ] && echo "✓ ffmpeg $FFMPEG_VERSION linux-x64 redistribuable (GPL v3, sans nonfree, statique) — $(du -h "$bin" | cut -f1)"
  return $missing
}
if [ "${1:-}" = "--check" ]; then check_binary; exit $?; fi

for t in curl tar git file; do command -v "$t" >/dev/null || { echo "outil manquant : $t"; exit 64; }; done
mkdir -p "$SRC" "$OUT"
fetch() { [ -f "$2" ] && return 0; echo "  ↓ $1"; curl -fsSL --retry 3 -o "$2.part" "$1" && mv "$2.part" "$2"; }
step "sources (cache partagé $SRC)"
fetch "$SRC_OPENSSL" "$SRC/openssl-$OPENSSL_VERSION.tar.gz"
fetch "$SRC_SRT" "$SRC/srt-$SRT_VERSION.tar.gz"
fetch "$SRC_OPUS" "$SRC/opus-$OPUS_VERSION.tar.gz"
fetch "$SRC_FFMPEG" "$SRC/ffmpeg-$FFMPEG_VERSION.tar.xz"
[ -d "$SRC/x264" ] || git clone -q --branch "$X264_REF" --depth 1 "$SRC_X264" "$SRC/x264"
[ -d "$SRC/nv-codec-headers" ] || git clone -q --branch "$NVHDR_REF" --depth 1 "$SRC_NVHDR" "$SRC/nv-codec-headers"
X264_COMMIT="$(git -C "$SRC/x264" rev-parse HEAD)"; echo "$X264_COMMIT" > "$SRC/x264-commit.txt"
git -C "$SRC/x264" archive --format=tar.gz -o "$SRC/x264-src.tar.gz" HEAD   # arbre propre pour le conteneur

step "build dans $IMAGE (amd64)"
docker_run -v "$WORK:/work" -v "$ROOT/scripts/package/build-ffmpeg-linux.sh:/build.sh:ro" \
  -e FFMPEG_VERSION -e OPUS_VERSION -e SRT_VERSION -e OPENSSL_VERSION -e X264_REF -e NVHDR_REF -e FFMPEG_LINUX_IMAGE="$IMAGE" \
  "$IMAGE" bash /build.sh --inside | tee "$WORK/linux-build.log" | grep -E "^===|INSIDE_DONE|rror" || true
grep -q "INSIDE_DONE" "$WORK/linux-build.log" || { echo "✗ build conteneur en échec (voir $WORK/linux-build.log et $WORK/linux/*.log)"; exit 1; }
rm -rf "$OUT"; mkdir -p "$OUT"; cp -R "$WORK/linux/out/." "$OUT/"

step "sources correspondantes"
SRCBUNDLE="$PACK/.cache/ffmpeg-sources-$FFMPEG_VERSION"; mkdir -p "$SRCBUNDLE"
for a in "openssl-$OPENSSL_VERSION.tar.gz" "srt-$SRT_VERSION.tar.gz" "opus-$OPUS_VERSION.tar.gz" "ffmpeg-$FFMPEG_VERSION.tar.xz"; do
  [ -f "$SRCBUNDLE/$a" ] || cp "$SRC/$a" "$SRCBUNDLE/"
done
[ -f "$SRCBUNDLE/x264-$X264_COMMIT.tar.gz" ] || git -C "$SRC/x264" archive --format=tar.gz --prefix="x264-$X264_COMMIT/" -o "$SRCBUNDLE/x264-$X264_COMMIT.tar.gz" HEAD
[ -f "$SRCBUNDLE/nv-codec-headers-$NVHDR_REF.tar.gz" ] || git -C "$SRC/nv-codec-headers" archive --format=tar.gz --prefix="nv-codec-headers-$NVHDR_REF/" -o "$SRCBUNDLE/nv-codec-headers-$NVHDR_REF.tar.gz" HEAD
cp "$ROOT/scripts/package/build-ffmpeg-linux.sh" "$SRCBUNDLE/"; cp "$OUT/THIRD-PARTY-LICENSES/SOURCES.txt" "$SRCBUNDLE/SOURCES-linux-x64.txt"
echo "sources correspondantes : $SRCBUNDLE"

step "vérification"
check_binary
