#!/usr/bin/env bash
# FFmpeg (LGPL 2.1+) mínimo para 1B Music en Android: SOLO los demuxers/decoders de audio que Media3 no trae
# (design §10 A7). Bibliotecas COMPARTIDAS (.so separadas de nuestro JNI, decisión de B1b: cumplir la LGPL dejando
# sustituir FFmpeg sin recompilar la app), -Os, sin programas, sin red, sin GPL ni nonfree. Con --target-os=android
# el soname no lleva versión (libavcodec.so), como exige el empaquetado de Android.
#
#   tools/build-ffmpeg-android.sh            # compila las ABIs que falten (no hace nada si ya están)
#   tools/build-ffmpeg-android.sh --root     # imprime el directorio de salida y sale
#   ABIS="arm64-v8a" tools/build-ffmpeg-android.sh
#
# Salida (caché fuera de git, compartida entre worktrees/clones):
#   ${ONEB_FFMPEG_CACHE:-~/.cache/1bmusic-ffmpeg}/<versión>-<hash de este script>/<abi>/{include,lib/*.so}
# La clave incluye el hash de ESTE fichero: cambiar la configuración = otra carpeta (nunca se mezclan).
# La fuente se descarga de ffmpeg.org a build/ffmpeg-src/ (comprobada con SHA-256) y se compila en build/ffmpeg-build/.
# Lo invoca Gradle (:androidApp, tarea ffmpegPrebuilt) antes de la compilación nativa; un clon limpio solo necesita
# el NDK (ndkVersion de androidApp/build.gradle.kts) y conexión la primera vez.
set -euo pipefail

FFMPEG_VERSION=9.0.2
FFMPEG_SHA256=8c3850283eb25fa026482078a04051e0be17347b09ef81a0849bec15a96e002e
NDK_VERSION=${NDK_VERSION:-30.0.16248370}
API=30 # = minSdk

REPO=$(cd "$(dirname "$0")/.." && pwd)
KEY=$(sha256sum "$0" | cut -c1-12)
ROOT=${ONEB_FFMPEG_CACHE:-$HOME/.cache/1bmusic-ffmpeg}/$FFMPEG_VERSION-$KEY
if [ "${1:-}" = "--root" ]; then echo "$ROOT"; exit 0; fi
ABIS=${ABIS:-"arm64-v8a armeabi-v7a x86_64"}

SDK=${ANDROID_HOME:-${ANDROID_SDK_ROOT:-$HOME/Android/Sdk}}
NDK=${ANDROID_NDK_HOME:-$SDK/ndk/$NDK_VERSION}
[ -d "$NDK" ] || { echo "Falta el NDK $NDK_VERSION: $SDK/cmdline-tools/latest/bin/sdkmanager --install \"ndk;$NDK_VERSION\"" >&2; exit 1; }
TC=$NDK/toolchains/llvm/prebuilt/linux-x86_64

# ---------------------------------------------------------------- componentes (todos LGPL)
DEMUXERS=ape,wv,tta,mpc,mpc8,asf,aiff,iff,dsf,ogg,caf
DECODERS=ape,wavpack,tta,mpc7,mpc8,wmav1,wmav2,wmapro,wmalossless,speex,opus,vorbis,alac
DECODERS+=,dsd_lsbf,dsd_lsbf_planar,dsd_msbf,dsd_msbf_planar,dst
DECODERS+=,pcm_s8,pcm_u8,pcm_s16be,pcm_s16le,pcm_s24be,pcm_s24le,pcm_s32be,pcm_s32le,pcm_f32be,pcm_f32le
DECODERS+=,pcm_f64be,pcm_f64le,pcm_alaw,pcm_mulaw,adpcm_ima_qt,mace3,mace6
PARSERS=vorbis,opus

all_built() { for a in $ABIS; do [ -f "$ROOT/$a/.done" ] || return 1; done; }
if all_built; then echo "FFmpeg $FFMPEG_VERSION ya compilado en $ROOT"; exit 0; fi

