#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
NATIVE_INPUTS_MANIFEST="${NATIVE_INPUTS_MANIFEST:-$SCRIPT_DIR/native-inputs.json}"

manifest_value() {
  python3 - "$NATIVE_INPUTS_MANIFEST" "$1" "$2" <<'PY'
import json
import sys

with open(sys.argv[1], encoding="utf-8") as source:
    manifest = json.load(source)
value = manifest["inputs"][sys.argv[2]][sys.argv[3]]
if not isinstance(value, str) or not value:
    raise SystemExit(f"invalid manifest value: {sys.argv[2]}.{sys.argv[3]}")
print(value)
PY
}

FFMPEG_VERSION="$(manifest_value ffmpeg version)"
FFMPEG_URL="$(manifest_value ffmpeg url)"
FFMPEG_SHA256="$(manifest_value ffmpeg sha256)"
SHADERC_VERSION="$(manifest_value shaderc version)"
SHADERC_URL="$(manifest_value shaderc url)"
SHADERC_REF="$(manifest_value shaderc ref)"
SHADERC_COMMIT="$(manifest_value shaderc commit)"
LIBPLACEBO_VERSION="$(manifest_value libplacebo version)"
LIBPLACEBO_URL="$(manifest_value libplacebo url)"
LIBPLACEBO_REF="$(manifest_value libplacebo ref)"
LIBPLACEBO_COMMIT="$(manifest_value libplacebo commit)"
MPV_VERSION="$(manifest_value mpv version)"
MPV_URL="$(manifest_value mpv url)"
MPV_SHA256="$(manifest_value mpv sha256)"

sha256_file() {
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum "$1" | cut -d ' ' -f 1
  else
    shasum -a 256 "$1" | cut -d ' ' -f 1
  fi
}

download_verified() {
  local url="$1"
  local expected_sha256="$2"
  local destination="$3"
  local temporary
  local actual_sha256

  if [[ ! "$expected_sha256" =~ ^[0-9a-f]{64}$ ]]; then
    echo "Invalid SHA-256 pin for $url" >&2
    return 1
  fi

  mkdir -p "$(dirname "$destination")"
  temporary="$(mktemp "${destination}.tmp.XXXXXX")"
  if ! curl \
    --fail \
    --location \
    --silent \
    --show-error \
    --proto '=https,file' \
    --tlsv1.2 \
    --output "$temporary" \
    "$url"; then
    rm -f "$temporary"
    return 1
  fi

  actual_sha256="$(sha256_file "$temporary")"
  if [ "$actual_sha256" != "$expected_sha256" ]; then
    echo "SHA-256 mismatch for $url" >&2
    echo "Expected: $expected_sha256" >&2
    echo "Actual:   $actual_sha256" >&2
    rm -f "$temporary" "$destination"
    return 1
  fi

  mv "$temporary" "$destination"
}

checkout_verified_ref() {
  local url="$1"
  local ref="$2"
  local expected_commit="$3"
  local destination="$4"
  local actual_commit

  if [[ ! "$expected_commit" =~ ^[0-9a-f]{40}$ ]]; then
    echo "Invalid Git commit pin for $url at $ref" >&2
    return 1
  fi

  rm -rf "$destination"
  if ! git clone --quiet --depth 1 --branch "$ref" --no-checkout \
    "$url" "$destination"; then
    rm -rf "$destination"
    return 1
  fi

  actual_commit="$(git -C "$destination" rev-parse 'HEAD^{commit}')"
  if [ "$actual_commit" != "$expected_commit" ]; then
    echo "Git ref mismatch for $url at $ref" >&2
    echo "Expected: $expected_commit" >&2
    echo "Actual:   $actual_commit" >&2
    rm -rf "$destination"
    return 1
  fi

  git -C "$destination" checkout --quiet --detach "$expected_commit"
}

cleanup_srcdir=""

cleanup() {
  if [ -n "$cleanup_srcdir" ]; then
    rm -rf -- "$cleanup_srcdir"
  fi
}

