#!/bin/sh
#
# Copyright (C) 2005-2014
#       pancake <pancake@nopcode.org>
#
# acr is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# acr is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with acr; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
#===========================================================================
#
# AMR : Auto Make Replacement
# @author: pancake@nopcode.org

VERSION="0.2"
NESTED=0
S=\$

show_usage() {
	cat <<EOF
Usage: amr [options]
 -a : recursive scan directories and prints the configure.amr
 -c : parse configure.amr to print a configure.acr
 -m : parse configure.amr and generate the propers Makefile.acr
 -s : shellscript that simulates a makefile
 -d : prints all directories where amr must run
 -r : show report
 -g : print out autogen.sh
 -v : show version information"
EOF
	exit $1
}

autogen_sh() {
cat <<EOF
#!/bin/sh
# amr: autogenerated autogen.sh
echo "Autogenerating configure.amr..."
amr -a > configure.amr
DIRS=\`amr -d\`
echo "Source directories: ${S}{DIRS}"
for A in ${S}{DIRS}; do
        echo " - ${S}{A}"
        (cd ${S}{A} && amr -a > configure.amr)
done
echo "Generating configure.acr..."
amr -c > configure.acr
echo "Generating final configure script..."
acr -p
EOF
exit 0
}

case "$1" in
"-g")
	autogen_sh
	;;
"-a")
	AMR="gen-configure"
	;;
"-m")
	AMR="gen-makefile"
	;;
"-c")
	AMR="gen-acr"
	;;
"-r")
	AMR="show-report"
	;;
"-s")
	AMR="gen-shellscript"
	;;
"-d")
	AMR="print-dirs"
	;;
"-w")
	echo "Write output to the proper file"
	;;
"-v")
	echo "amr: version ${VERSION}"
	exit 0
	;;
""|"-h")
	show_usage 0
	;;
*)
	show_usage 1
	;;
esac

CSOURCES=""
CDEPS_VARS=""
CDIRS=""
CDIR=""
COLDIR=""
CDEPS_VAR_IS_DEFINED=0
CINCLUDES=""
_MODE=0
_COMMENT=0

check_cidep() {
	FILE=$1
	for A in $CINCLUDES ; do
		[ "$A" = "$FILE" ] && return
	done

	echo "CInclude ${FILE} not found" > /dev/stderr
	exit 1
}

check_cdep() {
	FILE=$1
	for A in $CSOURCES ; do
		[ "$A" = "$FILE" ] && return
	done

	echo "CSource ${FILE} not found" > /dev/stderr
	exit 1
}

# Check if we're in the root.
MYDIR=${PWD}
RTDIR=${PWD}
NESTED=0
while : ; do
	cd ..
	if [ -e "configure.amr" ]; then
		RTDIR=${PWD}
		NESTED=1
		break
	fi
	[ "${PWD}" = "/" ] && break
done

cd ${RTDIR}
PKGNAME=`basename ${PWD}`

cd ${MYDIR}

if [ "gen-configure" = "$AMR" ]; then
	FILES=`find . -type f -name "*.c"`
	for A in $FILES ; do
		case "$A" in
		*c$)
			CDIR="`echo $A| awk -F / '{ for(i=1;i<NF;i++){ str=str$i"/" } print str }'`"
			if [ -z "`echo $CDIRS|grep $CDIR`" ]; then
				CDIRS="${CDIRS} ${CDIR}"
			fi
			CSOURCES="${CSOURCES} $A"
			_INCLUDES=`grep '#include <' "${A}" | sed -e 's,<,,' -e 's,>,,' | cut -d \  -f 2`
			for INC in  ${_INCLUDES}; do
				if [ -z "`echo ${CINCLUDES} | grep ${INC}`" ]; then
					CINCLUDES="${CINCLUDES} ${INC}"
				fi
			done
			;;
		*)
		esac
	done

	COLDIR=$CDIRS
	echo "## sample configure.amr ##"
	for A in $CDIRS ; do
		CDIR=$A
		echo "CDIR $CDIR"
		[ ! "${CDIR}" = "./" ] && continue
		echo
		CFILES=""
		for B in $CSOURCES; do
			FILE="`echo $CDIR $B | awk '{print substr($2,length($1)+1); }'`"
			CFILES="${CFILES} ${FILE}"
		done
		[ "${CFILES}" ] && echo "CSOURCES ${CFILES} ;"

		HFILES=""
		HFILES=`find . | grep \.h | sed -e 's,\./,,'`
		#for B in ${CINCLUDES}; do
		#	FILE="`echo $CDIR $B | awk '{print substr($2,length($1)+1); }'`"
		#	FILE="`echo $CDIR $B | awk '{print substr($2,length($1)+1); }'`"
		#	HFILES="${HFILES} ${FILE}"
		#done
		echo "CINCLUDES ${CINCLUDES} ;"
		echo

		for B in $HFILES ; do
			STR=""
			for C in $CFILES ; do
				if [ -n "`cat ${CDIR}/$C | grep '#include "' | grep $B`" ]; then
					STR="${STR} ${C}"
				fi
			done
			[ -n "${STR}" ] && echo "CDEPS ${B}${STR} ;"
		done
	done
	exit 0
fi

if [ ! -e "configure.amr" ]; then
	echo "amr: 'configure.amr' file not found. Use 'amr -a > configure.amr' first."
	exit 1
fi

parse_configure_amr() {
FILE=$1
echo "Parsing ${FILE}..." >/dev/stderr
CONFIGURE_AMR="`cat ${FILE} 2>/dev/null`"
for A in $CONFIGURE_AMR ; do
	# TODO: Support for oneline commands and /* */
	# COMMENT
	if [ "$A" = "##" ]; then
		if [ "$_COMMENT" = 0 ]; then
		_COMMENT=1 ; else _COMMENT=0; fi
	fi
	[ "${_COMMENT}" = 1 ] && continue

	case "$A" in 
	"##")
		;;
	"CSOURCES")
		_MODE=csources
		;;
	"CINCLUDES")
		_MODE=cincludes
		;;
	"CDEPS")
		_MODE=cdeps
		;;
	"CDIR")
		_MODE=cdir
		;;
	*)
		case "${_MODE}" in
		"csources")
			if [ ";" = "$A" ]; then
			_MODE=0 ; continue ; fi
			CSOURCES="${CSOURCES} ${CDIR}/${A}"
			COBJECTS="${COBJECTS} `echo ${CDIR}/${A} | sed -e 's,\.c,\.o,g'`"
			;;
		"cdir")
			CDIR=$A
			_MODE=0
			;;
		"cincludes")
			if [ ";" = "$A" ]; then
			_MODE=0 ; continue ; fi
			CINCLUDES="${CINCLUDES} ${A}"
			;;
		"cdeps")
			if [ ";" = "$A" ]; then
			_MODE=0 ; CDEPS_VAR_IS_DEFINED=0 ; continue ; fi
			if [ "${CDEPS_VAR_IS_DEFINED}" = 0 ]; then
				CDEPS_VAR="`echo ${CDIR}/${A} | sed -e 's,^\.,,' -e 's,//,/,g' -e 's,\.,_,g' -e 's,/,_,g'`"
				CDEPS_VARS="${CDEPS_VARS} ${CDEPS_VAR}"
				CDEPS_VAR_IS_DEFINED=1
				continue
			fi
			check_cdep "${CDIR}/$A"
			eval "${CDEPS_VAR}=\"\$${CDEPS_VAR} ${A}\""
			;;
		*|0)
			echo "Invalid keyword '$A'" > /dev/stderr
			exit 1
			;;
		esac
	;; esac
done
}

parse_configure_amr "configure.amr"

COBJECTS=`echo ${COBJECTS} | sed -e 's,\.//,,g'`

case "$AMR" in
"gen-makefile")
	echo "## Sample Makefile.acr ##"
	echo "VPATH=@VPATH@"
	if [ -n "${CSOURCES}" ]; then
		echo "CC=@CC@"
		echo "CFLAGS=@CFLAGS@"
		echo "LDFLAGS=@LDFLAGS@"
	fi

	# TODO: handle multiple subdirectories
	if [ "${CDIR}" = "./" ]; then
		echo "OBJ=${COBJECTS}"
		echo "BIN=@PKGNAME@"
		echo "VERSION=@VERSION@"
		echo
		echo "all: \${OBJ}"
		echo "	\${CC} \${LDFLAGS} \${OBJ} -o \${BIN}"
		echo
		for A in ${COBJECTS}; do
			CFILE="`echo ${A} | sed -e 's,\.o,\.c,g'`"
			DEPS=`cat ${CFILE} | grep '#include "' | sed -e 's,",,g' | cut -d \  -f 2`
			DEPS="${CFILE} $(echo $DEPS)"
			echo "${A}: ${DEPS}" | sed -e 's,//,/,g'
			printf "\t \${CC} \${CFLAGS} -c -o ${A} $<"
			echo
			echo
		done
		echo "clean:"
		echo "	-rm -f \${OBJ} \${BIN}"
		echo
		echo "mrproper:"
		echo "	-rm -f Makefile"
	else
		echo
		echo "all:"
		echo "	cd ${CDIR} && ${S}{MAKE} all"
		echo
		echo "install:"
		echo "	cd ${CDIR} && ${S}{MAKE} install"
		echo
		echo "clean:"
		echo "	cd ${CDIR} && ${S}{MAKE} clean"
		echo 
		echo "mrproper:"
		echo "	cd ${CDIR} && ${S}{MAKE} mrproper"
		echo
		echo "dist: mrproper"
        	echo "	cd .. && mv ${S}{PKGNAME}-${S}{VERSION}"
        	echo "	-cd .. && tar czvf ${S}{PKGNAME}-${S}{VERSION}.tar.gz \\"
        	echo "	\`find ${S}{PKGNAME}-${S}{VERSION} -type f|grep -v git\`"
        	echo "	cd .. && mv ${S}{PKGNAME}-${S}{VERSION} ${S}{PKGNAME}"
		echo
	fi
	;;
"print-dirs")
	echo $CDIR
	;;
"gen-acr")
	# Recursive parse configure.acr
	CDIR_ORIG=${CDIR}
	for A in ${CDIR}; do
		parse_configure_amr "${A}/configure.amr"
	done
	CDIR=${CDIR_ORIG}
	echo "## sample configure.acr ##"
	if [ "${NESTED}" = 0 ]; then
	echo "PKGNAME ${PKGNAME}"
	echo "VERSION 0.1" # TODO
	echo "CONTACT your name ; your@email" # TODO
	echo
	fi
	[ -n "${CSOURCES}" ] && echo "LANG_C!"
	echo
	for A in ${CINCLUDES} ; do
		echo "CHKINC! ${A}"
	done
	echo
	SFILES=`find .| grep acr| grep -v Makefile| grep -v configure | sed -e 's,\.acr,,g'`
	echo "SUBDIRS . ${CDIR} ${SFILES} ;"
	;;
"gen-shellscript")
	;;
"show-report")
	echo "CSOURCES = ${CSOURCES}"
	echo "CINCLUDES = ${CINCLUDES}"
	echo "CDEPS_VARS = ${CDEPS_VARS}"

	S="\$"
	for A in ${CDEPS_VARS} ; do
		echo "-. $A"
		for B in `eval echo ${S}${A}`;do
			echo " |- $B"
		done
	done
	;;
esac

# if [ main.h > main.o ]; then
#  rm -f main.o usage.o engine.o
# fi
