# Anticonf script by Pacha (2025)

PKG_CONFIG_NAME="capybara"

# This is to adhere to CRAN policy about not forcing -O3 and other optimizations
for arg in "$@"; do
  case "$arg" in
    --enable-optimization)
      ENABLE_OPTIMIZATION=yes
      ;;
  esac
done

# Find compiler
CXX=$(${R_HOME}/bin/R CMD config CXX)
CXXFLAGS=$(${R_HOME}/bin/R CMD config CXXFLAGS)
CPPFLAGS=$(${R_HOME}/bin/R CMD config CPPFLAGS)

# Set optimization flags if requested
OPTFLAGS=""
if [ "$ENABLE_OPTIMIZATION" = "yes" ]; then
  # Test for -O3 support
  save_CXXFLAGS="$CXXFLAGS"
  echo 'int main(){return 0;}' > conftest.cpp
  if $CXX $CXXFLAGS -O3 conftest.cpp -o conftest >/dev/null 2>&1; then 
    OPTFLAGS="-O3"
  else
    echo "Warning: compiler does not support -O3, falling back to -O2"
    OPTFLAGS="-O2"
  fi
  rm -f conftest conftest.cpp
  CXXFLAGS="$save_CXXFLAGS"

  # 2) Add the rest unconditionally (they typically don’t hurt
  #    if they’re unsupported, but you could test them similarly)
  OPTFLAGS="$OPTFLAGS -funroll-loops -march=native"
  
  # Check for AVX2 support
  if grep -q avx2 /proc/cpuinfo 2>/dev/null; then
    OPTFLAGS="$OPTFLAGS -mavx2"
  fi

  echo "Using optimization flags: $OPTFLAGS"
else
  echo "Not using optimization flags"
fi

# Link BLAS/LAPACK against MKL if MKLROOT is set
R_BLAS_LIBS=$("${R_HOME}/bin/R" CMD config BLAS_LIBS)
R_LAPACK_LIBS=$("${R_HOME}/bin/R" CMD config LAPACK_LIBS)
R_FLIBS=$("${R_HOME}/bin/R" CMD config FLIBS)

: ${BLAS_LIBS:="$R_BLAS_LIBS"}
: ${LAPACK_LIBS:="$R_LAPACK_LIBS"}
: ${FLIBS:="$R_FLIBS"}

if [ -n "$MKLROOT" ]; then
  echo "detected MKLROOT=$MKLROOT → linking BLAS/LAPACK via MKL"
  BLAS_LIBS="-L${MKLROOT}/lib/intel64_lin -lmkl_rt"
  LAPACK_LIBS="$BLAS_LIBS"
fi

# Check for OpenMP support
OPENMP_FLAG=""
for flag in -fopenmp -qopenmp -openmp -xopenmp; do
  save_CXXFLAGS="$CXXFLAGS"
  CXXFLAGS="$CXXFLAGS $flag"
  
  echo "int main() { return 0; }" | $CXX -xc++ -E $CXXFLAGS - >/dev/null 2>&1
  if [ $? -eq 0 ]; then
    OPENMP_FLAG="$flag"
    break
  fi
  CXXFLAGS="$save_CXXFLAGS"
done

# Determine number of cores using OpenMP if available
if [ -n "$CAPYBARA_NCORES" ]; then
  num_cores="$CAPYBARA_NCORES"
  echo "using environment value: $num_cores"
else
  cat > nthreads.cpp << 'EOL'
#include <iostream>
#ifdef _OPENMP
  #include <omp.h>
#endif

int main() {
  int nthreads;
  #ifdef _OPENMP
    nthreads = std::max(1, (omp_get_max_threads() + 1) / 2);
  #else
    nthreads = 1;
  #endif
  std::cout << nthreads << std::endl;
  return 0;
}
EOL

  # Need to compile WITH the OpenMP flag
  if [ -n "$OPENMP_FLAG" ]; then
    $CXX nthreads.cpp -o nthreads $OPENMP_FLAG
  else
    $CXX nthreads.cpp -o nthreads
  fi
  
  # Check if compilation succeeded
  if [ $? -eq 0 ] && [ -x ./nthreads ]; then
    num_cores=$(./nthreads)
    echo "Number of available cores: $num_cores"
  else
    echo "OpenMP test failed, defaulting to 1"
    num_cores=1
  fi

  # Clean up
  rm -f nthreads nthreads.cpp
fi

# Write to Makevars
echo "creating src/Makevars"
sed -e "s|@ncores@|${num_cores}|g" \
    -e "s|@OPTFLAGS@|${OPTFLAGS}|g" \
    -e "s|@PKG_CXXFLAGS@|${PKG_CXXFLAGS}|g" \
    -e "s|@PKG_LIBS@|${PKG_LIBS}|g" \
    src/Makevars.in > src/Makevars

# Success
exit 0