main() {
  local prefix="${PREFIX:-$(pwd)/libmpv-prefix}"
  local jobs="${JOBS:-$(nproc)}"
  local srcdir

  mkdir -p "$prefix"
  prefix="$(realpath "$prefix")"
  export PKG_CONFIG_PATH="$prefix/lib/pkgconfig:$prefix/lib/$(uname -m)-linux-gnu/pkgconfig:${PKG_CONFIG_PATH:-}"

  srcdir="$(mktemp -d)"
  cleanup_srcdir="$srcdir"
  trap cleanup EXIT
  cd "$srcdir"

  echo "==> Sources in $srcdir"
  echo "==> Install prefix: $prefix"
  echo ""

  # ─── Step 1: ffmpeg (static libraries) ─────────────────────────────────────
  echo "==> Building ffmpeg $FFMPEG_VERSION (static, decoder-only)..."
  download_verified "$FFMPEG_URL" "$FFMPEG_SHA256" "$srcdir/ffmpeg.tar.xz"
  tar -xJf "$srcdir/ffmpeg.tar.xz"
  cd "ffmpeg-${FFMPEG_VERSION}"

  ./configure \
    --prefix="$prefix" \
    --enable-gpl \
    --enable-version3 \
    --enable-static \
    --disable-shared \
    --enable-pic \
    --disable-programs \
    --disable-doc \
    --disable-encoders \
    --disable-muxers \
    --enable-muxer=spdif \
    --disable-devices \
    --disable-bsfs \
    --enable-bsf=aac_adtstoasc,av1_metadata,extract_extradata,h264_metadata,h264_mp4toannexb,hevc_metadata,hevc_mp4toannexb,vp9_metadata \
    --disable-filters \
    --enable-filter=aformat,aresample,format,null,scale \
    --enable-gnutls \
    --enable-vaapi \
    --enable-vdpau \
    --disable-debug \
    --disable-stripping

  make -j"$jobs"
  make install
  cd "$srcdir"
  echo ""
  echo "==> ffmpeg done."
  echo ""

  # ─── Step 2: shaderc (static library) ───────────────────────────────────────
  echo "==> Building shaderc $SHADERC_VERSION (static)..."
  checkout_verified_ref \
    "$SHADERC_URL" "$SHADERC_REF" "$SHADERC_COMMIT" \
    "$srcdir/shaderc-v${SHADERC_VERSION}"
  cd "shaderc-v${SHADERC_VERSION}"
  ./utils/git-sync-deps

  cmake -S . -B build \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX="$prefix" \
    -DSHADERC_SKIP_TESTS=ON \
    -DSHADERC_SKIP_EXAMPLES=ON \
    -DSHADERC_SKIP_COPYRIGHT_CHECK=ON \
    -DBUILD_SHARED_LIBS=OFF \
    -DCMAKE_POSITION_INDEPENDENT_CODE=ON

  cmake --build build -j"$jobs"
  cmake --install build
  cd "$srcdir"
  echo ""
  echo "==> shaderc done."
  echo ""

  # ─── Step 3: libplacebo (static library) ───────────────────────────────────
  echo "==> Building libplacebo $LIBPLACEBO_VERSION (static)..."
  checkout_verified_ref \
    "$LIBPLACEBO_URL" "$LIBPLACEBO_REF" "$LIBPLACEBO_COMMIT" \
    "$srcdir/libplacebo-v${LIBPLACEBO_VERSION}"
  cd "libplacebo-v${LIBPLACEBO_VERSION}"
  git submodule update --init --recursive

  meson setup build \
    --prefix="$prefix" \
    --default-library=static \
    -Dvulkan=disabled \
    -Dd3d11=disabled \
    -Ddemos=false \
    -Dtests=false

  ninja -C build -j"$jobs"
  ninja -C build install
  cd "$srcdir"
  echo ""
  echo "==> libplacebo done."
  echo ""

  # ─── Step 4: mpv (shared libmpv) ───────────────────────────────────────────
  echo "==> Building mpv $MPV_VERSION (shared libmpv only)..."
  download_verified "$MPV_URL" "$MPV_SHA256" "$srcdir/mpv.tar.gz"
  tar -xzf "$srcdir/mpv.tar.gz"
  cd "mpv-${MPV_VERSION}"

  meson setup build \
    --prefix="$prefix" \
    -Dlibmpv=true \
    -Dcplayer=false \
    -Dbuild-date=false \
    -Dlua=enabled \
    -Djavascript=enabled \
    -Dcplugins=disabled \
    -Dmanpage-build=disabled \
    -Djack=disabled \
    -Dvulkan=disabled \
    -Dd3d11=disabled \
    -Dgl=enabled \
    -Dvaapi=enabled \
    -Dvdpau=enabled \
    -Dalsa=enabled \
    -Dpulse=enabled \
    -Dpipewire=enabled \
    -Dwayland=disabled \
    -Dx11=enabled

  ninja -C build -j"$jobs"
  ninja -C build install
  echo ""
  echo "==> mpv done."
  echo ""
  echo "==> libmpv build complete. Output in $prefix"
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  main "$@"
fi
