#!/bin/sh
#
# Sat RPi - SliTaz Raspberry Pi Build Tool
#
# Copyright (C) 2012-2014 SliTaz ARM - BSD License
# Author: Christophe Lincoln <pankso@slitaz.org>
#
. /lib/libtaz.sh

#: ${arch=armv6hf}
: ${arch=arm}

# Paths
[ "$work" ] || work="$(pwd)"
distro="$work/distro"
rpi="$work/rpi"
data="$rpi/data"
cache="$rpi/cache"
boot="$distro/boot"
rootfs="$distro/rootfs"
rpi_git="$rpi/git"
kernel="$rpi_git/linux"
dev="$2"

# URLs
rpi_mirror="http://mirror.slitaz.org/arm/rpi/"
rpi_git_url="git://github.com/raspberrypi/"

#
# Functions
#

usage() {
	cat << EOT

$(boldify "Usage:") $(basename $0) [command] [--option]

SliTaz Raspberry Pi Tool

$(boldify "Commands:")
  info          Display paths and distro info
  install       Install SliTaz RPi to sdcard
  gen           Generate a new SliTaz RPi distro
  cook-linux    Build the Raspberry Pi Linux kernel
  get-linux     Get the SliTaz RPi linux package
  clone-fw      Clone the RPi firmware repository
  get-prebuilt  Get a prebuilt SliTaz ARM toolchain
  clean         Clean the current work directory
  release       Release an installable tarball

$(boldify "Options:")
  --nosat       Don't regenerate the distro with sat
  --nopatch     Don't patch the kernel before cooking
  --gconfig     Configure the kernel before cooking
  --fbtft       Try to compile the Framebuffer touch screen driver

EOT
}

error() {
	echo "[ $(colorize 31 'ERROR') ] $@"
}

header() {
	newline && colorize 35 "$@" && separator
}

# Get all RPi firmware
clone_fw() {
	[ -d "${rpi_git}/firmware" ] && return 0
	mkdir -p ${rpi_git} && cd ${rpi_git}
	git clone --depth 1 ${rpi_git_url}firmware.git
}

umount_sd() {
	umount /dev/${dev}1 2>/dev/null || exit 1
	umount /dev/${dev}3 2>/dev/null || exit 1
}

#
# Commands
#

