#!/bin/sh

# Usage: makehdimage [image path/target dir]
#
# This script will compile all files needed to create a bootable Haiku image,
# create such an image, and copy the files to the correct location.
#
# You need the Userland FS Server package from Ingo Weinhold to successfully
# create the image, and you also need to have the UserlandFSServer running
# in the background when you start the script (as long as you don't use
# the target directory mode). The package is available here:
#   http://tfs.cs.tu-berlin.de/~bonefish/download/userlandfs.zip
#
# If you don't specify the image, $sourceDir/haiku.image will be used. In
# the current default configuration, you have to start this script in the
# "current" directory of the Haiku tree. A 40 MB image will be created there.
#
# If you specify a target directory, no image is going to be created at
# all, and also the Userland FS Server is not needed.
#
# You may want to change it to suit your needs. Have fun!


# path of the checked out Haiku sources
sourceDir=.
alreadyMounted=
targetDir=/haiku

# disk image path, size in MB
if [ -d "$1" ]; then
	alreadyMounted=true
	targetDir=$1
elif [ "$1" == "" ]; then
	imagePath=$sourceDir/haiku.image
else
	imagePath=$1
fi
imageSize=40

# ufs_mount path
ufsMount=ufs_mount

# build everything needed
previousDir=`pwd`
cd $sourceDir
sourceDir=`pwd`
	# we accept relative source directories as well

if [ $alreadyMounted ]; then
	echo "Building binaries and copy them to $targetDir"
else
	echo "Building $imageSize MB image at $imagePath..."
fi

# paths of helper commands
rc=$sourceDir/distro/x86.R1/beos/bin/rc
resattr=$sourceDir/objects/x86.R1/tools/resattr/resattr

export RUN_WITHOUT_APP_SERVER=1
export TARGET_PLATFORM=haiku

BEOS_BIN="touch sync ln listarea listattr listsem listport \
	true false ls df mount unmount cp mv ps sh mkdir sleep \
	grep cat less clockconfig du rm date find locate xargs \
	isvolume shutdown safemode sysinfo kill diff cmp more \
	renice rmattr addattr listdev pwd chmod chown chgrp dd \
	tee md5sum catattr query lsindex mkindex roster listimage \
	quit open translate setvolume waitfor uname iroster keymap \
	strace rmdir error"

BEOS_SYSTEM_LIB="libbe.so libstdc++.r4.so libnet.so libmedia.so \
	libtranslation.so libbind.so libnetapi.so libsocket.so"

BEOS_SYSTEM_SERVERS="registrar syslog_daemon media_server media_addon_server input_server"

BEOS_ADD_ONS_TRANSLATORS="STXTTranslator RTF-Translator"
BEOS_ADD_ONS_MEDIA="mixer.media_addon legacy.media_addon multi_audio.media_addon"
BEOS_ADD_ONS_INPUT_DEVICES="<input>keyboard"

echo "Building executables and libraries..."

jam -j$(sysinfo -cpu | head -c 2) -q rc resattr kernel boot_loader config_manager \
	pci isa ide scsi ide_isa bfs blkman fast_log ide_adapter locked_pool \
	scsi_periph intel keyboard scsi_dsk scsi_cd \
	rld.so kernel_fortune consoled \
	$BEOS_BIN $BEOS_SYSTEM_LIB $BEOS_SYSTEM_SERVERS \
	$BEOS_ADD_ONS_TRANSLATORS $BEOS_ADD_ONS_MEDIA $BEOS_ADD_ONS_INPUT_DEVICES\
	libnet.so dprintf null zero random ps2_hid \<driver\>tty console \
	\<driver\>config vga_text timezone_files keymap_files \
	|| { echo "*** Build failed!" 1>&2 ; exit 1; }

# create the image and the directory structure

if [ ! $alreadyMounted ]; then
	echo
	echo "Creating image..."
	dd if=/dev/zero of=$imagePath bs=1M count=$imageSize
	mkbfs $imagePath Haiku >/dev/null
	mkdir -p $targetDir
	sync
	$ufsMount obfs $imagePath $targetDir || exit 1
fi

cd $targetDir

echo
echo "Creating directory structure..."

