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

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$ROOT/tools/macos_build_settings.sh"

LLVM_VERSION="22.1.8"
LLVM_ARCHIVE_NAME="llvm-project-${LLVM_VERSION}.src.tar.xz"
LLVM_ARCHIVE_SHA256="922f1817a0df7b1489272d18134ee0087a8b068828f87ac63b9861b1a9965888"
LLVM_ARCHIVE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/${LLVM_ARCHIVE_NAME}"
CACHE_DIR="${FILMBUDDY_LLVM_SOURCE_CACHE:-$ROOT/vendor-local/llvm-source-cache}"
ARCHIVE="${FILMBUDDY_LLVM_SOURCE_ARCHIVE:-$CACHE_DIR/$LLVM_ARCHIVE_NAME}"
SOURCE_DIR="$CACHE_DIR/llvm-project-${LLVM_VERSION}.src"
BUILD_DIR="$ROOT/build/vendor/libomp-${LLVM_VERSION}-macos${FILMBUDDY_MACOS_DEPLOYMENT_TARGET}-${FILMBUDDY_BUILD_ARCH}"
INSTALL_DIR="$BUILD_DIR/install"
LIBOMP_DYLIB="$INSTALL_DIR/lib/libomp.dylib"
LIBOMP_LICENSE_SOURCE="$SOURCE_DIR/openmp/LICENSE.TXT"
LIBOMP_LICENSE="$INSTALL_DIR/share/licenses/libomp/LICENSE.TXT"

log() { printf '%s\n' "$*" >&2; }

install_license() {
  if [[ ! -s "$LIBOMP_LICENSE_SOURCE" && -f "$ARCHIVE" ]]; then
    mkdir -p "$CACHE_DIR"
    tar -xf "$ARCHIVE" -C "$CACHE_DIR" \
      "llvm-project-${LLVM_VERSION}.src/openmp/LICENSE.TXT"
  fi
  if [[ ! -s "$LIBOMP_LICENSE_SOURCE" ]]; then
    echo "error: pinned libomp license is unavailable at $LIBOMP_LICENSE_SOURCE" >&2
    exit 1
  fi
  mkdir -p "$(dirname "$LIBOMP_LICENSE")"
  cp "$LIBOMP_LICENSE_SOURCE" "$LIBOMP_LICENSE"
}

if [[ -f "$LIBOMP_DYLIB" ]]; then
  install_license
  filmbuddy_verify_macos_binary "$LIBOMP_DYLIB"
  printf '%s\n' "$INSTALL_DIR"
  exit 0
fi

for tool in curl cmake shasum tar; do
  if ! command -v "$tool" >/dev/null 2>&1; then
    echo "error: required build tool '$tool' is unavailable" >&2
    exit 1
  fi
done

mkdir -p "$CACHE_DIR" "$ROOT/build/vendor"
if [[ ! -f "$ARCHIVE" ]]; then
  log "[libomp] downloading pinned LLVM $LLVM_VERSION source"
  curl -L --fail --retry 3 -o "$ARCHIVE.partial" "$LLVM_ARCHIVE_URL" >&2
  mv "$ARCHIVE.partial" "$ARCHIVE"
fi

ACTUAL_SHA256="$(shasum -a 256 "$ARCHIVE" | awk '{print $1}')"
if [[ "$ACTUAL_SHA256" != "$LLVM_ARCHIVE_SHA256" ]]; then
  echo "error: LLVM source checksum mismatch for $ARCHIVE" >&2
  echo "expected: $LLVM_ARCHIVE_SHA256" >&2
  echo "actual:   $ACTUAL_SHA256" >&2
  exit 1
fi

if [[ ! -d "$SOURCE_DIR/openmp" || ! -d "$SOURCE_DIR/cmake" ]]; then
  log "[libomp] extracting the pinned OpenMP source"
  rm -rf "$SOURCE_DIR"
  tar -xf "$ARCHIVE" -C "$CACHE_DIR" \
    "llvm-project-${LLVM_VERSION}.src/openmp" \
    "llvm-project-${LLVM_VERSION}.src/cmake"
fi

install_license

log "[libomp] configuring macOS $FILMBUDDY_MACOS_DEPLOYMENT_TARGET / $FILMBUDDY_BUILD_ARCH"
cmake_path_flags=()
if [[ -n "${FILMBUDDY_LIBOMP_FILE_PREFIX_MAP_TO:-}" ]]; then
  # LLVM's assertion strings embed __FILE__. Release verification maps a clean
  # extraction to the source prefix found in the shipped dylib so path-only
  # differences do not defeat the unsigned byte-for-byte comparison.
  file_prefix_map="-ffile-prefix-map=$SOURCE_DIR=${FILMBUDDY_LIBOMP_FILE_PREFIX_MAP_TO%/}"
  cmake_path_flags+=(
    "-DCMAKE_C_FLAGS=$file_prefix_map"
    "-DCMAKE_CXX_FLAGS=$file_prefix_map"
  )
fi
cmake -S "$SOURCE_DIR/openmp" -B "$BUILD_DIR" \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_OSX_ARCHITECTURES="$FILMBUDDY_BUILD_ARCH" \
  -DCMAKE_OSX_DEPLOYMENT_TARGET="$FILMBUDDY_MACOS_DEPLOYMENT_TARGET" \
  -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \
  -DLIBOMP_INSTALL_ALIASES=OFF \
  -DOPENMP_ENABLE_LIBOMPTARGET=OFF \
  -DOPENMP_ENABLE_OMPT_TOOLS=OFF \
  -DOPENMP_ENABLE_LIBOMP_PROFILING=OFF \
  "${cmake_path_flags[@]}" >&2

log "[libomp] building"
cmake --build "$BUILD_DIR" --target install -j"$(sysctl -n hw.logicalcpu 2>/dev/null || echo 8)" >&2

if [[ ! -f "$LIBOMP_DYLIB" ]]; then
  echo "error: compatible libomp was not produced at $LIBOMP_DYLIB" >&2
  exit 1
fi
filmbuddy_verify_macos_binary "$LIBOMP_DYLIB"
printf '%s\n' "$INSTALL_DIR"
