#!/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

# target defaults that can be overridden by $TARGET.conf

CHIPSET=10
DSP=36
RF=12
DISABLE_SLEEP=0
FCHG_STATE=0
RVTMUX_ON_MODEM=0

. "targets/$TARGET.conf"

# settings derived from the target-defined DSP version

case "$DSP" in
	33)
		AMR=0
		L1_DYN_DSP_DWNLD=0
		L1_VOICE_MEMO_AMR=0
		MELODY_E2=0
		SPEECH_RECO=0
		;;
	34)
		AMR=1
		L1_DYN_DSP_DWNLD=0
		L1_VOICE_MEMO_AMR=0
		MELODY_E2=0
		SPEECH_RECO=0
		;;
	36)
		AMR=1
		L1_DYN_DSP_DWNLD=1
		L1_VOICE_MEMO_AMR=1
		MELODY_E2=1
		SPEECH_RECO=1
		;;
	*)
		echo "Error: DSP=$DSP setting not understood" 1>&2
		exit 1
esac

# functional configuration part

# these vars MUST be set by the functional config
GPRS=
MMI=
R2D_STATE=
SRVC=

# dummy defaults for sans-UI configs
R2D_EMBEDDED_LCD=7
UI_CONFIG=bigcolor

# apply functional config

. "configs/$CONFIG"

# verify it

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

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

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

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

if [ "$MMI" != 0 ]
then
	FCHG_STATE=1
fi

# miscellaneous configurable feature settings

ALLOW_CSIM_GSM=1
MEMSUPER=0
OSL=0
OSX=0
SERIAL_DYNAMIC_SWITCH=0
TI_PROFILER=0
TRACEMASK_IN_FFS=0
TR_BAUD_CONFIG=TR_BAUD_115200
USE_CACHE=1
USE_STR2IND=0

SUFFIX=

# allow the user to override these defaults

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

BUILD_DIR="build-$TARGET-$CONFIG$SUFFIX"

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 [ $# != 1 ]
	then
		echo "Error: build_lib takes 1 argument" 1>&2
		exit 1
	fi
	scripts/mk-component.sh "$1"
	SUBDIR="$SUBDIR $1"
	current_lib=$1/$1.lib
	LIBS="$LIBS $current_lib"
}

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