mkdir -p beos/bin
mkdir -p beos/etc
mkdir -p beos/system/add-ons/kernel/boot
mkdir -p beos/system/add-ons/kernel/bus_managers
mkdir -p beos/system/add-ons/kernel/busses/ide
mkdir -p beos/system/add-ons/kernel/drivers/bin
mkdir -p beos/system/add-ons/kernel/drivers/dev/disk/scsi
mkdir -p beos/system/add-ons/kernel/drivers/dev/input
mkdir -p beos/system/add-ons/kernel/drivers/dev/misc
mkdir -p beos/system/add-ons/kernel/file_systems
mkdir -p beos/system/add-ons/kernel/console
mkdir -p beos/system/add-ons/kernel/generic
mkdir -p beos/system/add-ons/kernel/partitioning_systems
mkdir -p beos/system/add-ons/Translators
mkdir -p beos/system/add-ons/media
mkdir -p beos/system/add-ons/input_server/devices
mkdir -p beos/system/boot
mkdir -p beos/system/lib
mkdir -p beos/system/servers
mkdir -p home/config
mkdir -p home/config/settings/kernel/drivers
mkdir -p var/tmp

# modules

echo "Installing kernel modules..."

cd $sourceDir/distro/x86.R1/beos/system/add-ons/kernel

for f in bus_managers/isa bus_managers/ide bus_managers/scsi busses/ide/ide_isa \
		file_systems/bfs generic/blkman generic/fast_log generic/ide_adapter \
		generic/locked_pool generic/scsi_periph partitioning_systems/intel \
		console/vga_text; do
	cp $f $targetDir/beos/system/add-ons/kernel/$f
done

for f in drivers/dev/disk/scsi/scsi_dsk drivers/dev/disk/scsi/scsi_cd; do
	name=drivers/bin/$(basename $f)
	cp $name $targetDir/beos/system/add-ons/kernel/$name
done

cd $sourceDir/objects/x86.R1/add-ons/kernel

for f in bus_managers/config_manager bus_managers/pci; do
	name=$(basename $f)
	cp $f/$name $targetDir/beos/system/add-ons/kernel/$f
done


# drivers
for f in drivers/arch/x86/keyboard/keyboard; do
	cp $f $targetDir/beos/system/add-ons/kernel/drivers/bin
done

cd $sourceDir/distro/x86.R1/beos/system/add-ons/kernel/drivers/bin
for f in ps2_hid; do
	cp $f $targetDir/beos/system/add-ons/kernel/drivers/bin
done

cd $sourceDir/distro/x86.R1/beos/system/add-ons/kernel/drivers/dev
for f in misc/config console tty random dprintf null zero; do
	cp $f $targetDir/beos/system/add-ons/kernel/drivers/bin
done


# kernel
echo "Installing kernel..."
cp $sourceDir/objects/x86.R1/kernel/kernel $targetDir/beos/system/kernel_x86


# libs
echo "Installing libraries..."
cd $sourceDir/distro/x86.R1/beos/system/lib
cp $BEOS_SYSTEM_LIB $targetDir/beos/system/lib/
cd $sourceDir/objects/x86.R1/kernel/
cp rld.so libroot.so $targetDir/beos/system/lib/


# servers
echo "Installing servers..."
cd $sourceDir/distro/x86.R1/beos/system/servers
copyattr -d $BEOS_SYSTEM_SERVERS $targetDir/beos/system/servers/


# apps
echo "Installing apps..."

cd $sourceDir/objects/x86.R1/kernel
for f in fortune; do
	cp kernel_$f $targetDir/beos/bin/$f
done

cd $sourceDir/distro/x86.R1/beos/bin
cp ../apps/consoled $BEOS_BIN $targetDir/beos/bin/
cd $targetDir/beos/bin


# scripts and data files
echo "Installing scripts and data files..."
cd $sourceDir
cp data/system/boot/Bootscript data/system/boot/SetupEnvironment $targetDir/beos/system/boot/
cp data/etc/profile data/etc/termcap $targetDir/beos/etc/
cp src/kernel/apps/fortune/fortunes $targetDir/beos/etc/
cp -R distro/x86.R1/beos/etc $targetDir/beos/
cp data/settings/kernel/drivers/kernel $targetDir/home/config/settings/kernel/drivers/
ln -sf /boot/beos/etc/timezones/Europe/Paris $targetDir/home/config/settings/timezone
cp distro/x86.R1/beos/etc/Keymap/US-International $targetDir/home/config/settings/Key_map


