#!/usr/bin/env bash
# B54: builds AirdateCore/Vendor/Libav.xcframework — a decoders-only, LGPL-only FFmpeg
# (TrueHD/MLP + DTS) plus the LibavShim, as ONE dynamic framework per slice.
# Reproducible: pinned tag + SHA-256. Run from the repo root. Takes ~10 min.
set -euo pipefail
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer

FFMPEG_VERSION="7.1.2"
FFMPEG_SHA256="089bc60fb59d6aecc5d994ff530fd0dcb3ee39aa55867849a2bbc4e555f9c304"   # tarball gpg-verified 2026-10-01 (.asc good signature); see Vendor/Libav/BUILD.md
ROOT="$(pwd)"
WORK="$ROOT/build/libav"
# FFmpeg's configure cannot do out-of-tree builds from a source path containing whitespace
# (this repo lives under "Claude Projects"), so scratch goes to a space-free cache dir then.
case "$ROOT" in *[[:space:]]*) WORK="$HOME/Library/Caches/reelhouse-libav" ;; esac
OUT="$ROOT/AirdateCore/Vendor/Libav.xcframework"
SHIM="$ROOT/AirdateCore/Vendor/Libav/shim"
mkdir -p "$WORK"
# Only the shim's C API leaves the framework; -all_load would otherwise export ~1170 av_* symbols.
EXPORTS="$WORK/libav.exports"
printf '_ls_*\n' > "$EXPORTS"

TARBALL="$WORK/ffmpeg-$FFMPEG_VERSION.tar.xz"
[ -f "$TARBALL" ] || curl -fL "https://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.xz" -o "$TARBALL"
ACTUAL="$(shasum -a 256 "$TARBALL" | cut -d' ' -f1)"
if [ "$FFMPEG_SHA256" != "$ACTUAL" ]; then
  echo "SHA-256 mismatch: expected $FFMPEG_SHA256, got $ACTUAL" >&2; exit 1
fi
rm -rf "$WORK/src" && mkdir -p "$WORK/src" && tar -xf "$TARBALL" -C "$WORK/src" --strip-components 1

CONFIGURE_FLAGS=(
  --disable-everything --disable-gpl --disable-nonfree --disable-autodetect
  --disable-programs --disable-doc --disable-network
  --disable-avformat --disable-avdevice --disable-avfilter --disable-swresample --disable-swscale
  --disable-shared --enable-static --enable-pic
  --enable-decoder=truehd,mlp,dca
)

# name sdk clang-target minos-flag
SLICES=(
  "tvos appletvos arm64-apple-tvos26.0"
  "tvos-sim appletvsimulator arm64-apple-tvos26.0-simulator"
  "ios iphoneos arm64-apple-ios26.0"
  "ios-sim iphonesimulator arm64-apple-ios26.0-simulator"
  "macos macosx arm64-apple-macos14.0"
)

FRAMEWORKS=()
for slice in "${SLICES[@]}"; do
  read -r NAME SDK TARGET <<<"$slice"
  SYSROOT="$(xcrun --sdk "$SDK" --show-sdk-path)"
  CC="$(xcrun --sdk "$SDK" -f clang)"
  B="$WORK/$NAME"; rm -rf "$B"; mkdir -p "$B"
  ( cd "$B" && "$WORK/src/configure" "${CONFIGURE_FLAGS[@]}" \
      --prefix="$B/install" --enable-cross-compile --target-os=darwin --arch=aarch64 \
      --cc="$CC" --sysroot="$SYSROOT" \
      --extra-cflags="-target $TARGET -isysroot $SYSROOT" \
      --extra-ldflags="-target $TARGET -isysroot $SYSROOT" \
    && make -j"$(sysctl -n hw.ncpu)" && make install ) > "$B/build.log" 2>&1 \
    || { echo "FFmpeg build failed for $NAME — see $B/build.log" >&2; tail -40 "$B/build.log" >&2; exit 1; }

  "$CC" -target "$TARGET" -isysroot "$SYSROOT" -I"$B/install/include" -O2 -fPIC \
        -c "$SHIM/LibavShim.c" -o "$B/LibavShim.o"

  if [ "$NAME" = macos ]; then
    FW="$B/fw/Libav.framework"; V="$FW/Versions/A"
    mkdir -p "$V/Headers" "$V/Modules" "$V/Resources"
    BIN="$V/Libav"; PLIST="$V/Resources/Info.plist"; HDR="$V/Headers"; MOD="$V/Modules"
  else
    FW="$B/fw/Libav.framework"; mkdir -p "$FW/Headers" "$FW/Modules"
    BIN="$FW/Libav"; PLIST="$FW/Info.plist"; HDR="$FW/Headers"; MOD="$FW/Modules"
  fi
  "$CC" -dynamiclib -target "$TARGET" -isysroot "$SYSROOT" \
        -install_name @rpath/Libav.framework/Libav -compatibility_version 1 -current_version 1 \
        "$B/LibavShim.o" -Wl,-exported_symbols_list,"$EXPORTS" -Wl,-all_load "$B/install/lib/libavcodec.a" "$B/install/lib/libavutil.a" \
        -lm -o "$BIN"
  cp "$SHIM/LibavShim.h" "$HDR/"
  cp "$SHIM/module.modulemap" "$MOD/"
  case "$NAME" in
    tvos) PLAT=AppleTVOS; MINOS=26.0 ;; tvos-sim) PLAT=AppleTVSimulator; MINOS=26.0 ;;
    ios) PLAT=iPhoneOS; MINOS=26.0 ;; ios-sim) PLAT=iPhoneSimulator; MINOS=26.0 ;;
    macos) PLAT=MacOSX; MINOS=14.0 ;;
  esac
  cat > "$PLIST" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
  <key>CFBundleDevelopmentRegion</key><string>en</string>
  <key>CFBundleExecutable</key><string>Libav</string>
  <key>CFBundleIdentifier</key><string>net.reelhouse.libav</string>
  <key>CFBundleInfoDictionaryVersion</key><string>6.0</string>
  <key>CFBundleName</key><string>Libav</string>
  <key>CFBundlePackageType</key><string>FMWK</string>
  <key>CFBundleShortVersionString</key><string>$FFMPEG_VERSION</string>
  <key>CFBundleVersion</key><string>1</string>
  <key>CFBundleSupportedPlatforms</key><array><string>$PLAT</string></array>
  <key>MinimumOSVersion</key><string>$MINOS</string>
</dict></plist>
PLIST
  if [ "$NAME" = macos ]; then
    ( cd "$FW/Versions" && ln -sfn A Current )
    ( cd "$FW" && ln -sfn Versions/Current/Libav Libav && ln -sfn Versions/Current/Headers Headers \
               && ln -sfn Versions/Current/Modules Modules && ln -sfn Versions/Current/Resources Resources )
  fi
  FRAMEWORKS+=(-framework "$FW")
done

rm -rf "$OUT"
xcodebuild -create-xcframework "${FRAMEWORKS[@]}" -output "$OUT"
echo "built $OUT"
du -sh "$OUT"/*/Libav.framework
