#!/usr/bin/env bash
#
# Zephir Parser
# Copyright (c) 2013-present Zephir Team (https://zephir-lang.com/)
#
# This source file is subject the MIT license, that is bundled with this
# package in the file LICENSE, and is available through the world-wide-web
# at the following url: https://zephir-lang.com//license.html
#
#  By default, this utility DOES NOT INSTALL the extension and performs just
#  compilation and building.  This behavior is convenient to use with
#  `php -d extension=$(pwd)/modules/zephir_parser.so` option during on testing
#  and/or debugging.  To install extension refer to following examples.
#
#  Available options:
#  --phpize <PATH>        Path to custom `phpize' executable
#  --php-config <PATH>    Path to custom `php-config' executable
#  --install              Install Zephir Parser
#
#  Available environment variables:
#  RE2C_BIN               Path to custom `re2c'
#  RE2C_FLAGS             The `re2c' flags e.g. `--debug-output', `--no-optimize-tag', etc.
#
#  Usage:
#
#  Build extension using default PHP's paths:
#  ./install-development
#
#  Build extension using custom PHP's paths:
#  ./install-development --phpize /usr/bin/phpize5.6 --php-config /usr/bin/php-config5.6
#
#  Build and install extension:
#  ./install-development --phpize /usr/bin/phpize5.6 --php-config /usr/bin/php-config5.6 --install

export ZEND_DONT_UNLOAD_MODULES=1
export USE_ZEND_ALLOC=0

CURRENT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
PARSER_DIR=${CURRENT_DIR}/parser

CC=${CC:-""}
RE2C_BIN=${RE2C_BIN:-`command -v re2c 2>/dev/null || true`}

GCC_BIN=`command -v gcc 2>/dev/null || true`
CLANG_BIN=`command -v clang 2>/dev/null || true`
PHPIZE_BIN=`command -v phpize 2>/dev/null || true`
PHPCONFIG_BIN=`command -v php-config 2>/dev/null || true`

INSTALL_EXTENSION="${INSTALL_EXTENSION:-0}"
RE2C_FLAGS="${RE2C_FLAGS:-}"

if [ x"$RE2C_BIN" = x ]; then
	echo -e "error: unable to locate the re2c"
	exit 2
fi

re2c_vernum=`re2c --vernum 2>/dev/null`
if test -z "$re2c_vernum"; then
  echo "error: unable to locate the re2c"
  exit 2
fi

if [ x"$CC" == x ]; then
	if [ x"$GCC_BIN" != x ]; then
		export CC="gcc"
	else
		if [ x"$CLANG_BIN" != x ]; then
			export CC="clang"
		fi
	fi
fi

if [ x"$CC" == x ]; then
	echo -e "error: unable to locate the compiler"
	exit 1
fi

export CFLAGS="-g -O0 -Wall -Werror -fvisibility=hidden"

if [ x"$CC" == xclang ]; then
	export CFLAGS="${CFLAGS} -fcolor-diagnostics"
fi

# Translate long options to short
for arg in "$@"; do
	shift
	case "$arg" in
		"--phpize") set -- "$@" "-i" ;;
		"--php-config") set -- "$@" "-c" ;;
		"--install") set -- "$@" "-e" ;;
		*) set -- "$@" "$arg" ;;
	esac
done

# Options switcher
while getopts a:i:c:e opts; do
	case ${opts} in
		i) PHPIZE_BIN=${OPTARG} ;;
		c) PHPCONFIG_BIN=${OPTARG} ;;
		e) INSTALL_EXTENSION=1 ;;
	esac
done

if [ x"$PHPIZE_BIN" = x ]; then
	echo -e "error: unable to locate the phpize"
	exit 1
fi

if [ x"$PHPCONFIG_BIN" = x ]; then
	echo -e "error: unable to locate the php-config"
	exit 1
fi

PHP_FULL_VERSION=`${PHPCONFIG_BIN} --version`

if [ $? != 0 ]; then
	echo "php-config is not installed"
	exit 1
fi

if [ "${PHP_FULL_VERSION:0:3}" == "5.3" ]; then
	echo "php 5.3 is no longer supported"
	exit 1
fi

# Cleanup

rm -rf .libs

cd ${PARSER_DIR}
rm -f \
	*.o \
	*.lo \
	lemon \
	scanner.c \
	parser.c \
	parser.php5.c \
	parser.php5.h \
	parser.php5.out \
	parser.php7.c \
	parser.php7.h \
	parser.php7.out \
	parser.loT

rm -rf .libs

if test "$re2c_vernum" -gt "9999"; then
	${RE2C_BIN} ${RE2C_FLAGS} -W --no-generation-date -o scanner.c scanner.re
else
	${RE2C_BIN} ${RE2C_FLAGS} --no-generation-date -o scanner.c scanner.re
fi

# Compile lemon
${CC} lemon.c -o lemon

if [ "${PHP_FULL_VERSION:0:1}" == "5" ]; then
	PHP_VERSION="php5"
else
	PHP_VERSION="php7"
fi

echo -e "Generating parser..."
./lemon -s parser.${PHP_VERSION}.lemon

if [ ! -f parser.${PHP_VERSION}.c ]; then
	echo "error: couldn't generate parser"
	exit 1
fi

echo "#include <php.h>" > parser.c
cat parser.${PHP_VERSION}.c >> parser.c
cat base.c >> parser.c

sed s/"\#line"/"\/\/"/g scanner.c > xx && mv -f xx scanner.c
sed s/"#line"/"\/\/"/g parser.c > xx && mv -f xx parser.c

cd ${CURRENT_DIR}

# Clean current compilation
if [ -f Makefile ]; then
	make clean
	${PHPIZE_BIN} --clean
fi

${PHPIZE_BIN}

# For some reason the libtool script being generated by autogen contains lines referring
# to "$echo message" instead of "echo message".
export echo=echo

# Detect Gentoo Linux
if [ -f /etc/gentoo-release ]; then
	LIBTOOLIZE_BIN=$(command -v libtoolize 2>/dev/null)
	aclocal && ${LIBTOOLIZE_BIN} --force && autoheader && autoconf
fi

# Detect macOS
if [ "$(uname -s 2>/dev/null)" = "Darwin" ]; then
	LIBTOOLIZE_BIN=$(command -v glibtoolize 2>/dev/null)
	aclocal && ${LIBTOOLIZE_BIN} --force && autoheader && autoconf
fi

./configure --help

./configure \
	--with-php-config=${PHPCONFIG_BIN} \
	--enable-zephir_parser

# Perform the compilation
make -j"$(getconf _NPROCESSORS_ONLN)"

exit_status=$?

if [ ! $exit_status -eq 0 ]; then
	echo -e "\nSomething went wrong.\nCheck logs and/or output to determine issue.\n"
else
	if [ "${INSTALL_EXTENSION}" = 1 ]; then
		make -s install
		echo -e "\nInstall succeed.\n"
	else
		echo -e "\nBuild succeed.\n"
	fi
fi

exit $exit_status