# boot loader
echo "Installing boot loader..."
cd $targetDir/beos/system
objcopy -O binary $sourceDir/objects/x86.R1/kernel/boot_loader zbeos


# boot module links
echo "Creating boot module links..."
cd $targetDir/beos/system/add-ons/kernel/boot
for f in bus_managers/config_manager bus_managers/pci bus_managers/isa bus_managers/ide bus_managers/scsi busses/ide/ide_isa file_systems/bfs generic/blkman generic/fast_log generic/ide_adapter generic/locked_pool generic/scsi_periph partitioning_systems/intel; do
	ln -fs /boot/beos/system/add-ons/kernel/$f $(basename $f)
done
for f in drivers/dev/disk/scsi/scsi_dsk drivers/dev/disk/scsi/scsi_cd; do
	ln -fs /boot/beos/system/add-ons/kernel/drivers/bin/$(basename $f) .
done


# driver links
echo "Creating driver links..."
cd $targetDir/beos/system/add-ons/kernel
for f in drivers/dev/dprintf drivers/dev/keyboard drivers/dev/null \
		drivers/dev/misc/config drivers/dev/tty drivers/dev/zero \
		drivers/dev/disk/scsi/scsi_dsk drivers/dev/disk/scsi/scsi_cd \
		drivers/dev/misc/config drivers/dev/input/ps2_hid drivers/dev/console; do
	relName=$(echo $f | sed -e s@drivers/dev/@@)
	linkName=bin/$(basename $f)
	while [ $relName != . ]; do
		relName=$(dirname $relName)
		linkName=../$linkName
	done
	(cd $(dirname $f); ln -fs $linkName .)
done


# add-ons
echo "Copying add-ons..."

cd $sourceDir/distro/x86.R1/beos/system/add-ons/Translators
for f in $BEOS_ADD_ONS_TRANSLATORS; do
	copyattr -d $f $targetDir/beos/system/add-ons/Translators/
done

cd $sourceDir/distro/x86.R1/beos/system/add-ons/media
for f in $BEOS_ADD_ONS_MEDIA; do
	copyattr -d $f $targetDir/beos/system/add-ons/media/
done

cd $sourceDir/distro/x86.R1/beos/system/add-ons/input_server/devices/
for f in keyboard; do
	copyattr -d $f $targetDir/beos/system/add-ons/input_server/devices/
done


# install MIME database
mimeDBSource=$sourceDir/src/data/beos_mime
mimeDBDest=$targetDir/home/config/settings/beos_mime

echo "Deleting old MIME database..."

rm -rf $mimeDBDest
mkdir -p $mimeDBDest

echo "Installing MIME database..."

for inSuperFile in $mimeDBSource/*.super; do
	superType=$(basename $inSuperFile .super)
	outSuperDir=$mimeDBDest/$superType

	# create super type dir
	mkdir -p $outSuperDir

	# compile rdef to rsrc file and the rsrc file to attributes
	tmpFile=/tmp/mimedb$$.rsrc
	$rc -o $tmpFile $inSuperFile
	$resattr -O -o $outSuperDir $tmpFile
	rm -f $tmpFile

	# iterate through the sub types
	for inSubFile in $mimeDBSource/$superType/*; do
		# check, if the type exists
		if test -f $inSubFile && grep META:TYPE $inSubFile &> /dev/null; then
			subType=$(basename $inSubFile)
			outSubFile=$outSuperDir/$subType

			# compile rdef to rsrc file and the rsrc file to attributes
			tmpFile=/tmp/mimedb$$.rsrc
			$rc -o $tmpFile $inSubFile
			$resattr -O -o $outSubFile $tmpFile
			rm -f $tmpFile
		fi
	done
done


cd $previousDir
sync

if [ ! $alreadyMounted ]; then
	echo Unmounting ...
	sleep 1
	unmount $targetDir
	sleep 1
	sync
	rmdir $targetDir
	sync
fi

if [ $archive ]; then
	zip haiku.zip $imagePath
fi