#!/bin/bash
#
# Guess values for system-dependent variables and create Makefiles.
#

# usage message
usage()
{
  cat <<_EOF
Usage: $0 [OPTION]... [VAR=VALUE]...

Configuration:
  -h, --help              display this help and exit
  --enable-shared-mongoc  link the mongoc shared library
  --enable-shared-lz4     link the lz4 shared library
  --enable-shared-glog    link the glog shared library
  --enable-gui-mod        compile and link with QtGui module
  --enable-debug          compile with debugging information
  --spec=SPEC             use SPEC as QMAKESPEC

Installation directories:
  --prefix=PREFIX       install files in PREFIX [$PREFIX]

Fine tuning of the installation directories:
  --bindir=DIR          user executables [$BINDIR]
  --libdir=DIR          object code libraries [$LIBDIR]
  --includedir=DIR      C++ header files [$INCLUDEDIR]
  --datadir=DIR         read-only architecture-independent data [$DATADIR]
_EOF
}

# absorbs the difference of GNU sed and BSD sed
replace()
{
  [ ! -f "$2" ] && return
  sed -e "$1" "$2" > "$2".$$
  mv -f "$2".$$ "$2"
}

# check the platform
if ! which uname >/dev/null 2>&1; then
  echo "uname: command not found"
  exit
fi

# default values
BASEDIR=`pwd`/`dirname $0`
KERNEL=`uname -s`
MACHINE=`uname -m`
RELEASE=`uname -r`
NPROC=`nproc 2>/dev/null`

if [ "$KERNEL" = "Darwin" ]; then
  PREFIX=/usr/local
else
  PREFIX=/usr
fi
BINDIR=$PREFIX/bin
LIBDIR=$PREFIX/lib
INCLUDEDIR=$PREFIX/include/treefrog
DATADIR=$PREFIX/share/treefrog
CMAKE=cmake

# parse options
while [ -n "`echo $1 | grep '-'`" ]; do
  case $1 in
  *=?*) optarg=`expr "X$1" : '[^=]*=\(.*\)'` ;;
  *=)   optarg= ;;
  *)    optarg=yes ;;
  esac

  case $1 in
    --prefix=*)
      PREFIX=$optarg
      BINDIR=$PREFIX/bin
      LIBDIR=$PREFIX/lib
      INCLUDEDIR=$PREFIX/include/treefrog
      DATADIR=$PREFIX/share/treefrog
      ;;
    --bindir=*)
      BINDIR=$optarg
      ;;
    --libdir=*)
      LIBDIR=$optarg
      ;;
    --includedir=*)
      INCLUDEDIR=$optarg
      ;;
    --datadir=*)
      DATADIR=$optarg
      ;;
    --enable-debug | --enable-debug=*)
      ENABLE_DEBUG=yes
      ;;
    --enable-gui-mod | --enable-gui-mod=*)
      ENABLE_GUI="use_gui=1"
      ;;
    --enable-shared-mongoc | --enable-shared-mongoc=*)
      ENABLE_SHARED_MONGOC="enable_shared_mongoc=1"
      ;;
    --enable-shared-lz4 | --enable-shared-lz4=*)
      ENABLE_SHARED_LZ4="enable_shared_lz4=1"
      ;;
    --enable-shared-glog | --enable-shared-glog=*)
      ENABLE_SHARED_GLOG="enable_shared_glog=1"
      ;;
    --spec=*)
      SPEC=$optarg
      ;;
    --help | -help | -h | *)
      usage
      exit
      ;;
  esac
  shift
done

# spec
if [ "$SPEC" != "" ]; then
  OPT="-spec $SPEC"
elif [ "$QMAKESPEC" != "" ]; then
  OPT="-spec $QMAKESPEC"
elif [ "$KERNEL" = "Darwin" ]; then  # macOS
  OPT="-spec macx-clang"
elif [ "$KERNEL" = "Linux" ]; then
  OPT="-spec linux-g++"
elif [ "$KERNEL" = "FreeBSD" ]; then
  OPT="-spec freebsd-clang"
fi

# x64 config
if [ "$KERNEL" = "Darwin" ]; then  # macOS
  REL=`echo $RELEASE | tr -d '.'`
  if [ "$REL" -ge  1050 ]; then
    OPT="$OPT CONFIG+=x86_64"
  fi

  if [ "$MACHINE" = "ppc" ]; then
    OPT="$OPT CONFIG+=ppc"
  fi
else
  if [[ "$SPEC" =~ "wasm" ]]; then
    OPT=
    CMAKE="emcmake cmake"
    CC=emcc
    AR=emar
  elif [ "$MACHINE" = "x86_64" ]; then
    OPT="$OPT CONFIG+=x86_64"
  fi
fi

