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

# check for `cmake` command
type cmake > /dev/null 2>&1 || {
    echo "\
This package requires CMake, please install it first, then you may
use this configure script to access CMake equivalent functionality.\
" >&2;
    exit 1;
}

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

  Build Options:
    --builddir=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
    --generator=GENERATOR  CMake generator to use (see cmake --help)
    --ccache               use ccache to speed up recompilation (requires
                           ccache installation and CMake 3.10+)
    --toolchain=PATH       path to a CMAKE_TOOLCHAIN_FILE
                           (useful for cross-compiling)

  Installation Directories:
    --prefix=PREFIX        installation directory [/usr/local/zeek]
    --scriptdir=PATH       root installation directory for Zeek scripts
                           [PREFIX/share/zeek]
    --localstatedir=PATH   when using ZeekControl, path to store log files
                           and run-time data (within log/ and spool/ subdirs)
                           [PREFIX]
    --spooldir=PATH        when using ZeekControl, path to store run-time data
                           [PREFIX/spool]
    --logdir=PATH          when using ZeekControl, path to store log file
                           [PREFIX/logs]
    --conf-files-dir=PATH  config files installation directory [PREFIX/etc]
    --mandir=PATH          installation path for man pages [PREFIX/share/man]

  Optional Features:
    --enable-debug         compile in debugging mode (like --build-type=Debug)
    --enable-coverage      compile with code coverage support (implies debugging mode)
    --enable-mobile-ipv6   analyze mobile IPv6 features defined by RFC 6275
    --enable-perftools     enable use of Google perftools (use tcmalloc)
    --enable-perftools-debug use Google's perftools for debugging
    --enable-jemalloc      link against jemalloc
    --enable-static-broker build Broker statically (ignored if --with-broker is specified)
    --enable-static-binpac build binpac statically (ignored if --with-binpac is specified)
    --disable-zeekctl      don't install ZeekControl
    --disable-auxtools     don't build or install auxiliary tools
    --disable-python       don't try to build python bindings for Broker
    --disable-broker-tests don't try to build Broker unit tests
    --sanitizers=SANITIZERS comma-separated list of Clang sanitizers to enable

  Required Packages in Non-Standard Locations:
    --with-openssl=PATH    path to OpenSSL install root
    --with-bind=PATH       path to BIND install root
    --with-pcap=PATH       path to libpcap install root
    --with-binpac=PATH     path to BinPAC executable
                           (useful for cross-compiling)
    --with-bifcl=PATH      path to Zeek BIF compiler executable
                           (useful for cross-compiling)
    --with-flex=PATH       path to flex executable
    --with-bison=PATH      path to bison executable
    --with-python=PATH     path to Python executable
    --with-broker=PATH     path to Broker install root
                           (Zeek uses an embedded version by default)
    --with-caf=PATH        path to C++ Actor Framework install root
                           (a Broker dependency that is embedded by default)

  Optional Packages in Non-Standard Locations:
    --with-geoip=PATH      path to the libmaxminddb install root
    --with-krb5=PATH       path to krb5 install root
    --with-perftools=PATH  path to Google Perftools install root
    --with-jemalloc=PATH   path to jemalloc install root
    --with-python-lib=PATH path to libpython
    --with-python-inc=PATH path to Python headers
    --with-swig=PATH       path to SWIG executable
    --with-rocksdb=PATH    path to RocksDB installation
                           (an optional Broker dependency)

  Packaging Options (for developers):
    --binary-package       toggle special logic for binary packaging
    --ignore-dirs=PATHS    paths to ignore when creating source package
                           (semicolon delimited and quoted when multiple)
    --pkg-name-prefix=NAME use the given name as the package prefix instead
                           of the default CMake project name
    --osx-sysroot=PATH     path to the OS X SDK to compile against
    --osx-min-version=VER  minimum OS X version (the deployment target)

  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 )"

if [ ! -e "$sourcedir/cmake/COPYING" ] && [ -d "$sourcedir/.git" ]; then
    echo "\
You seem to be missing the content of the cmake directory.

This typically means that you performed a non-recursive git clone of
Zeek. To check out the required subdirectories, please execute:

  ( cd $sourcedir && git submodule update --recursive --init )
" >&2;
    exit 1;
fi

# 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"
}

