#!/bin/bash

topdir="$HOME/np"

arm_target=armv4tl-softfloat-linux-gnueabi
dsp_target=c6x-none-elf

die () {
	echo "$@" >&2
	exit 1
}

fetch () {
	local url="$1";
	local file="${url##*/}"

	if [ -r "$topdir/src/$file" ]; then
		echo "$file: file already exists skipping download"
	else
		(cd "$topdir/src" && wget "$@") || die "cannot fetch $@"
	fi
}

verify () {
	local sum="$1"
	local file="$2"

	my_sum=$(sha1sum "$topdir/src/$file" | awk '{ print $1 }')
	if [ "$my_sum" == "$sum" ]; then
		echo "$file: checksum OK" >&2
	else
		die "$file: checksum verification error $my_sum, should be $sum"
	fi
}

untar () {
	local pkg="$1"
	local file="$2"
	local dir="$3";

	[ -n "$dir" ] || dir="$topdir/src"
	mkdir -p "$dir"

	if [ -d "$dir/$pkg" ]; then
		echo "$pkg: skipping untar" >&2
	else
		(cd "$dir"; tar xf "$topdir/src/$file") \
			|| die "$file: cannot untar"
	fi
}

patch_pkg () {
	local pkg="$1"
	local file="$2"
	local dir="$3"
	local nr="$4"

	[ -n "$dir" ] || dir="$topdir/src"
	mkdir -p "$dir"

	if [ -r "$dir/$pkg/.patch-$nr-applied" ]; then
		echo "$pkg: skipping patch $nr" >&2
	else
		echo "$pkg: applying patch $nr" >&2
		(cd "$dir/$pkg" && patch -p1 < "$topdir/src/$file"; \
			touch "$dir/$pkg/.patch-$nr-applied") \
			|| die "$file: cannot patch $nr"
	fi
}

build () {
	local dir="$1"
	local pkg="$2"
	shift 2;

	echo "$dir: starting build..." >&2
	(
	mkdir -p "$topdir"/build/"$dir" &&
	cd "$topdir"/build/"$dir" &&
	"$topdir"/src/"$pkg"/configure "$@" &&
	make "$MAKEFLAGS" && make install
	) || die "$dir: build error"
}

build_strip () {
	local dir="$1"
	local pkg="$2"
	shift 2;

	echo "$dir: starting build..." >&2
	(
	mkdir -p "$topdir"/build/"$dir" &&
	cd "$topdir"/build/"$dir" &&
	"$topdir"/src/"$pkg"/configure "$@" &&
	make "$MAKEFLAGS" && make install-strip
	) || die "$dir: build error"
}

echo "Building np firmware..." >&2

echo -n "checking number of processors... " >&2
CPUS=$(nproc 2>/dev/null)
if test "$?" -eq 0; then
	echo "$CPUS" >&2
else
	echo "failed (missing nproc?), using 4 by default" >&2
	CPUS=4
fi
[ -n "$CPUS" ] || CPUS=4

MAKEFLAGS="-j$CPUS"

mkdir -p "$topdir"/src || die "cannot create '$topdir/src'"
mkdir -p "$topdir"/build || die "cannot create '$topdir/build'"

echo -n "checking for ARM cross-compiler... " >&2
if [ -x "$topdir/bin/$arm_target-gcc" ]; then
	echo "ok" >&2
else
	echo "missing" >&2
	echo "Please run np-build-toolchain first" >&2
	exit 1
fi

echo -n "checking for C6X cross-compiler... " >&2
if [ -x "$topdir/bin/$dsp_target-gcc" ]; then
	echo "ok" >&2
else
	echo "missing" >&2
	echo "Please run np-build-toolchain first" >&2
	exit 1
fi

fetch ftp://ftp.podlesie.net/pub/km/np/aic3106-conf-0.0.0.tar.gz
verify b4a420cad98b1aa1d59b80c6b8b605cb418c6dbd aic3106-conf-0.0.0.tar.gz
untar aic3106-conf-0.0.0 aic3106-conf-0.0.0.tar.gz "$topdir/build"
if [ -x "$topdir/destroot/bin/aic3106-conf" ]; then
	echo "aic3106-conf already installed, skipping compilation" >&2
else
	echo "building aic3106-conf..." >&2
	build_strip aic3106-conf-0.0.0 ../build/aic3106-conf-0.0.0 \
		--host "$arm_target" \
		--prefix "$topdir/destroot"
fi

fetch ftp://ftp.podlesie.net/pub/km/np/dspboot-0.0-np.tar.gz
verify 35a7d1852745897523a8dedb549bfb693cff8f6b dspboot-0.0-np.tar.gz
untar dspboot-0.0-np dspboot-0.0-np.tar.gz "$topdir/build"
if [ -x "$topdir/destroot/bin/dspboot" ]; then
	echo "dspboot already installed, skipping compilation" >&2
