#!/bin/sh

set -e

if [ ! -f configure.sh ]
then
	echo "This script needs to be run from the top of the source tree" 1>&2
	exit 1
fi

if [ ! -f helpers/makeline ]
then
	echo "Please run make in the helpers directory first" 1>&2
	exit 1
fi

# start looking at our invokation line

if [ "$1" == --clean ]
then
	clean_flag=1
	shift
else
	clean_flag=0
fi

if [ $# -lt 2 ]
then
	echo "usage: $0 [--clean] target config [vars]" 1>&2
	exit 1
fi

TARGET="$1"
CONFIG="$2"

if [ ! -f "targets/$TARGET.conf" -o ! -f "targets/$TARGET.h" ]
then
	echo "Error: target $TARGET not known" 1>&2
	exit 1
fi

if [ ! -f "configs/$CONFIG" ]
then
	echo "Error: configuration $CONFIG not known" 1>&2
	exit 1
fi

. "targets/$TARGET.conf"

BUILD_DIR="build-$TARGET-$CONFIG"
USE_STR2IND=0

# allow the user to override these defaults

shift
shift
while [ $# != 0 ]
do
	eval "$1"
	shift
done

echo "Building configuration $CONFIG for target $TARGET in $BUILD_DIR"

if [ "$clean_flag" = 1 ]
then
	rm -rf $BUILD_DIR
fi
mkdir -p $BUILD_DIR

: > $BUILD_DIR/lcfgen

# shell functions to be used in the configuration recipe

build_lib() {
	if [ $# -lt 1 -o $# -gt 2 ]
	then
		echo "Error: build_lib takes 1 or 2 arguments" 1>&2
		exit 1
	fi
	scripts/mk-component.sh "$1" "$2"
	SUBDIR="$SUBDIR $1"
	current_lib=$1/$1.lib
	LIBS="$LIBS $current_lib"
}

blob_lib_std() {
	if [ $# != 1 ]
	then
		echo "Error: blob_lib_std takes 1 argument" 1>&2
		exit 1
	fi
	current_lib="../blobs/libs/$1.lib"
	LIBS="$LIBS $current_lib"
}

blob_lib_gpf() {
	if [ $# != 1 ]
	then
		echo "Error: blob_lib_gpf takes 1 argument" 1>&2
		exit 1
	fi
	current_lib="../blobs/gpflibs/$1.lib"
	LIBS="$LIBS $current_lib"
}

blob_lib_os() {
	if [ $# != 1 ]
	then
		echo "Error: blob_lib_os takes 1 argument" 1>&2
		exit 1
	fi
	current_lib="../blobs/oslibs/$1.lib"
	LIBS="$LIBS $current_lib"
}

blob_lib_custom() {
	if [ $# != 2 ]
	then
		echo "Error: blob_lib_custom takes 2 arguments" 1>&2
		exit 1
	fi
	if [ -z "$1" ]
	then
		echo "Error: this config is not supported on this target" 1>&2
		exit 1
	fi
	cp $1 $BUILD_DIR/$2.lib
	current_lib=$2.lib
	LIBS="$LIBS $current_lib"
}

lib_link_magic() {
	if [ $# != 1 ]
	then
		echo "Error: lib_link_magic takes 1 argument" 1>&2
		exit 1
	fi
	if [ -z "$current_lib" ]
	then
	  echo "Error: lib_link_magic called before build_lib or blob_lib" 1>&2
	  exit 1
	fi
	SPECIAL_LINK_LIBS="$SPECIAL_LINK_LIBS $current_lib"
	echo "$1" >> $BUILD_DIR/lcfgen
}

# invoke the configuration recipe

export BUILD_DIR TARGET USE_STR2IND

SUBDIR=
LIBS=
SPECIAL_LINK_LIBS=
current_lib=

. "configs/$CONFIG"

# str2ind magic

if [ -z "$str2ind_blobs_used" ]
then
	echo "Error: configs/$CONFIG must set str2ind_blobs_used" 1>&2
	exit 1
fi

if [ "$str2ind_blobs_used" = 1 ]
then
	cp blobs/str2ind.tab $BUILD_DIR
fi

if [ "$str2ind_blobs_used" = 0 -a "$USE_STR2IND" = 0 ]
then
	echo 'char *str2ind_version = "&0";' > $BUILD_DIR/str2ind.c
fi

# generate the top level Makefile!

helpers/makeline def SUBDIR $SUBDIR > $BUILD_DIR/Makefile
echo >> $BUILD_DIR/Makefile
helpers/makeline def LIBS $LIBS >> $BUILD_DIR/Makefile
echo >> $BUILD_DIR/Makefile
helpers/makeline def SPECIAL_LINK_LIBS $SPECIAL_LINK_LIBS >> $BUILD_DIR/Makefile
echo >> $BUILD_DIR/Makefile
helpers/makeline def LINK_SCRIPT_SRC ../$LINK_SCRIPT_SRC >> $BUILD_DIR/Makefile
echo >> $BUILD_DIR/Makefile

cat makefile-frags/first-part >> $BUILD_DIR/Makefile

if [ "$USE_STR2IND" = 1 ]
then
	cat makefile-frags/str2ind-tab-depend >> $BUILD_DIR/Makefile
fi

if [ "$str2ind_blobs_used" = 1 -o "$USE_STR2IND" = 1 ]
then
	cat makefile-frags/str2ind-c-gen >> $BUILD_DIR/Makefile
fi

cat makefile-frags/link-steps >> $BUILD_DIR/Makefile

cat makefile-frags/clean-always >> $BUILD_DIR/Makefile
if [ "$str2ind_blobs_used" = 0 ]
then
	echo '	rm -f str2ind.tab str2ind.log' >> $BUILD_DIR/Makefile
fi
if [ "$str2ind_blobs_used" = 1 -o "$USE_STR2IND" = 1 ]
then
	echo '	rm -f str2ind.c' >> $BUILD_DIR/Makefile
fi
echo >> $BUILD_DIR/Makefile
echo 'FRC:' >> $BUILD_DIR/Makefile

# All done!

echo "Run make in $BUILD_DIR to compile the firmware"
