#! /bin/sh

##########################################################################
# Copyright (c) 2023, King Abdullah University of Science and Technology
# All rights reserved.
# MPCR is an R package provided by the STSDS group at KAUST
##########################################################################


# Function to install CMake from source
install_cmake() {
  echo "CMake not found. Installing CMake from source..."

  # Create a temporary directory for building CMake
  temp_dir=$(mktemp -d)
  cd "$temp_dir" || exit 1

  # Download CMake source code
  wget https://github.com/Kitware/CMake/releases/download/v3.28.1/cmake-3.28.1.tar.gz

  # Extract the source code
  tar -xzvf cmake-3.28.1.tar.gz

  # Enter the extracted directory
  cd cmake-3.28.1 || exit 1

  # Configure, build, and install CMake to the specified location
  ./bootstrap --prefix="$install_dir" --parallel=8 -- -DCMAKE_USE_OPENSSL=OFF
  make -j 8
  sudo make install

  # Clean up
  cd "$temp_dir" || exit 1
  rm -rf "$temp_dir"
}


cd "$(dirname "$0")"

OS_NAME=$(uname -s)
echo $OS_TYPE
echo "------------------------------------------------------------"

case "$OS_NAME" in
  Darwin*)
    case "$1" in
      /*)
        ABSOLUE_PATH="$1"
        ;;
      *)
        ABSOLUE_PATH="$PWD/${1#./}"
        ;;
    esac
    ;;
  *)
    ABSOLUE_PATH=$(dirname $(realpath "$0"))
    ;;
esac

BUILDING_EXAMPLES="OFF"
BUILDING_TESTS="OFF"
INSTALL_PATH="/usr/local"
VERBOSE=OFF
CONFIG_PATH="${ABSOLUE_PATH}/config"
echo ${ABSOLUE_PATH}

mv "${ABSOLUE_PATH}/src/cmake/" "${ABSOLUE_PATH}/cmake"
mv "${ABSOLUE_PATH}/src/CMakeLists_inv.txt" "${ABSOLUE_PATH}/CMakeLists.txt"

rm -rf bin/
mkdir bin/

# Check if cmake is installed
if command -v cmake /dev/null 2>&1; then
  # Save the installation directory to the variable
  cmake_install_dir=$(command -v cmake | xargs dirname)
  echo "CMake is installed in: $cmake_install_dir"
  cmake_command_bin=cmake
elif [ -x "/Applications/CMake.app/Contents/bin/cmake" ]; then
  echo "CMake found in /Applications/CMake.app/Contents/bin/cmake."
  cmake_install_dir="/Applications/CMake.app/Contents/bin"
  cmake_command_bin="${cmake_install_dir}/cmake"
else
  echo "Installing CMake from source"
  mkdir "${ABSOLUTE_PATH}/inst/_deps/"
  install_dir="${ABSOLUTE_PATH}/inst/_deps/"
  install_cmake "$install_dir"
  cmake_command_bin="${ABSOLUTE_PATH}/inst/_deps/bin/cmake"
fi


"$cmake_command_bin" -DCMAKE_BUILD_TYPE=RELEASE \
  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
  -DMPCR_BUILD_TESTS=$BUILDING_TESTS \
  -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH \
  -DCMAKE_CONFIG_PREFIX="$CONFIG_PATH" \
  -DCMAKE_VERBOSE_MAKEFILE:BOOL=$VERBOSE \
  -H"${ABSOLUE_PATH}" \
  -B"${ABSOLUE_PATH}/bin" \
  -DRUNNING_CPP=OFF \
  -DBUILD_MPCR_STATIC="OFF"\
  -DBUILD_SHARED_LIBS=OFF


cd bin/

# Fix musl compilation: Add missing <cstdint> to all blaspp headers that use int64_t
if [ -d "_deps/blaspp-src/include" ]; then
  echo "Patching BLAS++ headers for musl compatibility..."
  find _deps/blaspp-src/include -name "*.hh" -o -name "*.h" | while read -r header; do
    if grep -q 'int64_t\|uint64_t\|int32_t\|uint32_t\|int16_t\|uint16_t' "$header" 2>/dev/null; then
      if ! grep -q '#include <cstdint>' "$header" 2>/dev/null; then
        echo "  Patching $(basename $header)..."
        sed -i '1i #include <cstdint>' "$header" 2>/dev/null || \
        sed -i '' '1i\
#include <cstdint>
' "$header" 2>/dev/null
      fi
    fi
  done
fi

make clean
make all -j 2

case "$OS_NAME" in
  Darwin*)
    cp "${ABSOLUE_PATH}/bin/src/libmpcr.dylib" "${ABSOLUE_PATH}/src/MPCR.so" || echo "Failed: libmpcr.dylib -> src"
    ;;
  *)
    cp "${ABSOLUE_PATH}/bin/src/libmpcr.so" "${ABSOLUE_PATH}/src/MPCR.so" || echo "Failed: libmpcr.so -> src"
    ;;
esac
${R_HOME}/bin/Rscript "${ABSOLUE_PATH}/cmake/CreateSymbolTable.R" "${ABSOLUE_PATH}/bin/" "${ABSOLUE_PATH}/src/symbols.rds"

rm -rf "${ABSOLUE_PATH}/bin/"
