#!/usr/bin/env bash
#
# Zephir Parser
#
# Copyright (c) 2013-2017 Zephir Team and contributors
#
# 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:
# http://zephir-lang.com/license.html
#
# If you did not receive a copy of the MIT license and are unable
# to obtain it through the world-wide-web, please send a note to
# license@zephir-lang.com so we can mail you a copy immediately.

#  Available params:
#  --phpize
#  --php-config
#
#  Example:
#  ./install --phpize /usr/bin/phpize5.6 --php-config /usr/bin/php-config5.6

set -e

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

GCC_BIN=$(command -v gcc 2>/dev/null)
RE2C_BIN=${RE2C_BIN:-$(command -v re2c 2>/dev/null)}

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

# 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)
PHPCONFIG_BIN=$(command -v php-config 2>/dev/null)

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

# Perform the compilation
${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 --silent --with-php-config=${PHPCONFIG_BIN} --enable-zephir_parser

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"

