#!/bin/bash

##############################################################################
# Yocto Project-based Build System for Building SoFIA Software Setup Script
##############################################################################

REPOTAG="repo-oe"
REPOSRC="http://commondatastorage.googleapis.com/git-repo-downloads/repo"
REPOCOMMONDIR="$HOME/common/bin"
OEROOT=poky-sofia
BASEDIR=$(pwd)
MANIFESTSRC=$BASEDIR/manifests

NCPUS=$(grep -c processor /proc/cpuinfo)
PROGNAME=setup-build-env-ext
LINUX_ONLY=false

###############################################################################
# Unpacking released package
###############################################################################
unpack_tarball_meta-intel-sofia-sw() {
	echo "Unpacking meta-intel-sofia-sw packages ..."
	cd $BASEDIR
	tar -jxvf tarballs/meta-intel-sofia-sw.tar.bz2 -C $OEROOT/
	tar -jxvf tarballs/meta-intel-sofia.tar.bz2 -C $OEROOT/meta-intel-sofia-sw/
	tar -jxvf tarballs/meta-intel-sofia-mobilevisor.tar.bz2 -C $OEROOT/meta-intel-sofia-sw/
	tar -jxvf tarballs/meta-intel-sofia-distro.tar.bz2 -C $OEROOT/meta-intel-sofia-sw/
}

unpack_tarball_sofia-fw() {
	echo "Unpacking sofia-fw packages ..."
	cd $BASEDIR
	mkdir -p sofia-fw/build
	tar -jxvf tarballs/sofia-fw-build.tar.bz2 --strip-components=1 -C sofia-fw/build
	cp sofia-fw/build/core/root.mk sofia-fw/Makefile

	mkdir -p sofia-fw/external/openssl
	tar -jxvf tarballs/sofia-fw-external-openssl.tar.bz2 --strip-components=1 -C sofia-fw/external/openssl

	mkdir -p sofia-fw/system/extras
	tar -jxvf tarballs/sofia-fw-system-extras.tar.bz2 --strip-components=1 -C sofia-fw/system/extras

	mkdir -p sofia-fw/device/intel/sofia3g-kernel
	tar -jxvf tarballs/sofia-fw-device-intel-sofia3g-kernel.tar.bz2 --strip-components=1 -C sofia-fw/device/intel/sofia3g-kernel

	mkdir -p sofia-fw/device/intel/sofia3gr
	tar -jxvf tarballs/sofia-fw-device-intel-sofia3gr.tar.bz2 --strip-components=1 -C sofia-fw/device/intel/sofia3gr

	mkdir -p sofia-fw/device/intel/build
	tar -jxvf tarballs/sofia-fw-device-intel-build.tar.bz2 --strip-components=1 -C sofia-fw/device/intel/build

	mkdir -p sofia-fw/device/intel/common
	tar -jxvf tarballs/sofia-fw-device-intel-common.tar.bz2 --strip-components=1 -C sofia-fw/device/intel/common

	mkdir -p sofia-fw/hardware/intel/mrd-3gr-sofia/bootsystems
	tar -jxvf tarballs/sofia-fw-hardware-intel-mrd-3gr-sofia-bootsystems.tar.bz2 --strip-components=1 -C sofia-fw/hardware/intel/mrd-3gr-sofia/bootsystems

	mkdir -p sofia-fw/hardware/intel/mrd-3gr-sofia/mobilevisor/guests
	tar -jxvf tarballs/sofia-fw-hardware-intel-mrd-3gr-sofia-mobilevisor-guests.tar.bz2 --strip-components=1 -C sofia-fw/hardware/intel/mrd-3gr-sofia/mobilevisor/guests

	mkdir -p sofia-fw/hardware/intel/mrd-3gr-sofia/mobilevisor/products
	tar -jxvf tarballs/sofia-fw-hardware-intel-mrd-3gr-sofia-mobilevisor-products.tar.bz2 --strip-components=1 -C sofia-fw/hardware/intel/mrd-3gr-sofia/mobilevisor/products

	mkdir -p sofia-fw/hardware/intel/mrd-3gr-sofia/mobilevisor/release
	tar -jxvf tarballs/sofia-fw-hardware-intel-mrd-3gr-sofia-mobilevisor-release.tar.bz2 --strip-components=1 -C sofia-fw/hardware/intel/mrd-3gr-sofia/mobilevisor/release

	mkdir -p sofia-fw/hardware/intel/mrd-3gr-sofia/mobilevisor/services
	tar -jxvf tarballs/sofia-fw-hardware-intel-mrd-3gr-sofia-mobilevisor-services.tar.bz2 --strip-components=1 -C sofia-fw/hardware/intel/mrd-3gr-sofia/mobilevisor/services

	mkdir -p sofia-fw/hardware/intel/mrd-3gr-sofia/modem
	tar -jxvf tarballs/sofia-fw-hardware-intel-mrd-3gr-sofia-modem.tar.bz2 --strip-components=1 -C sofia-fw/hardware/intel/mrd-3gr-sofia/modem

	mkdir -p sofia-fw/hardware/intel/mrd-3gr-sofia/secure_vm
	tar -jxvf tarballs/sofia-fw-hardware-intel-mrd-3gr-sofia-secure_vm.tar.bz2 --strip-components=1 -C sofia-fw/hardware/intel/mrd-3gr-sofia/secure_vm

	mkdir -p sofia-fw/hardware/intel/mrd-3gr-sofia/soclib
	tar -jxvf tarballs/sofia-fw-hardware-intel-mrd-3gr-sofia-soclib.tar.bz2 --strip-components=1 -C sofia-fw/hardware/intel/mrd-3gr-sofia/soclib
}

