#!/bin/sh
# Convenience wrapper for easily viewing/setting options that
# the project's CMake scripts will recognize
set -e
command="$0 $*"

usage="\
Usage: $0 [OPTION]... [VAR=VALUE]...

  Build Options:
    --cmake=PATH           custom path to a CMake binary
    --generator=GENERATOR  CMake generator to use (see 'cmake --help')
    --build-dir=DIR        place build files in directory [build]
    --build-type=TYPE      set CMake build type [RelWithDebInfo]:
                             - Debug: optimizations off, debug symbols + flags
                             - MinSizeRel: size optimizations, debugging off
                             - Release: optimizations on, debugging off
                             - RelWithDebInfo: optimizations on,
                                   debug symbols on, debug flags off
    --ccache               use ccache to speed up recompilation (requires
                           ccache installation and CMake 3.10+)
    --enable-debug         compile in debugging mode (like --build-type=Debug)
    --enable-static        build static libraries (in addition to shared)
    --enable-static-only   only build static libraries, not shared
    --with-log-level=LVL   build embedded CAF with debugging output.  Levels:
                             ERROR, WARNING, INFO, DEBUG, TRACE
    --sanitizers=LIST      comma-separated list of sanitizer names to enable

  Installation Directories:
    --prefix=PREFIX        installation directory [/usr/local]
    --libdir=DIR           installation directory for static and dynamic
                           libraries [PREFIX/lib]
    --python-home=PATH     explicit installation method for optional Python
                           bindings [PATH/lib/python], the path tracks
                           --prefix if that option is used.
    --python-prefix=PATH   explicit install directory for Python bindings
                           [PATH/lib/python<Python Version>/site-packages]

  Optional Features:
    --disable-python       don't try to build python bindings
    --disable-docs         don't try to build local documentation
    --disable-tests        don't try to build unit tests
    --enable-rocksdb       try to find and a RocksDB installation and use it
    --with-rocksdb=PATH    path to RocksDB installation, implies --enable-rocksdb
    --with-python=PATH     path to Python executable
    --with-python-config=PATH
                           path to python-config executable
    --with-zeek=PATH       path to Zeek executable for interoperability tests

  Required Packages in Non-Standard Locations:
    --with-caf=PATH        path to C++ Actor Framework installation
    --with-openssl=PATH    path to OpenSSL install root

  Influential Environment Variables (only on first invocation
  per build directory):
    CC                     C compiler command
    CFLAGS                 C compiler flags
    CXX                    C++ compiler command
    CXXFLAGS               C++ compiler flags
"

sourcedir="$( cd "$( dirname "$0" )" && pwd )"

# Function to append a CMake cache entry definition to the
# CMakeCacheEntries variable
#   $1 is the cache entry variable name
#   $2 is the cache entry variable type
#   $3 is the cache entry variable value
append_cache_entry () {
    CMakeCacheEntries="$CMakeCacheEntries -D $1:$2=$3"
}

# set defaults
builddir=build
prefix=/usr/local
CMakeCacheEntries=""
append_cache_entry CMAKE_INSTALL_PREFIX PATH    $prefix
append_cache_entry BROKER_DISABLE_DOCS  BOOL    false

