#!/bin/sh

OPTS=`getopt -o "h" --long \
help,fetch-only,no-debug,disable-fast-vapi,with-tests,release,with-libsignal-in-tree,\
enable-plugin:,disable-plugin:,\
prefix:,program-prefix:,exec-prefix:,lib-suffix:,\
bindir:,libdir:,includedir:,datadir:,\
host:,build:,\
sbindir:,sysconfdir:,libexecdir:,localstatedir:,sharedstatedir:,mandir:,infodir:,\
enable-dependency-tracking,disable-dependency-tracking,\
disable-silent-rules,disable-maintainer-mode\
 -n './configure' -- "$@"`
if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi

eval set -- "$OPTS"

PREFIX=${PREFIX:-/usr/local}
ENABLED_PLUGINS=
DISABLED_PLUGINS=
BUILD_LIBSIGNAL_IN_TREE=
BUILD_TESTS=
BUILD_TYPE=Debug
DISABLE_FAST_VAPI=
LIB_SUFFIX=
NO_DEBUG=
FETCH_ONLY=

EXEC_PREFIX=
BINDIR=
SBINDIR=n
SYSCONFDIR=
DATADIR=
INCLUDEDIR=
LIBDIR=
LIBEXECDIR=
LOCALSTATEDIR=
SHAREDSTATEDIR=
MANDIR=
INFODIR=