unpack_tarball_sofia-fw_linux_only() {
	echo "Unpacking sofia-fw linux only packages ..."
	cd $BASEDIR

	mkdir -p sofia-fw/out
	tar -jxvf tarballs/sofia-fw-out-binaries.tar.bz2 -C sofia-fw/out

	tar -jxvf tarballs/sofia-fw-device-intel-sofia3gr.tar.bz2 -C sofia-fw/

	tar -jxvf tarballs/sofia-fw-hardware-intel-mrd-3gr-sofia.tar.bz2 -C sofia-fw/
}

###############################################################################
# Setting-up repositories (repo init & repo sync) for OE-class build system.
###############################################################################

get_repo() {
	if [ ! -d ${REPOCOMMONDIR} ]; then
		mkdir -p ${REPOCOMMONDIR}
	fi
	if [ ! -f ${REPOCOMMONDIR}/${REPOTAG} ]; then
		curl ${REPOSRC} > ${REPOCOMMONDIR}/${REPOTAG}
		chmod a+x ${REPOCOMMONDIR}/${REPOTAG}
		ln -sf ${REPOCOMMONDIR}/${REPOTAG} ${REPOCOMMONDIR}/repo
	fi
	found=$(which $REPOTAG)
	if [ x"$found" == x ]; then
	export PATH=${REPOCOMMONDIR}:$PATH
	fi
}

repo_init_sync () {
	# initialize repo according to the selected branch
	repo init -u ${MANIFESTSRC} -m ${MANIFESTFILE} -b $BRANCH
	repo sync -c -j${NCPUS}
}

display_repo_setup_info () {
cat << EOF
===============================================================================

The script has successfully created the repositories from hosting server
and also fetched in a 'repo' tool.

Handling multiple 'repo' tool
-----------------------------
To avoid contaminate 'repo' tool fetched from multiple sources such as
Android, Chrome or other in-house development, it is important to use
the right 'repo' that bears the correct PGP signature especially for
in-house development setup.

So, to avoid over-writing your previously curl'ed repo from other project
that may be in one of the following locaions (also already part of PATH
environment variable),

~/bin
/usr/local/bin
/usr/local/sbin
/opt/bin

we suggest that you manually manage those version of 'repo' tool accordingly.
For example, you could choose to do the following:
 1) Create ~/common/bin folder
 2) Append each of the 'repo' tool with a recognisable tag, e.g., repo-android
    repo-chrome & etc at its current location. Then, move those tagged 'repo'
    tool under ~/common/bin
 3) Finally, create a 'repo' symlink under ~/common/bin to target the desired
    tagged repo.
 4) Append ~/common/bin path to environment variable PATH through ~/.bashrc
    or any other user environment config file.