case "$1" in
	info)
		header "SliTaz Raspberry Pi info"
		echo "RPi path : $rpi"
		colorize 36 "/boot/cmdline.txt:"
		cat ${boot}/cmdline.txt
		colorize 36 "/boot/config.txt:"
		cat ${boot}/config.txt
		separator && newline ;;
	
	install)
		rpiboot="/media/rpi/boot"
		rpiroot="/media/rpi/rootfs"
		header "SliTaz Raspberry Pi install"
		if [ ! "$dev" ]; then
			echo -n "SD card disk name (ex sdc): "; read dev
		fi
		[ ! "$dev" ] && exit 1
		
		# Store sdcard partition(s) list
		fdisk -l /dev/${dev} | grep "^/dev/$dev" | awk '{print $1}' \
			> ${cache}/sdcard.part
		partnb=$(cat ${cache}/sdcard.part | wc -l)
		if [ "$partnb" != 3 ]; then
			error "SliTaz RPi needs 3 partitions on the sdcard" 
			newline && exit 1
		fi
		
		# Mount sdcard
		if mount | grep -q "^/dev/$dev[1-3]"; then
			debug "Unmounting: /dev/$dev"
			umount_sd
		fi
		echo -n "Mounting: /dev/$dev partitions"
		mkdir -p ${rpiboot} ${rpiroot}
		mount /dev/${dev}1 ${rpiboot} || exit 1
		mount /dev/${dev}3 ${rpiroot} || exit 1
		status
		echo -n "Cleaning: filesystem directories"
		for dir in bin dev etc lib media mnt proc sbin sys tmp usr var run
		do
			rm -rf ${rpiroot}/${dir}
		done; status
		echo -n "Installing: boot files"
		cp -rf ${boot}/* ${rpiboot}; status
		echo -n "Installing: rootfs files"
		cp -a ${rootfs}/* ${rpiroot}; status
		
		# Unmount
		echo -n "Unmounting: RPi sdcard"
		umount_sd; status
		
		rm -f ${cache}/sdcard.part
		separator
		echo "Insert the SD card into your Raspberry Pi and boot!"
		newline ;;

	gen)
		# Separate boot files since the Raspberry Pi boots off a FAT32 /boot 
		# partition on the sdcard.
		: ${flavor=rpi-base}
		
		# Use the rootfs generated by sat
		if [ ! -x "/usr/bin/sat" ]; then
			error "Sat is not installed" && exit 1
		fi
		check_root
		
		# We may want to simply regenerate the RPi distro
		if [ ! "$nosat" ]; then
			sat gen --work="$work" --flavor="$flavor" \
				--noinit --nolinux || exit 1
		else
			newline
		fi
		
		colorize 35 "SliTaz Raspberry Pi distro"
		separator
		mkdir -p ${boot}
		
		# Custom RPi rootfs: make sure all files belong to root
		if [ -d "$rpi/rootfs" ]; then
			size=$(du -sh $rpi/rootfs | awk '{print $1}')
			echo -n "Copying custom RPi rootfs: $size"
			tmp=$distro/tmp-$$
			mkdir -p $tmp
			cp -r $rpi/rootfs/* $tmp
			chown -R root.root $tmp
			cp -a $tmp/* ${rootfs} && rm -rf $tmp
			mv -f ${rootfs}/boot/* ${boot}
			status
		fi
		
		# TazBerry, Piboot, Pileds, ...
		for tool in tazberry piboot pileds raspicomm piface pitft-setup \
			pibrella piborg/piborg
		do
			echo -n "Copying utility: $tool"
			cp -f ${rpi}/${tool} ${rootfs}/usr/sbin
			status
		done
		
		# CGI Plugins
		echo -n "Copying CGI/adm plugins..."
		cp -a ${rpi}/cgi-adm/* ${rootfs}/var/www/adm
		status
		
		# Kernel at last
		. $cache/linux-*-arm/receipt
		kvers="$VERSION"
		kpkg="$rootfs/var/lib/tazpkg/installed/linux"
		fs="$cache/linux-$kvers-arm/fs"
		ksize=$(du -sh $fs | awk '{print $1}')
		if [ -d "$fs" ]; then
			echo -n "Copying: kernel $kvers ($ksize)"
			rm -rf ${rootfs}/lib/modules
			cp -rf ${fs}/lib/* ${rootfs}/lib
			cp -f  ${fs}/boot/* ${boot}
			mkdir -p ${kpkg}
			cd ${cache}/linux-${kvers}-arm
			cp -f files.list md5sum receipt ${kpkg}
			status
		else
			echo "SliTaz RPi Kernel: not used"
		fi
		
		separator
		echo -n "Boot: $(du -sh $boot | awk '{print $1}') "
		echo "- Rootfs: $(du -sh $rootfs | awk '{print $1}')" 
		newline ;;
	
	cook-linux)
		# Native SliTaz Toolchain and cross toolchain must be installed
		check_root
		install="$cache/linux-install"
		if [ ! -d "/cross/$arch" ]; then
			error "Missing cross toolchain in: /cross/$arch" && exit 1
		fi
		
		# Kernel source and --clean
		mkdir -p ${rpi_git} && cd ${rpi_git}
		[ -d "$kernel" ] || git clone --depth 1 ${rpi_git_url}linux.git
		[ "$clean" ] && rm -rf ${install}
		
		# FBtft drivers for small touchscreens such PiTFT, PiScreen
		if [ "$fbtft" ] && [ ! -d "${kernel}/drivers/video/fbtft" ]; then
			cd ${kernel}/drivers/video
			#git clone git://github.com/notro/fbtft.git
			git clone https://github.com/adafruit/adafruit-rpi-fbtft
			mv adafruit-rpi-fbtft fbtft
			cd ${kernel}
			echo 'source "drivers/video/fbtft/Kconfig"' >> drivers/video/Kconfig
			echo 'obj-y += fbtft/' >> drivers/video/Makefile
			cd ${rpi_git}
		fi
		
		# Compile
		if [ ! -d "$install" ]; then
			cd ${kernel}
			export PATH=$PATH:/cross/${arch}/tools/bin
			export HOST_SYSTEM=${arch}-slitaz-linux-gnueabi
			make mrproper &&
			make ARCH=arm bcmrpi_defconfig
			if [ ! "$nopatch" ]; then
				echo "Patching SliTaz RPi Linux .config"
				patch -p0 -i ${data}/linux-rpi.patch || exit 1
			fi
			[ "$gconfig" ] && make ARCH=arm gconfig
			make ARCH=arm CROSS_COMPILE=${HOST_SYSTEM}- zImage &&
			make ARCH=arm CROSS_COMPILE=${HOST_SYSTEM}- modules &&
			make ARCH=arm CROSS_COMPILE=${HOST_SYSTEM}- \
				INSTALL_MOD_PATH=${install} modules_install || exit 1
			mkdir -p ${install}/boot
			cp -a arch/arm/boot/zImage ${install}/boot/kernel.img
		fi
		
		# Kernel version
		kvers=$(ls ${install}/lib/modules)
		kvers=${kvers%-tazberry+}+
		
		# Compress modules
		#cd ${install}/lib/modules/*/kernel || exit 1
		#mods=$(find . -name "*.ko$" | wc -l)
		#newline
		#echo "Compressing kernel modules: $mods"
		#find . -name "*.ko$" -exec xz '{}' \; 2> /dev/null
		
		# Rebuild modules.dep
		cd ${install}
		depmod -b . ${kvers%+}-tazberry+
		
		# Kernel
		pkg="linux"
		[ "$fbtft" ] && pkg="linux-fbtft"
		fs="$cache/$pkg-$kvers-arm/fs"
		echo "Kernel version: $kvers"
		if [ -d "$install" ]; then
			rm -rf ${cache}/${pkg}-${kvers}-arm
			mkdir -p ${fs}
			cp -a ${install}/* ${fs}
			rm -f ${fs}/lib/modules/*/build \
				${fs}/lib/modules/*/source
		else
			echo "Kernel is not built..." && exit 1
		fi
		
		# Pack .tazpkg
		cd ${cache}
		echo "Creating package: receipt"
		cat > ${pkg}-${kvers}-arm/receipt << EOT
# SliTaz package receipt

PACKAGE="${pkg}"
VERSION="$kvers"
SHORT_DESC="SliTaz GNU/Linux Kernel for the Raspberry Pi."
MAINTAINER="pankso@slitaz.org"
WEB_SITE="http://www.kernel.org"
HOST_ARCH="arm"

EOT
		tazpkg pack ${pkg}-${kvers}-arm ;;
	
	clone-fw)
		clone_fw ;;
		
	get-linux)
		# Precook RPi kernel
		check_root
		mkdir -p ${cache}
		
		# Last version
		rm -f ${cache}/linux-version.txt
		if busybox wget -q -s ${rpi_mirror}/packages/last-linux.txt; then
			echo -n "Fetching latest Kernel string..."
			wget -q ${rpi_mirror}/packages/last-linux.txt \
				-O ${cache}/linux-version.txt || exit 1
			status
		else
			echo "Mirror is unreachable" && exit 1
		fi
		kvers=$(cat $cache/linux-version.txt)
		[ "$up" ] && rm -rf ${cache}/linux-${kvers}*
		echo "Kernel version: $kvers"
		
		# Download
		if [ ! -f "$cache/linux-$kvers.tazpkg" ]; then
			echo -n "Fetching latest Linux package..."
			wget -q ${rpi_mirror}/packages/linux-${kvers}-arm.tazpkg \
				-O ${cache}/linux-${kvers}-arm.tazpkg; status
		fi
		
		# Extract
		if [ ! -d "$cache/linux-$kvers" ]; then
			cd ${cache} && tazpkg extract linux-${kvers}-arm.tazpkg
		fi 
		rm -f ${cache}/linux-version.txt ;;
		
	get-prebuilt)
		# --> in cross ??
		: ${arch=arm}
		name="slitaz-$arch-toolchain"
		vers="20140304"
		tarball="$name-$vers.tar.bz2"
		url="http://mirror.slitaz.org/packages/cross/"
		mkdir -p /cross
		cd /cross
		if [ ! -f "$tarball" ]; then
			if busybox wget -qs ${url%/}/${tarball}; then
				busybox wget ${url%/}/${tarball}
			else
				echo "Toolchain URL is unreachable" && exit 1
			fi 
		fi
		if [ ! -d "${name}-${vers}" ]; then
			echo "Extracting: $tarball"
			tar xjf ${tarball}
		fi
		echo "Copying: ${name}-${vers}/${arch}"
		mkdir -p ${arch}
		cp -a ${name}-${vers}/${arch}/* ${arch} 
		echo "Tools path: /cross/${arch}/tools/bin" ;;
		
	release)
		# Used to release official SliTaz RPi images
		cd ${distro} || exit 1
		if [ ! "$flavor" ]; then
			. $distro/rootfs/etc/slitaz/flavor.conf || exit 1
			flavor="$FLAVOR"
		fi
		dname="slitaz-$flavor-$(date +%Y%m%d)"
		dsize=$(du -sh $distro | awk '{print $1}' | cut -d "." -f 1)
		rm -rf ${dname} && mkdir ${dname}
		cp -a boot rootfs ${dname}
		echo "Copying: SliTaz release files"
		cp ${rpi}/release/* ${dname}
		echo "Creating: ${dname}.tar.bz2"
		tar -cjf ${dname}.tar.bz2 ${dname}
		echo "Creating: ${dname}.md5"
		md5sum ${dname}.tar.bz2 > ${dname}.md5
		rm -rf ${dname} ;;
	
	clean)
		echo "Cleaning: $rpi"
		rm -rf ${cache} ${rpi_git} ;;
		
	*|*help) usage ;;
esac
exit 0