help() {
    cat << EOF
Usage:
  ./configure [OPTION]...

Defaults for the options (based on current environment) are specified in
brackets.

Configuration:
  -h, --help                 Print this help and exit
  --disable-fast-vapi        Disable the usage of Vala compilers fast-vapi
                             feature. fast-vapi mode is slower when doing
                             clean builds, but faster when doing incremental
                             builds (during development).
  --fetch-only               Only fetch the files required to run ./configure
                             without network access later and exit.
  --no-debug                 Build without debug symbols
  --release                  Configure to build an optimized release version
  --with-libsignal-in-tree   Build libsignal-protocol-c in tree and link it
                             statically.
  --with-tests               Also build tests.

Plugin configuration:
  --enable-plugin=PLUGIN     Enable compilation of plugin PLUGIN.
  --disable-plugin=PLUGIN    Disable compilation of plugin PLUGIN.

Installation directories:
  --prefix=PREFIX            Install architecture-independent files in PREFIX
                             [$PREFIX]
  --program-prefix=PREFIX    Same as --prefix
  --exec-prefix=             Install architecture-dependent files in EPREFIX
                             [PREFIX]
  --lib-suffix=SUFFIX        Append SUFFIX to the directory name for libraries

By default, \`make install' will install all the files in
\`/usr/local/bin', \`/usr/local/lib' etc.  You can specify
an installation prefix other than \`/usr/local' using \`--prefix',
for instance \`--prefix=\$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR               user executables [EPREFIX/bin]
  --libdir=DIR               object code libraries [EPREFIX/lib]
  --includedir=DIR           C header files [PREFIX/include]
  --datadir=DIR              read-only data [PREFIX/share]

For compatibility with autotools, these options will be silently ignored:
--host, --build, --sbindir, --sysconfdir, --libexecdir, --sharedstatedir,
--localstatedir, --mandir, --infodir, --enable-dependency-tracking,
--disable-dependency-tracking

Some influential environment variables:
  CC                         C compiler command
  CFLAGS                     C compiler flags
  PKG_CONFIG_PATH            directories to add to pkg-config's search path
  PKG_CONFIG_LIBDIR          path overriding pkg-config's built-in search path
  USE_CCACHE                 decide to use ccache when compiling C objects
  VALAC                      Vala compiler command
  VALACFLAGS                 Vala compiler flags

Use these variables to override the choices made by \`configure' or to help
it to find libraries and programs with nonstandard names/locations.

EOF
}

while true; do
    case "$1" in
        --prefix ) PREFIX="$2"; shift; shift ;;
        --enable-plugin ) if [ -z "$ENABLED_PLUGINS" ]; then ENABLED_PLUGINS="$2"; else ENABLED_PLUGINS="$ENABLED_PLUGINS;$2"; fi; shift; shift ;;
        --disable-plugin ) if [ -z "$DISABLED_PLUGINS" ]; then DISABLED_PLUGINS="$2"; else DISABLED_PLUGINS="$DISABLED_PLUGINS;$2"; fi; shift; shift ;;
        --valac ) VALA_EXECUTABLE="$2"; shift; shift ;;
        --valac-flags ) VALAC_FLAGS="$2"; shift; shift ;;
        --lib-suffix ) LIB_SUFFIX="$2"; shift; shift ;;
        --with-libsignal-in-tree ) BUILD_LIBSIGNAL_IN_TREE=yes; shift ;;
        --disable-fast-vapi ) DISABLE_FAST_VAPI=yes; shift ;;
        --no-debug ) NO_DEBUG=yes; shift ;;
        --fetch-only ) FETCH_ONLY=yes; shift ;;
        --release ) BUILD_TYPE=RelWithDebInfo; shift ;;
        --with-tests ) BUILD_TESTS=yes; shift ;;
        # Autotools paths
        --program-prefix ) PREFIX="$2"; shift; shift ;;
        --exec-prefix ) EXEC_PREFIX="$2"; shift; shift ;;
        --bindir ) BINDIR="$2"; shift; shift ;;
        --datadir ) DATADIR="$2"; shift; shift ;;
        --includedir ) INCLUDEDIR="$2"; shift; shift ;;
        --libdir ) LIBDIR="$2"; shift; shift ;;
        # Autotools paths not used
        --sbindir ) SBINDIR="$2"; shift; shift ;;
        --sysconfdir ) SYSCONFDIR="$2"; shift; shift ;;
        --libexecdir ) LIBEXECDIR="$2"; shift; shift ;;
        --localstatedir ) LOCALSTATEDIR="$2"; shift; shift ;;
        --sharedstatedir ) SHAREDSTATEDIR="$2"; shift; shift ;;
        --mandir ) MANDIR="$2"; shift; shift ;;
        --infodir ) INFODIR="$2"; shift; shift ;;
        # Ignore for autotools compat
        --host | --build ) shift; shift ;;
        --disable-dependency-tracking | --enable-dependency-tracking ) shift ;;
        # Ignore for debian compat
        --disable-silent-rules | --disable-maintainer-mode ) shift ;;
        -h | --help ) help; exit 0 ;;
        -- ) shift; break ;;
        * ) break ;;
    esac
done

if [ "$BUILD_LIBSIGNAL_IN_TREE" = "yes" ] || [ "$FETCH_ONLY" = "yes" ]; then
    if [ -d ".git" ]; then
        git submodule update --init 2>/dev/null
    else
        tmp=0
        for i in $(cat .gitmodules | grep -n submodule | awk -F ':' '{print $1}') $(wc -l .gitmodules | awk '{print $1}'); do
            if ! [ $tmp -eq 0 ]; then
                name=$(cat .gitmodules | head -n $tmp | tail -n 1 | awk -F '"' '{print $2}')
                def=$(cat .gitmodules | head -n $i | tail -n $(expr "$i" - "$tmp") | awk -F ' ' '{print $1 $2 $3}')
                path=$(echo "$def" | grep '^path=' | awk -F '=' '{print $2}')
                url=$(echo "$def" | grep '^url=' | awk -F '=' '{print $2}')
                branch=$(echo "$def" | grep '^branch=' | awk -F '=' '{print $2}')

                if ! ls "$path"/* >/dev/null 2>/dev/null; then
                    git=$(which git)
                    if ! [ $? -eq 0 ] || ! [ -x $git ]; then
                        echo "Failed retrieving missing files"
                        exit 5
                    fi
                    res=$(git clone "$url" "$path" 2>&1)
                    if ! [ $? -eq 0 ] || ! [ -d $path ]; then
                        echo "Failed retrieving missing files: $res"
                        exit 5
                    fi
                    if [ -n "$branch" ]; then
                        olddir="$(pwd)"
                        cd "$path"
                        res=$(git checkout "$branch" 2>&1)
                        if ! [ $? -eq 0 ]; then
                            echo "Failed retrieving missing files: $res"
                            exit 5
                        fi
                        cd "$olddir"
                    fi
                    echo "Submodule path '$path': checked out '$branch' (via git clone)"
                fi
            fi
            tmp=$i
        done
    fi
fi

if [ "$FETCH_ONLY" = "yes" ]; then exit 0; fi

if [ ! -x "$(which cmake 2>/dev/null)" ]
then
    echo "-!- CMake required."
    exit 1
fi

ninja_bin="$(which ninja-build 2>/dev/null)"
if ! [ -x "$ninja_bin" ]; then
    ninja_bin="$(which ninja 2>/dev/null)"
fi
if [ -x "$ninja_bin" ]; then
    ninja_version=`$ninja_bin --version 2>/dev/null`
    if [ $? -eq 0 ]; then
        if [ -d build ]; then
            last_ninja_version=`cat build/.ninja_version 2>/dev/null`
        else
            last_ninja_version=0
        fi
        if [ "$ninja_version" != "$last_ninja_version" ]; then
            echo "-- Found Ninja: $ninja_bin (found version \"$ninja_version\")"
        fi
        cmake_type="Ninja"
        exec_bin="$ninja_bin"
        exec_command="$exec_bin"
    elif [ "/usr/sbin/ninja" = "$ninja_bin" ]; then
        echo "-- Ninja at $ninja_bin is not usable. Did you install 'ninja' instead of 'ninja-build'?"
    fi
fi

if ! [ -x "$exec_bin" ]; then
    make_bin="$(which make 2>/dev/null)"
    if [ -x "$make_bin" ]; then
        echo "-- Found Make: $make_bin"
        cmake_type="Unix Makefiles"
        exec_bin="$make_bin"
        exec_command="$exec_bin"
        echo "--   Running with make. Using Ninja (ninja-build) might improve build experience."
    fi
fi

if ! [ -x "$exec_bin" ]; then
    echo "-!- No compatible build system (Ninja, Make) found."
    exit 4
fi


if [ -f ./build ]; then
    echo "-!- ./build file exists. ./configure can't continue"
    exit 2
fi

if [ -d build ]; then
    last_type=`cat build/.cmake_type`
    if [ "$cmake_type" != "$last_type" ]
    then
        echo "-- Using different build system, cleaning build system files"
        cd build
        rm -r CMakeCache.txt CMakeFiles
        cd ..
    fi
fi

mkdir -p build
cd build

echo "$cmake_type" > .cmake_type
echo "$ninja_version" > .ninja_version
cmake -G "$cmake_type" \
    -DCMAKE_INSTALL_PREFIX="$PREFIX" \
    -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
    -DENABLED_PLUGINS="$ENABLED_PLUGINS" \
    -DDISABLED_PLUGINS="$DISABLED_PLUGINS" \
    -DBUILD_TESTS="$BUILD_TESTS" \
    -DBUILD_LIBSIGNAL_IN_TREE="$BUILD_LIBSIGNAL_IN_TREE" \
    -DVALA_EXECUTABLE="$VALAC" \
    -DCMAKE_VALA_FLAGS="$VALACFLAGS" \
    -DDISABLE_FAST_VAPI="$DISABLE_FAST_VAPI" \
    -DLIB_SUFFIX="$LIB_SUFFIX" \
    -DNO_DEBUG="$NO_DEBUG" \
    -DEXEC_INSTALL_PREFIX="$EXEC_PREFIX" \
    -DSHARE_INSTALL_PREFIX="$DATADIR" \
    -DBIN_INSTALL_DIR="$BINDIR" \
    -DINCLUDE_INSTALL_DIR="$INCLUDEDIR" \
    -DLIB_INSTALL_DIR="$LIBDIR" \
    -Wno-dev \
    .. || exit 9

if [ "$cmake_type" = "Ninja" ]; then
cat << EOF > Makefile
default:
	@sh -c "$exec_command"
%:
	@sh -c "$exec_command \"\$@\""
EOF
fi

cd ..

cat << EOF > Makefile
default:
	@sh -c "cd build; $exec_command"
distclean: clean uninstall
	
test: default
	echo "make test not yet supported"
%:
	@sh -c "cd build; $exec_command \"\$@\""
EOF

echo "-- Configured. Type 'make' to build, 'make install' to install."