cd "$BASEDIR"
replace "s|unix:LIBS +=.*$|unix:LIBS += -Wl,-rpath,. -Wl,-rpath,$LIBDIR -L$LIBDIR -ltreefrog
|" defaults/appbase.pri
replace "s|unix:INCLUDEPATH +=.*$|unix:INCLUDEPATH += $INCLUDEDIR
|" defaults/appbase.pri

if [ -n "$ENABLE_DEBUG" ]; then
  OPT="$OPT CONFIG+=debug"
else
  OPT="$OPT CONFIG+=release"
fi

# search qmake command
if [ -z "$QMAKE" ]; then
  which qmake-qt5 >/dev/null 2>&1 && QMAKE=qmake-qt5
  which qmake     >/dev/null 2>&1 && QMAKE=qmake
  which qmake6    >/dev/null 2>&1 && QMAKE=qmake6

  if [ -z "$QMAKE" ]; then
    echo "qmake: command not found"
    echo
    exit 1
  fi
fi

if ! which cmake >/dev/null 2>&1; then
  echo "cmake: command not found"
  echo
  exit 1
fi

if [ -n "$ENABLE_SHARED_MONGOC" ] && ! which pkg-config >/dev/null 2>&1; then
  echo "pkg-config: command not found"
  echo
  exit 1
fi

if [ -n "$ENABLE_SHARED_GLOG" ] && ! which pkg-config >/dev/null 2>&1; then
  echo "pkg-config: command not found"
  echo
  exit 1
fi

# src
cd "$BASEDIR/src"
rm -f .qmake.stash
[ -f Makefile ] && make -k distclean >/dev/null 2>&1
$QMAKE $OPT target.path=\"$LIBDIR\" header.path=\"$INCLUDEDIR\" $ENABLE_GUI $ENABLE_SHARED_MONGOC $ENABLE_SHARED_LZ4
RET=$?
if [ $RET != 0 ]; then
  echo "qmake failed"
  exit $RET
fi

# tools
cd "$BASEDIR/tools"
rm -f .qmake.stash
[ -f Makefile ] && make -k distclean >/dev/null 2>&1
$QMAKE -recursive $OPT target.path=\"$BINDIR\" header.path=\"$INCLUDEDIR\" datadir=\"$DATADIR\" lib.path=\"$LIBDIR\" $ENABLE_SHARED_GLOG
RET=$?
if [ $RET != 0 ]; then
  echo "qmake failed"
  exit $RET
fi

# compile MongoDB files
if [ -z "$ENABLE_SHARED_MONGOC" ]; then
  echo
  echo -n "Compiling MongoDB driver library ... "
  cd "$BASEDIR/3rdparty/mongo-driver"
  find . -type d | grep CMakeFiles | xargs rm -rf
  find . -type f | grep CMakeCache | xargs rm -f
  find . -type f | grep Makefile | xargs rm -f
  find . -type f | grep cmake_install | xargs rm -f
  $CMAKE -S . -DCMAKE_BUILD_TYPE=Release -DENABLE_STATIC=ON -DENABLE_SSL=OFF -DENABLE_SNAPPY=OFF -DENABLE_ZLIB=OFF -DENABLE_ZSTD=OFF -DENABLE_SRV=OFF -DENABLE_SASL=OFF -DENABLE_SHM_COUNTERS=OFF -DENABLE_TESTS=OFF >/dev/null 2>&1
  make clean >/dev/null 2>&1
  make -j${NPROC} mongoc_static >/dev/null 2>&1
  RET=$?
  if [ $RET != 0 ]; then
    echo "failed"
    echo "MongoDB driver not available."
    exit $RET
  fi
  echo "OK"
fi

# compile glog
if ! [[ "$SPEC" =~ "wasm" ]]; then
  cd "$BASEDIR/3rdparty/glog"
  rm -rf build
  if [ -z "$ENABLE_SHARED_GLOG" ]; then
    echo
    echo -n "Compiling glog ... "
    $CMAKE -S . -B build -G "Unix Makefiles" -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_STANDARD=14 >/dev/null 2>&1
    make -j${NPROC} -C build >/dev/null 2>&1
    RET=$?
    if [ $RET != 0 ]; then
      make -C build
      echo "failed"
      echo "glog not available."
      exit $RET
    fi
    echo "OK"
  fi
fi

# compile LZ4
cd "$BASEDIR/3rdparty/lz4"
make clean >/dev/null 2>&1
if [ -z "$ENABLE_SHARED_LZ4" ]; then
  echo
  echo -n "Compiling LZ4 ... "
  make -j${NPROC} lib >/dev/null 2>&1
  RET=$?
  if [ $RET != 0 ]; then
    make SHELL='bash -x' lib
    echo "failed"
    echo "LZ4 not available."
    exit $RET
  fi
  echo "OK"
fi

echo
echo "First, run \"make\" and \"sudo make install\" in src directory."
echo "Next, run \"make\" and \"sudo make install\" in tools directory."