# Function to remove a CMake cache entry definition from the
# CMakeCacheEntries variable
#   $1 is the cache entry variable name
remove_cache_entry () {
    CMakeCacheEntries="$CMakeCacheEntries -U $1"

    # Even with -U, cmake still warns by default if
    # added previously with -D.
    CMakeCacheEntries="$CMakeCacheEntries --no-warn-unused-cli"
}

# set defaults
builddir=build
prefix=/usr/local/zeek
CMakeCacheEntries=""
append_cache_entry CMAKE_INSTALL_PREFIX PATH   $prefix
append_cache_entry ZEEK_ROOT_DIR        PATH   $prefix
append_cache_entry PY_MOD_INSTALL_DIR   PATH   $prefix/lib/zeekctl
append_cache_entry ZEEK_SCRIPT_INSTALL_PATH STRING $prefix/share/zeek
append_cache_entry ZEEK_ETC_INSTALL_DIR PATH   $prefix/etc
append_cache_entry ENABLE_DEBUG         BOOL   false
append_cache_entry ENABLE_PERFTOOLS     BOOL   false
append_cache_entry ENABLE_JEMALLOC      BOOL   false
append_cache_entry BUILD_SHARED_LIBS    BOOL   true
append_cache_entry INSTALL_AUX_TOOLS    BOOL   true
append_cache_entry INSTALL_ZEEKCTL      BOOL   true
append_cache_entry CPACK_SOURCE_IGNORE_FILES STRING
append_cache_entry ENABLE_MOBILE_IPV6   BOOL   false
append_cache_entry SANITIZERS           STRING ""