# parse arguments
while [ $# -ne 0 ]; do
    case "$1" in
        -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
        *) optarg= ;;
    esac

    case "$1" in
        --help|-h)
            echo "${usage}" 1>&2
            exit 1
            ;;
        --cmake=*)
            CMakeCommand=$optarg
            ;;
        --generator=*)
            CMakeGenerator="$optarg"
            ;;
        --ccache)
            append_cache_entry ENABLE_CCACHE        BOOL   true
            ;;
        --build-dir=*)
            builddir=$optarg
            ;;
        # backwards compatibility
        --builddir=*)
            builddir=$optarg
            ;;
        --prefix=*)
            append_cache_entry CMAKE_INSTALL_PREFIX PATH   $optarg
            append_cache_entry CMAKE_INSTALL_LIBDIR PATH   $optarg/lib
            append_cache_entry BROKER_PYTHON_HOME   PATH   $optarg
            ;;
        --libdir=*)
            append_cache_entry CMAKE_INSTALL_LIBDIR PATH   $optarg
            ;;
        --python-home=*)
            append_cache_entry BROKER_PYTHON_HOME   PATH   $optarg
            ;;
        --python-prefix=*)
            append_cache_entry BROKER_PYTHON_PREFIX PATH   $optarg
            ;;
        --build-type=*)
            append_cache_entry CMAKE_BUILD_TYPE     STRING $optarg
            ;;
        --enable-debug)
            append_cache_entry ENABLE_DEBUG         BOOL   true
            ;;
        --enable-static)
            append_cache_entry ENABLE_STATIC        BOOL   true
            ;;
        --sanitizers=*)
            append_cache_entry BROKER_SANITIZERS    STRING    $optarg
            ;;
        --enable-static-only)
            append_cache_entry ENABLE_STATIC_ONLY   BOOL   true
            ;;
        --with-log-level=*)
            append_cache_entry CAF_LOG_LEVEL        STRING  $optarg
            ;;
        --disable-python)
            append_cache_entry DISABLE_PYTHON_BINDINGS BOOL true
            ;;
        --disable-docs)
            append_cache_entry BROKER_DISABLE_DOCS  BOOL    true
            ;;
        --disable-tests)
            append_cache_entry BROKER_DISABLE_TESTS BOOL    true
            ;;
        --with-caf=*)
            append_cache_entry CAF_ROOT_DIR         PATH    $optarg
            ;;
        --with-openssl=*)
            append_cache_entry OPENSSL_ROOT_DIR     PATH    $optarg
            ;;
        --enable-rocksdb)
            append_cache_entry BROKER_ENABLE_ROCKSDB BOOL true
            ;;
        --with-rocksdb=*)
            append_cache_entry BROKER_ENABLE_ROCKSDB BOOL true
            append_cache_entry ROCKSDB_ROOT_DIR     PATH    $optarg
            ;;
        --with-python=*)
            append_cache_entry PYTHON_EXECUTABLE    PATH    $optarg
            ;;
        --with-python-config=*)
            append_cache_entry PYTHON_CONFIG        PATH    $optarg
            ;;
        --with-zeek=*)
            append_cache_entry ZEEK_EXECUTABLE      PATH    $optarg
            ;;
        *)
            echo "Invalid option '$1'.  Try $0 --help to see available options."
            exit 1
            ;;
    esac
    shift
done

if [ -z "$CMakeCommand" ]; then
    # prefer cmake3 over "regular" cmake (cmake == cmake2 on RHEL)
    if command -v cmake3 >/dev/null 2>&1 ; then
        CMakeCommand="cmake3"
    elif command -v cmake >/dev/null 2>&1 ; then
        CMakeCommand="cmake"
    else
        echo "This package requires CMake, please install it first."
        echo "Then you may use this script to configure the CMake build."
        echo "Note: pass --cmake=PATH to use cmake in non-standard locations."
        exit 1;
    fi
fi

if [ -d $builddir ]; then
    # If build directory exists, check if it has a CMake cache
    if [ -f $builddir/CMakeCache.txt ]; then
        # If the CMake cache exists, delete it so that this configuration
        # is not tainted by a previous one
        rm -f $builddir/CMakeCache.txt
    fi
else
    # Create build directory
    mkdir -p $builddir
fi

echo "Build Directory : $builddir"
echo "Source Directory: $sourcedir"
cd $builddir

if [ -n "$CMakeGenerator" ]; then
    "$CMakeCommand" -G "$CMakeGenerator" $CMakeCacheEntries $sourcedir
else
    "$CMakeCommand" $CMakeCacheEntries $sourcedir
fi

printf "#!/bin/sh\n\n" > config.status
printf "# Switch to the source of this build directory.\n" >> config.status
printf "cd \"$sourcedir\"\n\n" >> config.status
printf "# Invoke the command to configure this build.\n" >> config.status
if [ -n "$CC" ]; then
  printf 'CC="%s" ' "$CC" >> config.status
fi
if [ -n "$CXX" ]; then
  printf 'CXX="%s" ' "$CXX" >> config.status
fi
if [ -n "$CXXFLAGS" ]; then
  printf 'CXXFLAGS="%s" ' "$CXXFLAGS" >> config.status
fi
printf "$command\n" $@ >> config.status
chmod u+x config.status
