#!/bin/bash
# eastbook-rebuild-1 codec build. Paths and receipts are arguments. Codec flags are fixed.
set -euo pipefail

LIBHEIF=""
LIBHEIF_SHA=""
LIBDE265=""
LIBDE265_SHA=""
WORK=""
EMSDK_DIR=""
CMAKE_BIN=""
RECEIPT=""

while [ $# -gt 0 ]; do
  case "$1" in
    --libheif) LIBHEIF="$2"; shift 2 ;;
    --libheif-sha256) LIBHEIF_SHA="$2"; shift 2 ;;
    --libde265) LIBDE265="$2"; shift 2 ;;
    --libde265-sha256) LIBDE265_SHA="$2"; shift 2 ;;
    --work) WORK="$2"; shift 2 ;;
    --emsdk) EMSDK_DIR="$2"; shift 2 ;;
    --cmake) CMAKE_BIN="$2"; shift 2 ;;
    --receipt) RECEIPT="$2"; shift 2 ;;
    *) echo "unknown argument: $1" >&2; exit 2 ;;
  esac
done

if [ -z "$LIBHEIF" ] || [ -z "$LIBHEIF_SHA" ] || [ -z "$LIBDE265" ] || [ -z "$LIBDE265_SHA" ] || [ -z "$WORK" ] || [ -z "$EMSDK_DIR" ] || [ -z "$CMAKE_BIN" ] || [ -z "$RECEIPT" ]; then
  echo "missing required argument" >&2
  exit 2
fi
if [ ! -f "$LIBHEIF" ] || [ ! -f "$LIBDE265" ] || [ ! -d "$EMSDK_DIR" ] || [ ! -x "$CMAKE_BIN" ]; then
  echo "missing input file or tool" >&2
  exit 2
fi
if [ -e "$WORK" ]; then
  echo "work directory already exists: $WORK" >&2
  exit 2
fi
if [ -e "$RECEIPT" ]; then
  echo "receipt already exists: $RECEIPT" >&2
  exit 2
fi
mkdir -p "$(dirname "$RECEIPT")"

sha256_file() {
  shasum -a 256 "$1" | awk '{print $1}'
}

got_heif="$(sha256_file "$LIBHEIF")"
got_de="$(sha256_file "$LIBDE265")"
if [ "$got_heif" != "$LIBHEIF_SHA" ] || [ "$got_de" != "$LIBDE265_SHA" ]; then
  echo "checksum mismatch" >&2
  echo "libheif $got_heif expected $LIBHEIF_SHA" >&2
  echo "libde265 $got_de expected $LIBDE265_SHA" >&2
  exit 2
fi

python3 - "$LIBHEIF" "$LIBDE265" << 'PY'
import sys
import tarfile

def check(path):
    with tarfile.open(path, "r:gz") as archive:
        for member in archive.getmembers():
            parts = member.name.split("/")
            if member.name.startswith("/") or ".." in parts:
                raise SystemExit("unsafe member " + member.name)
            if member.issym() or member.islnk() or member.isdev():
                raise SystemExit("unsafe link " + member.name)
            if member.name.split("/")[0].startswith("._"):
                raise SystemExit("appledouble " + member.name)

check(sys.argv[1])
check(sys.argv[2])
PY

export EMSDK_QUIET=1
# shellcheck disable=SC1091
source "$EMSDK_DIR/emsdk_env.sh"
export PATH="$(dirname "$CMAKE_BIN"):$PATH"

emcc_line="$(emcc --version | head -1)"
cmake_line="$("$CMAKE_BIN" --version | head -1)"
emcc_version="$(printf '%s\n' "$emcc_line" | awk '{ for (i = 1; i <= NF; i++) if ($i ~ /^[0-9]+\.[0-9]+\.[0-9]+$/) { print $i; exit } }')"
cmake_version="$(printf '%s\n' "$cmake_line" | awk '{ print $3 }')"
if [ "$emcc_version" != "3.1.64" ]; then
  echo "unexpected emcc: $emcc_line" >&2
  exit 2
fi
if [ "$cmake_version" != "3.31.8" ]; then
  echo "unexpected cmake: $cmake_line" >&2
  exit 2
fi

{
  echo "libheif $got_heif"
  echo "libde265 $got_de"
  echo "emcc $emcc_line"
  echo "cmake $cmake_line"
  echo "make $(make --version | head -1)"
  echo "FLAGS ENABLE_LIBDE265=1 LIBDE265_VERSION=1.0.16 ENABLE_AOM=0 ENABLE_WEBCODECS=0 ENABLE_UNCOMPRESSED=0 ENABLE_OPENJPEG=0 STANDALONE=0 DEBUG=0 USE_ES6=0 USE_WASM=0 USE_TYPESCRIPT=0 USE_UNSAFE_EVAL=0 CORES=4"
} > "$RECEIPT"

mkdir "$WORK"
tar -xzf "$LIBHEIF" -C "$WORK"
src="$WORK/libheif-1.23.5"
if [ ! -f "$src/build-emscripten.sh" ]; then
  echo "libheif archive missing build-emscripten.sh" >&2
  exit 2
fi
mkdir "$src/buildjs"
cp "$LIBDE265" "$src/buildjs/libde265-1.0.16.tar.gz"
cd "$src/buildjs"
set +e
CORES=4 \
  ENABLE_LIBDE265=1 \
  LIBDE265_VERSION=1.0.16 \
  ENABLE_AOM=0 \
  ENABLE_WEBCODECS=0 \
  ENABLE_UNCOMPRESSED=0 \
  ENABLE_OPENJPEG=0 \
  STANDALONE=0 \
  DEBUG=0 \
  USE_ES6=0 \
  USE_WASM=0 \
  USE_TYPESCRIPT=0 \
  USE_UNSAFE_EVAL=0 \
  ../build-emscripten.sh .. >> "$RECEIPT" 2>&1
status=$?
set -e
echo "BUILD_EXIT:$status" | tee -a "$RECEIPT"
if [ "$status" -ne 0 ]; then
  exit "$status"
fi
if [ ! -f libheif.js ]; then
  echo "libheif.js missing" >&2
  exit 1
fi
sha256_file libheif.js | tee -a "$RECEIPT"
exit 0
