#!/bin/sh

# Initialise
PKG_LIBS="-lpthread"

# Helper function: find library paths
# Usage: find_lib_paths <lib_name> <header_subdir> <default_libs>
# Sets: LIB_CFLAGS, LIB_LIBS
find_lib_paths() {
  lib_name=$1
  header_subdir=$2
  default_libs=$3
  LIB_CFLAGS=""
  LIB_LIBS="$default_libs"

  if [ "$INCLUDE_DIR" ] || [ "$LIB_DIR" ]; then
    LIB_CFLAGS="-I$INCLUDE_DIR"
    LIB_LIBS="-L$LIB_DIR $LIB_LIBS"
    echo "Found INCLUDE_DIR $INCLUDE_DIR"
    echo "Found LIB_DIR $LIB_DIR"
  elif [ -d "/usr/local/include/$header_subdir" ]; then
    LIB_CFLAGS="-I/usr/local/include"
    LIB_LIBS="-L/usr/local/lib $LIB_LIBS"
  elif [ -d "/usr/include/$header_subdir" ]; then
    LIB_CFLAGS="-I/usr/include"
    LIB_LIBS="-L/usr/lib $LIB_LIBS"
  elif [ -d "/usr/local/opt/$lib_name" ]; then
    LIB_CFLAGS="-I/usr/local/opt/$lib_name/include"
    LIB_LIBS="-L/usr/local/opt/$lib_name/lib $LIB_LIBS"
  fi
}

# Find compiler and export flags
CC=`"${R_HOME}/bin/R" CMD config CC`
CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS`
CPPFLAGS=`"${R_HOME}/bin/R" CMD config CPPFLAGS`
LDFLAGS=`"${R_HOME}/bin/R" CMD config LDFLAGS`
export CC CFLAGS CPPFLAGS LDFLAGS

# C++ standard: the bundled libfswatch requires C++17. R >= 4.3 compiles C++ as
# C++17 by default, so requesting it explicitly is redundant and trips a CRAN
# "please drop specification unless essential" NOTE. Only emit CXX_STD on older
# R, where the default is below C++17.
CXX_STD_LINE=`"${R_HOME}/bin/Rscript" -e 'cat(if (getRversion() < "4.3.0") "CXX_STD = CXX17" else "")'`

# Detect -latomic linker flag for ARM architectures (Raspberry Pi etc.)
echo "#include <stdint.h>
uint64_t v;
int main() {
    return (int)__atomic_load_n(&v, __ATOMIC_ACQUIRE);
}" | ${CC} -xc - -o /dev/null > /dev/null 2>&1
if [ $? -ne 0 ]; then
  echo "Adding -latomic linker flag ..."
  PKG_LIBS="$PKG_LIBS -latomic"
fi

# Determine whether to compile the bundled library
compile_fswatch=0

if [ -n "$WATCHER_LIBS" ]; then
  echo "WATCHER_LIBS is set... building from source"
  compile_fswatch=1
else
  # Find a system libfswatch
  find_lib_paths "fswatch" "libfswatch" "-lfswatch"
  FSWATCH_CFLAGS="$LIB_CFLAGS"
  FSWATCH_LIBS="$LIB_LIBS"

  echo "#include <libfswatch/c/libfswatch.h>
int main() {
#if FSW_OK
    *(void *) 0 = 0;
#endif
}" | ${CC} ${FSWATCH_CFLAGS} -xc - -o /dev/null > /dev/null 2>&1
  if [ $? -ne 0 ]; then
    compile_fswatch=1
  else
    echo "Found 'libfswatch' $FSWATCH_CFLAGS"
    PKG_LIBS="$FSWATCH_LIBS $PKG_LIBS"
  fi
fi

if [ "$compile_fswatch" -eq 1 ]; then
  # Compile the bundled libfswatch in place: put its source tree on the include
  # path and build the POSIX object list (common core + the self-guarding POSIX
  # monitors). The monitors self-guard on platform macros, so no uname-based
  # source selection is needed.
  echo "Compiling bundled 'libfswatch' in place ..."
  PKG_CPPFLAGS="-Ifswatch/libfswatch/src"
  # Single whitespace-separated line: embedded newlines would terminate the make
  # variable assignment.
  FSW_OBJECTS=`tr '\n' ' ' < tools/fsw_objects_posix.list | sed 's/ *$//'`
  case `uname -s` in
    Darwin) PKG_LIBS="$PKG_LIBS -framework CoreServices" ;;
  esac
else
  # System libfswatch: compile against ITS headers only. The bundled tree is
  # deliberately kept off the include path so the package compiles against the
  # same libfswatch version it links. No bundled objects are built.
  PKG_CPPFLAGS="$FSWATCH_CFLAGS"
  FSW_OBJECTS=""
fi

# Write to Makevars
sed -e "s|@cppflags@|$PKG_CPPFLAGS|" \
    -e "s|@libs@|$PKG_LIBS|" \
    -e "s|@fsw_objects@|$FSW_OBJECTS|" \
    -e "s|@cxx_std@|$CXX_STD_LINE|" \
    src/Makevars.in > src/Makevars

# Success
exit 0