SRC_DIR=$REPO/build/ffmpeg-src
TARBALL=$SRC_DIR/ffmpeg-$FFMPEG_VERSION.tar.xz
mkdir -p "$SRC_DIR"
if [ ! -f "$TARBALL" ]; then
  curl -fL --retry 3 -o "$TARBALL.part" "https://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.xz"
  mv "$TARBALL.part" "$TARBALL"
fi
echo "$FFMPEG_SHA256  $TARBALL" | sha256sum -c --quiet
SRC=$SRC_DIR/ffmpeg-$FFMPEG_VERSION
[ -f "$SRC/configure" ] || tar -C "$SRC_DIR" -xf "$TARBALL"

JOBS=${JOBS:-3}
for ABI in $ABIS; do
  [ -f "$ROOT/$ABI/.done" ] && continue
  case $ABI in
    arm64-v8a)   ARCH=aarch64; CPU=armv8-a;  TRIPLE=aarch64-linux-android;     EXTRA=(); ECF="" ;;
    armeabi-v7a) ARCH=arm;     CPU=armv7-a;  TRIPLE=armv7a-linux-androideabi;  EXTRA=(--enable-neon); ECF="-mfpu=neon -mfloat-abi=softfp" ;;
    x86_64)      ARCH=x86_64;  CPU=x86-64;   TRIPLE=x86_64-linux-android;      EXTRA=(--disable-x86asm); ECF="" ;;
    *) echo "ABI no soportada: $ABI" >&2; exit 1 ;;
  esac
  B=$REPO/build/ffmpeg-build/$ABI
  rm -rf "$B"; mkdir -p "$B"
  echo "== FFmpeg $FFMPEG_VERSION → $ABI"
  (
    cd "$B"
    "$SRC/configure" \
      --prefix="$ROOT/$ABI" \
      --target-os=android --arch=$ARCH --cpu=$CPU --enable-cross-compile \
      --cc="$TC/bin/$TRIPLE$API-clang" --cxx="$TC/bin/$TRIPLE$API-clang++" \
      --ar="$TC/bin/llvm-ar" --nm="$TC/bin/llvm-nm" --ranlib="$TC/bin/llvm-ranlib" --strip="$TC/bin/llvm-strip" \
      --disable-static --enable-shared --enable-pic --enable-small --disable-debug \
      --disable-programs --disable-doc --disable-network --disable-autodetect --disable-iconv --disable-pthreads \
      --disable-avdevice --disable-avfilter --disable-swscale --enable-swresample \
      --disable-everything \
      --enable-demuxer=$DEMUXERS --enable-decoder=$DECODERS --enable-parser=$PARSERS \
      --extra-cflags="-Os -ffunction-sections -fdata-sections $ECF" \
      --extra-ldflags="-Wl,--gc-sections -Wl,-z,max-page-size=16384" \
      "${EXTRA[@]}" > configure.log 2>&1 || { tail -30 configure.log; exit 1; }
    # Comprobación de licencia: nada de GPL/nonfree.
    grep -q '^#define CONFIG_GPL 0' config.h && grep -q '^#define CONFIG_NONFREE 0' config.h
    make -j"$JOBS" > make.log 2>&1 || { tail -40 make.log; exit 1; }
    make install > install.log 2>&1
    # Sin dependencias versionadas ni rutas absolutas (Android carga libX.so por nombre desde la APK).
    for so in "$ROOT/$ABI"/lib/lib*.so; do
      "$TC/bin/llvm-readelf" -d "$so" | grep -E 'NEEDED|SONAME' | grep -E '\.so\.[0-9]' && { echo "soname versionado en $so" >&2; exit 1; } || true
    done
  )
  cp "$SRC/COPYING.LGPLv2.1" "$ROOT/$ABI/COPYING.LGPLv2.1"
  echo "$FFMPEG_VERSION $DEMUXERS $DECODERS" > "$ROOT/$ABI/.done"
done
echo "FFmpeg $FFMPEG_VERSION en $ROOT"