What has been 'source setup-build-env repo'? done
-------------------------------------------------
As part of the setup procedure, this script performs the following:
 1) Create ${REPOCOMMONDIR} if not already exist
 2) Curl 'repo' tool to ${REPOCOMMONDIR}/${REPOTAG} from ${REPOSRC}
 3) Create symlink ${REPOCOMMONDIR}/repo to ${REPOCOMMONDIR}/${REPOTAG}
 4) Export ${REPOCOMMONDIR} at the 1st look-up path for PATH environment
    variable. Note that the PATH setup is only applicable to current shell
    terminal session and you must add below line to your ~/.bashrc manually.

EOF

echo '    $ export PATH=${REPOCOMMONDIR}:$PATH'

cat << EOF

 5) Initialize local development repositories in accordance to ${MANIFESTFILE} manifest kept at:
    ${MANIFESTSRC}:
    $ repo init -u ${MANIFESTSRC} -m ${MANIFESTFILE} -b $BRANCH

 6) Download remote source repositories to local development repositories:
    $ repo sync -c -j${NCPUS}

Not familiar with 'repo' tool?
------------------------------
If you are not familiar with the usage of 'repo' tool, please refer to the
documentation at http://source.android.com/source/developing.html


What is next?
-------------
Once you have confirmed that the repositories are intact, you can proceed to
setup OE-class build system environment by calling the following:

1) Understand the list of <machine type> that is supported by using following command:

   $ source ${PROGNAME} help

2) Setup OE-class build environment, by changing <machine type> below to one of the
   supported machine discovered in step (1)

$ source ${PROGNAME} build -m <machine type>

===============================================================================
EOF
}

###############################################################################
# Setting-up build configuration and environment for OE-class build system
###############################################################################

get_machine_type () {
	case $MACH in
		sofia-3gr)
			lunch_platform="sf3gr_telit_he922"
		;;
		sofia-lte)
			lunch_platform=""
			echo "WARNING: SoFIA LTE is not supported."
		;;
	esac
}

source_build_environment () {
	CURDIR=$(pwd)
	cd $OEROOT
	TEMPLATECONF=meta-intel-sofia-sw/meta-intel-sofia-distro/conf source oe-init-build-env $CURDIR/build-$MACH  > /dev/null

	# Check against any abnormaly in OE-build system initialization
	if [ ! -f conf/local.conf ]; then
		echo "ERROR: There is issue in source oe-init-build-env build!!!"
		return 1
	fi

	get_machine_type

	if [ -z "${lunch_platform}" ]; then
		echo "ERROR: $MACH is currently not supported yet"
		cd $CURDIR
		return 1
	fi

	# Fix-up MACHINE based on the parsed input -m <machine type> or --machine <machine type>
	sed -e "s#SOFIA_MACHINE_TYPE#$MACH#g" -i conf/local.conf
	sed -e "s#LUNCH_MACHINE#${lunch_platform}#g" -i conf/local.conf
	sed -e "s#SOFIABUILDTOP#$CURDIR#g" -i conf/local.conf

	# Fix-up path for OEROOTPATH under bblayer.conf.sample
	sed -e "s#OEROOTPATH#$CURDIR#g" -i conf/bblayers.conf

	cd $CURDIR
	return 0
}

display_build_env_info () {
cat << EOF
===============================================================================
machine type : ${MACH}
build folder : build-${MACH}

This terminal has been source with Poky build system environment.

If you want to continue modify your local build, please modify the default
settings under build-${MACH}/conf/local.conf

If you are bringing in more meta-layer from external, please add the layer path
into BBLAYERS under build-${MACH}/conf/bblayers.conf

To continue with bitbake build process, please perform the following:
---------------------------------------------------------------------

$ cd build-${MACH}
$ bitbake <target-image>

Note:
The target images are placed under build-${MACH}/tmp/deploy/images/${MACH}
The flash binaries are placed under build-${MACH}/tmp/depoy/fls-binary/

To generate SDK tool-chain for application development on SoFIA target platform,
please perform the following:
----------------------------

$ cd build-${MACH}
$ bitbake <target-image> -c populate_sdk

Note: the SDK installer is placed under build-${MACH}/tmp/deploy/sdk

===============================================================================
EOF
}