cache_lib() {
	if [ $# != 1 ]
	then
		echo "Error: cache_lib takes 1 argument" 1>&2
		exit 1
	fi
	current_lib="../cache/$1.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
export CHIPSET DSP RF
export AMR L1_DYN_DSP_DWNLD L1_VOICE_MEMO_AMR MELODY_E2 SPEECH_RECO
export DISABLE_SLEEP
export FCHG_STATE R2D_STATE
export GPRS MMI SRVC RVTMUX_ON_MODEM
export R2D_EMBEDDED_LCD UI_CONFIG
export ALLOW_CSIM_GSM SERIAL_DYNAMIC_SWITCH TR_BAUD_CONFIG
export TI_PROFILER TRACEMASK_IN_FFS
export MEMSUPER OSL

scripts/config-headers.sh

SUBDIR=
LIBS=
SPECIAL_LINK_LIBS=
current_lib=

if [ "$USE_CACHE" = 1 ]
then
	cache_lib ccddata
else
	build_lib ccddata
fi

# ACI libs
build_lib aci
build_lib aciext
build_lib aci_dti_mng
build_lib atiext
build_lib comlib

if [ "$GPRS" = 1 ]
then
	build_lib config_gprs_fl
	build_lib config_gprs_ir
else
	build_lib config_gsm_fl
	build_lib config_gsm_ir
fi
lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'

# UI layers
if [ "$MMI" = 2 ]
then
	build_lib bmi
	if [ "$UI_CONFIG" = bigcolor ]
	then
		build_lib icn
	fi
	build_lib mfw
fi

# G23M protocol stack libs
build_lib alr
build_lib cc
build_lib dl
build_lib dti
build_lib l1_pei
build_lib mm
build_lib rr
build_lib sim_b_lib
build_lib sms
build_lib ss
build_lib uart_b_lib

# fax and data
if [ "$SRVC" != 0 ]
then
	build_lib l2r
	build_lib ra
	build_lib rlp
fi

# fax specific
if [ "$SRVC" = 1 ]
then
	build_lib fad
	build_lib t30
fi

# GPRS specific
if [ "$GPRS" = 1 ]
then
	build_lib cci
	build_lib cci_ir
	lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'
	build_lib cl
	build_lib gmm
	build_lib grlc
	build_lib grlc_ir
	lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'
	build_lib grr
	build_lib llc
	build_lib sm
	build_lib sndcp
	build_lib ppp
	build_lib ppp_ir
	lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'
	build_lib upm
fi

# Condat drivers
build_lib gdi

# GPF

if [ "$USE_CACHE" = 1 -a "$MEMSUPER" = 0 ]
then
	cache_lib ccd_na7_db
elif [ "$USE_CACHE" = 1 -a "$MEMSUPER" = 2 ]
then
	cache_lib ccd_na7_db_ps
else
	build_lib ccd
fi

if [ "$USE_CACHE" = 1 -a "$MEMSUPER" = 0 -a "$OSL" = 0 ]
then
	cache_lib frame_na7_db_fl
	cache_lib frame_na7_db_ir
elif [ "$USE_CACHE" = 1 -a "$MEMSUPER" = 2 -a "$OSL" = 0 ]
then
	cache_lib frame_na7_db_ps_fl
	cache_lib frame_na7_db_ps_ir
else
	build_lib frame_fl
	build_lib frame_ir
fi
lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'

if [ "$USE_CACHE" = 1 ]
then
	cache_lib misc_na7_db_fl
	cache_lib misc_na7_db_ir
else
	build_lib misc_fl
	build_lib misc_ir
fi
lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'

if [ "$OSX" = 1 -o "$MEMSUPER" != 0 ]
then
	build_lib osx
else
	blob_lib osx_na7_db
fi
lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'

build_lib tif_fl
build_lib tif_ir
lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'

# core drivers
build_lib drivers_flash

# Layer 1
build_lib tpudrv
lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'
build_lib l1_ext
lib_link_magic '(BSS_LIBS (.l1s_global))'
build_lib l1_int
lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'
build_lib l1_custom_ext
build_lib l1_custom_int
lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'

build_lib riviera_core_flash
build_lib riviera_cust_flash

# services
build_lib audio
build_lib audio_bgd
build_lib cst
build_lib dar
build_lib dar_gbl_var
lib_link_magic '(BSS_DAR_LIB (.bss))'
build_lib etm
build_lib lls

# app drivers
build_lib abb
build_lib buzzer
if [ "$FCHG_STATE" = 1 ]
then
	build_lib fchg
fi
build_lib ffs
build_lib ffs_drv
build_lib ffs_pcm
build_lib kpd
build_lib power
if [ "$R2D_STATE" = 1 ]
then
	build_lib r2d_drv_custom_flash
	build_lib r2d_drv_flash
	build_lib r2d_drv_int_ram
	lib_link_magic '(CONST_LIBS (.text, .r2dlcd))'
fi
build_lib rtc_drv
build_lib sim_drv
build_lib spi_drv
build_lib uart_drv

# system glue
build_lib main
build_lib bootloader
lib_link_magic '(CONST_BOOT_LIB (.const, .text, .text:v$3) BSS_BOOT_LIB (.bss))'

# Nucleus
if [ "$USE_CACHE" = 1 ]
then
	cache_lib nucleus_flash
	cache_lib nucleus_intram
else
	build_lib nucleus_flash
	build_lib nucleus_intram
fi
lib_link_magic '(BSS_LIBS (.bss) CONST_LIBS (.text, .const))'

# TI's libc/libgcc equivalent
blob_lib rts16le_flash
blob_lib rts16le_int_ram
lib_link_magic '(BSS_LIBS (.bss))'

# generate the top level Makefile!

helpers/makeline def CONFIG_NAME "$CONFIG$SUFFIX" > $BUILD_DIR/Makefile
echo >> $BUILD_DIR/Makefile
helpers/makeline def TARGET $TARGET >> $BUILD_DIR/Makefile
echo >> $BUILD_DIR/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

if [ -n "$RAM_LINK_SCRIPT_SRC" ]
then
	helpers/makeline def RAM_LINK_SCRIPT_SRC ../$RAM_LINK_SCRIPT_SRC \
		>> $BUILD_DIR/Makefile
	echo >> $BUILD_DIR/Makefile
fi

helpers/makeline def FLASH_BASE_ADDR $FLASH_BASE_ADDR >> $BUILD_DIR/Makefile
helpers/makeline def FLASH_SECTOR_SIZE $FLASH_SECTOR_SIZE >> $BUILD_DIR/Makefile
echo >> $BUILD_DIR/Makefile

if [ "$USE_STR2IND" = 1 ]
then
	helpers/makeline def STR2IND_OBJ str2ind.obj >> $BUILD_DIR/Makefile
else
	echo 'STR2IND_OBJ=' >> $BUILD_DIR/Makefile
fi
echo >> $BUILD_DIR/Makefile

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

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

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

case "$TARGET" in
	c11x|c139|j100)
		cat makefile-frags/m0-to-bin-c139 >> $BUILD_DIR/Makefile
		;;
	c155)
		cat makefile-frags/m0-to-bin-c155 >> $BUILD_DIR/Makefile
		;;
	*)
		cat makefile-frags/m0-to-bin-std >> $BUILD_DIR/Makefile
		;;
esac

cat makefile-frags/flash-script-gen >> $BUILD_DIR/Makefile

if [ -n "$RAM_LINK_SCRIPT_SRC" ]
then
	cat makefile-frags/ram-link-steps >> $BUILD_DIR/Makefile
fi

cat makefile-frags/clean-always >> $BUILD_DIR/Makefile
echo >> $BUILD_DIR/Makefile
echo 'FRC:' >> $BUILD_DIR/Makefile

# All done!

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