else
	echo "building dspboot..." >&2
	(
	cd "$topdir"/build/dspboot-0.0-np &&
	make "$MAKEFLAGS" CROSS_COMPILE="$arm_target-" dspboot &&
	"$arm_target-strip" dspboot &&
	install -m 755 dspboot "$topdir"/destroot/bin/dspboot
	) || die "$dir: build error"
fi

if [ -r "$topdir/build/np-dsp-kernel.bin" ]; then
	echo "np-dsp already installed, skipping compilation" >&2
else
	echo "building np-dsp..." >&2

	fetch ftp://ftp.podlesie.net/pub/km/np/np-dsp-0.0.0.tar.gz
	verify 4a3349cd06a0b6c03c761d80d377f5ce2b8d78c9 np-dsp-0.0.0.tar.gz
	untar np-dsp-0.0.0 np-dsp-0.0.0.tar.gz "$topdir/build"
	(
	cd "$topdir"/build/np-dsp-0.0.0 &&
	./configure --host "$dsp_target" &&
	: > src/payload.bin &&
	make "$MAKEFLAGS" && dd if=src/np-dsp.bin bs=65536 conv=sync of="$topdir/build/np-dsp-kernel.bin"
	) || die "$dir: build error"
fi

if ! [ -r "$topdir"/src/np-anc-0.0.0.tar.gz ]; then
	echo "The '$topdir/src/np-anc-0.0.0.tar.gz' file is missing." >&2
	echo "It cannot be fetched. Please install it." >&2
	exit 1
fi
verify b83f56b861b7aa5335898129e1c02f15dc58a140 np-anc-0.0.0.tar.gz
untar np-anc-0.0.0 np-anc-0.0.0.tar.gz "$topdir/build"

if [ -r "$topdir/destroot/share/np-dsp.bin" ]; then
	echo "np-dsp already installed, skipping compilation" >&2
else
	mkdir -p "$topdir"/destroot/share
	(
	cd "$topdir"/build/np-anc-0.0.0 &&
	./configure --host "$dsp_target" &&
	make "$MAKEFLAGS" && cat "$topdir/build/np-dsp-kernel.bin" "src/np-anc.bin" > "$topdir/destroot/share/np-dsp.bin"
	) || die "$dir: build error"
fi

fetch ftp://ftp.kernel.org/pub/linux/kernel/v4.x/linux-4.7.2.tar.xz
verify eb9e03765e02f93533b1efc3635a634f20779084 linux-4.7.2.tar.xz
untar linux-4.7.2 linux-4.7.2.tar.xz "$topdir/build"

fetch ftp://ftp.podlesie.net/pub/km/np/linux-np.tar.gz
verify 8dfc79a3b2ffab84d192fba385f94cca3327aee9 linux-np.tar.gz
untar linux-np linux-np.tar.gz "$topdir/build/linux-4.7.2"

linux_np="$topdir/build/linux-4.7.2/linux-np"
install -m 755 "$topdir/destroot/bin/aic3106-conf" "$linux_np/root/usr/sbin/"
install -m 755 "$topdir/destroot/bin/dspboot" "$linux_np/root/usr/sbin/"
install -m 644 "$topdir/destroot/share/np-dsp.bin" "$linux_np/root/usr/share/np"

patch_pkg linux-4.7.2 "../build/linux-4.7.2/linux-np/patches/0001-configure-da850-for-np.patch" "$topdir/build" 1
patch_pkg linux-4.7.2 "../build/linux-4.7.2/linux-np/patches/0002-configure-da830-for-np.patch" "$topdir/build" 2
patch_pkg linux-4.7.2 "../build/linux-4.7.2/linux-np/patches/0003-davinci-disable-SPI-flash-on-da830.patch" "$topdir/build" 3

(cd "$topdir"/build/linux-4.7.2

MYGID="$(id -g)"
sed -i "s/^CONFIG_INITRAMFS_ROOT_UID=.*/CONFIG_INITRAMFS_ROOT_UID=$UID/" \
       	linux-np/.config
sed -i "s/^CONFIG_INITRAMFS_ROOT_GID=.*/CONFIG_INITRAMFS_ROOT_GID=$MYGID/" \
       	linux-np/.config

make ARCH=arm O=linux-np oldconfig < /dev/null
make ARCH=arm CROSS_COMPILE="$arm_target-" O=linux-np "$MAKEFLAGS" uImage
install -m 644 linux-np/arch/arm/boot/uImage "$topdir"/uImage
)