###############################################################################
# Parsing input arguments
###############################################################################

usage () {
cat << EOF

${PROGNAME} is a wrapper script on-top of 'repo' tool to setup the repositories
and initialize the needed environment for OE-class build system.

It supports two operations:
1) Setting-up repositories (repo init & repo sync) for OE-class build system.

$ source ${PROGNAME} repo -b <branch> | --branch <branch>

2) Setting-up build configuration and environment for OE-class build system.
   This operation depends '${PROGNAME} repo' operation to be executed before.

$ source ${PROGNAME} build -m <machine type> | --machine <machine type>

whereby <machine type> supported are:
$(ls meta-intel-sofia-sw/*/conf/machine/ 2> /dev/null | sed  -e "s#\.conf##g")

Note: sofia-lte is currently NOT supported.

EOF
}

clear_env () {
	unset SETUP_REPO SETUP_BUILD BRANCH MACH
}

do_prepare_env () {
	if [ "${LINUX_ONLY}" == "false" ]; then
		MANIFESTFILE=rel-sofia-3gr.xml
	else
		MANIFESTFILE=rel-sofia-3gr_linux-only.xml
	fi
}

if [ "$0" != "-$(basename $SHELL)" ] && [ "$0" != "$(basename $SHELL)" ] && [ "$0" != "/bin/bash" ]; then
	echo "this script needs to be sourced. Please run as '. $PROGNAME' or 'source $PROGNAME' "
	exit 1
fi

if [ $# -eq 0 ]; then
	usage
	clear_env
	return 1
fi

ALLARG=( $@ )
NUMARGS=${#ALLARG[@]}

for (( idx=0; idx < $NUMARGS; idx++ )); do
	case ${ALLARG[$idx]} in
	-h)
		;&
	--help)
		;&
	help)
		usage
		clear_env
		return 0
		;;
	repo)
		SETUP_REPO=true
		;;
	build)
		SETUP_BUILD=true
		;;
	-b)
		;&
	--branch)
		idx=$((idx+1))
		BRANCH=${ALLARG[$idx]}
		;;
	-m)
		;&
	--machine)
		idx=$((idx+1))
		MACH=${ALLARG[$idx]}
		;;
	--linux)
		LINUX_ONLY=true
		;;
	*)
		echo "ERROR: Unsupported argument detected ${ALLARG[$idx]}"
		usage
		clear_env
		return 1
		;;
	esac
done

if [ "${SETUP_REPO}" == "true" ] && [ -n "${BRANCH}" ] && [ -z "${MACH}" ]; then
	do_prepare_env
	get_repo
	repo_init_sync
	unpack_tarball_meta-intel-sofia-sw
	if [ "${LINUX_ONLY}" == "false" ]; then
		unpack_tarball_sofia-fw
	else
		unpack_tarball_sofia-fw_linux_only
	fi
	display_repo_setup_info
	clear_env
	return
fi

if [ "${SETUP_BUILD}" == "true" ] && [ -n "${MACH}" ] && [ -z "${BRANCH}" ]; then
	if [ ! -d $OEROOT ]; then
	echo "Unpacking meta-intel-sofia-sw packages ..."
		echo "ERROR: It seems like you have not executed source ${PROGNAME} repo -b <branch> ... "
		usage
		return
	fi
	source_build_environment || return 1
	display_build_env_info
	clear_env
	return
fi

if [ "${SETUP_BUILD}" == "true" ] && [ "${SETUP_REPO}" == "true" ]; then
	echo "ERROR: BOTH operations ${PROGNAME} repo AND build are selected. Choose only one operation"
	usage
	clear_env
	return 1
fi

# Below is the catch-all failed operation
echo "ERROR: Found unknown usage of input arguments: $@"
usage
clear_env
return 1