# 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
            ;;
        --builddir=*)
            builddir=$optarg
            ;;
        --build-type=*)
            append_cache_entry CMAKE_BUILD_TYPE     STRING $optarg

            if [ $(echo "$optarg" | tr [:upper:] [:lower:]) = "debug" ]; then
                append_cache_entry ENABLE_DEBUG         BOOL   true
            fi
            ;;
        --generator=*)
            CMakeGenerator="$optarg"
            ;;
        --ccache)
            append_cache_entry ENABLE_CCACHE         BOOL   true
            ;;
        --toolchain=*)
            append_cache_entry CMAKE_TOOLCHAIN_FILE  PATH   $optarg
            ;;
        --prefix=*)
            prefix=$optarg
            append_cache_entry CMAKE_INSTALL_PREFIX PATH   $optarg
            append_cache_entry ZEEK_ROOT_DIR        PATH   $optarg
            append_cache_entry PY_MOD_INSTALL_DIR   PATH   $optarg/lib/zeekctl
            ;;
        --scriptdir=*)
            append_cache_entry ZEEK_SCRIPT_INSTALL_PATH STRING $optarg
            user_set_scriptdir="true"
            ;;
        --conf-files-dir=*)
            append_cache_entry ZEEK_ETC_INSTALL_DIR PATH   $optarg
            user_set_conffilesdir="true"
            ;;
        --localstatedir=*)
            append_cache_entry ZEEK_LOCAL_STATE_DIR PATH   $optarg
            ;;
        --spooldir=*)
            append_cache_entry ZEEK_SPOOL_DIR       PATH   $optarg
            ;;
        --logdir=*)
            append_cache_entry ZEEK_LOG_DIR         PATH   $optarg
            ;;
        --mandir=*)
            append_cache_entry ZEEK_MAN_INSTALL_PATH         PATH   $optarg
            ;;
        --enable-coverage)
            append_cache_entry ENABLE_COVERAGE         BOOL   true
            append_cache_entry ENABLE_DEBUG         BOOL   true
            ;;
        --enable-debug)
            append_cache_entry ENABLE_DEBUG         BOOL   true
            ;;
        --enable-mobile-ipv6)
            append_cache_entry ENABLE_MOBILE_IPV6         BOOL   true
            ;;
        --enable-perftools)
            append_cache_entry ENABLE_PERFTOOLS     BOOL   true
            ;;
        --enable-perftools-debug)
            append_cache_entry ENABLE_PERFTOOLS     BOOL   true
            append_cache_entry ENABLE_PERFTOOLS_DEBUG BOOL   true
            ;;
        --sanitizers=*)
            append_cache_entry SANITIZERS    STRING    $optarg
            ;;
        --enable-jemalloc)
            append_cache_entry ENABLE_JEMALLOC     BOOL   true
            ;;
        --enable-static-broker)
            append_cache_entry BUILD_STATIC_BROKER    BOOL    true
            ;;
        --enable-static-binpac)
            append_cache_entry BUILD_STATIC_BINPAC    BOOL    true
            ;;
        --disable-zeekctl)
            append_cache_entry INSTALL_ZEEKCTL       BOOL   false
            ;;
        --disable-auxtools)
            append_cache_entry INSTALL_AUX_TOOLS    BOOL   false
            ;;
        --disable-python)
            append_cache_entry DISABLE_PYTHON_BINDINGS     BOOL   true
            ;;
        --disable-broker-tests)
            append_cache_entry BROKER_DISABLE_TESTS     BOOL   true
            ;;
        --with-openssl=*)
            append_cache_entry OPENSSL_ROOT_DIR PATH $optarg
            ;;
        --with-bind=*)
            append_cache_entry BIND_ROOT_DIR PATH $optarg
            ;;
        --with-pcap=*)
            append_cache_entry PCAP_ROOT_DIR PATH $optarg
            ;;
        --with-binpac=*)
            append_cache_entry BINPAC_EXE_PATH     PATH $optarg
            append_cache_entry BinPAC_ROOT_DIR     PATH "$(dirname $optarg)/.."
            ;;
        --with-bifcl=*)
            append_cache_entry BIFCL_EXE_PATH      PATH   $optarg
            ;;
        --with-flex=*)
            append_cache_entry FLEX_EXECUTABLE PATH $optarg
            ;;
        --with-bison=*)
            append_cache_entry BISON_EXECUTABLE PATH $optarg
            ;;
        --with-geoip=*)
            append_cache_entry LibMMDB_ROOT_DIR PATH $optarg
            ;;
        --with-krb5=*)
            append_cache_entry LibKrb5_ROOT_DIR PATH $optarg
            ;;
        --with-perftools=*)
            append_cache_entry GooglePerftools_ROOT_DIR PATH $optarg
            ;;
        --with-jemalloc=*)
            append_cache_entry JEMALLOC_ROOT_DIR    PATH    $optarg
            append_cache_entry ENABLE_JEMALLOC      BOOL    true
            ;;
        --with-python=*)
            append_cache_entry PYTHON_EXECUTABLE    PATH    $optarg
            ;;
        --with-python-lib=*)
            append_cache_entry PYTHON_LIBRARY       PATH    $optarg
            ;;
        --with-python-inc=*)
            append_cache_entry PYTHON_INCLUDE_DIR   PATH    $optarg
            append_cache_entry PYTHON_INCLUDE_PATH  PATH    $optarg
            ;;
        --with-swig=*)
            append_cache_entry SWIG_EXECUTABLE      PATH    $optarg
            ;;
        --with-broker=*)
            append_cache_entry BROKER_ROOT_DIR      PATH   $optarg
            ;;
        --with-caf=*)
            append_cache_entry CAF_ROOT_DIR      PATH   $optarg
            ;;
        --with-rocksdb=*)
            append_cache_entry ROCKSDB_ROOT_DIR     PATH   $optarg
            ;;
        --binary-package)
            append_cache_entry BINARY_PACKAGING_MODE BOOL true
            ;;
        --ignore-dirs=*)
            append_cache_entry CPACK_SOURCE_IGNORE_FILES STRING $optarg
            ;;
        --pkg-name-prefix=*)
            append_cache_entry PACKAGE_NAME_PREFIX STRING $optarg
            ;;
        --osx-sysroot=*)
            append_cache_entry CMAKE_OSX_SYSROOT PATH $optarg
            ;;
        --osx-min-version=*)
            append_cache_entry CMAKE_OSX_DEPLOYMENT_TARGET STRING $optarg
            ;;
        *)
            echo "Invalid option '$1'.  Try $0 --help to see available options."
            exit 1
            ;;
    esac
    shift
done

if [ "$user_set_scriptdir" != "true" ]; then
    append_cache_entry ZEEK_SCRIPT_INSTALL_PATH STRING $prefix/share/zeek
fi

if [ "$user_set_conffilesdir" != "true" ]; then
    append_cache_entry ZEEK_ETC_INSTALL_DIR PATH $prefix/etc
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
    cmake -G "$CMakeGenerator" $CMakeCacheEntries $sourcedir
else
    cmake $CMakeCacheEntries $sourcedir
fi

echo "# This is the command used to configure this build" > config.status
echo $command >> config.status
chmod u+x config.status
