#!/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
#
#  Available options:
#  --phpize <PATH>        Path to custom `phpize' executable
#  --php-config <PATH>    Path to custom `php-config' executable
#
#  Available env. vars:
#  RE2C_BIN               Path to custom `re2c'
#
#  Usage:
#
#  Build and install extension using default PHP's paths:
#  ./install
#
#  Build and install extension using custom PHP's paths:
#  ./install --phpize /usr/bin/phpize5.6 --php-config /usr/bin/php-config5.6

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

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

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

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

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

if test "$re2c_vernum" -lt "1306"; then
	echo "error: minimal required version of re2c is 0.13.6"
	exit 1
fi

# Check best compilation flags for compiler
export CC=gcc
export CFLAGS="-march=native -mtune=native -O2 -fomit-frame-pointer"

# Set defaults
PHPIZE_BIN=`command -v phpize 2>/dev/null || true`
PHPCONFIG_BIN=`command -v php-config 2>/dev/null || true`

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

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

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

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

# Detect possible flags
echo "int main() {}" > t.c
gcc ${CFLAGS} t.c -o t 2> t.t
if [ $? != 0 ]; then
	chmod +x gcccpuopt
	BFLAGS=`./gcccpuopt`
	export CFLAGS="-O2 -fomit-frame-pointer $BFLAGS"
	gcc ${CFLAGS} t.c -o t 2> t.t
	if [ $? != 0 ]; then
		export CFLAGS="-O2"
	fi
fi

# Activate some gcc specific optimizations for gcc >= 4
if [ $(gcc -dumpversion | cut -f1 -d.) -ge 4 ]; then
	gcc ${CFLAGS} -fvisibility=hidden t.c -o t 2> t.t && export CFLAGS="$CFLAGS -fvisibility=hidden"
fi

gcc ${CFLAGS} -flto t.c -o t 2> t.t && { export CFLAGS="$CFLAGS -flto"; export LDFLAGS="$LDFLAGS $CFLAGS"; }

rm -f t.t t.c t

cd ${CURRENT_DIR}/parser

# Cleanup
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 \
	config.h.in~

${RE2C_BIN} --no-generation-date -o scanner.c scanner.re

# 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 || true`
	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 || true`
	aclocal && ${LIBTOOLIZE_BIN} --force && autoheader && autoconf
fi

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

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

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

cd ${CURRENT_DIR}/parser

# Cleanup
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 \
	config.h.in~

echo -e "\nThanks for compiling Zephir Parser!\nBuild succeed: Please restart your web server to complete the installation\n"
