#!/bin/sh -efu

# Copyright 2013 Intel Corporation
# Author: Artem Bityutskiy
# License: GPLv2

#
# This is a simple script which installs the extlinux bootloader and creates
# a valid extlinux.conf configuration file. This script requires a number of
# environment variables to be defined. Namely:
#
# 1. INSTALLERFW_PART_COUNT - count of partitions
# 2. INSTALLERFW_PARTX_MOUNTPOINT - mount point of partition number X
#    (0 <= X < $INSTALLERFW_PART_COUNT)
# 3. INSTALLERFW_PARTX_PARTUUID - GPT GUID (AKA PARTUUID) of partition number X
# 4. INSTALLERFW_MOUNT_PREFIX - where the target partitions are mounted (the
#    "root" directory of the file-system we install extlinux to)
# 5. INSTALLERFW_PARTX_DISK_DEVNODE_NOW - the disk device node which contains
#    partition number X
# 6. INSTALLERFW_PARTX_DEVNODE_NOW - device node for partition number X

PROG="setup-mbr-ivi"

# Print debugging information
print_debug_info()
{
	printf "%s\n" "INSTALLERFW_MOUNT_PREFIX=$INSTALLERFW_MOUNT_PREFIX"
	printf "%s\n" "INSTALLERFW_PART_COUNT=$INSTALLERFW_PART_COUNT"
	printf "%s\n" "INSTALLERFW_PART0_FSOPTS=$INSTALLERFW_PART0_FSOPTS"
	printf "%s\n" "INSTALLERFW_PART0_FSTYPE=$INSTALLERFW_PART0_FSTYPE"
	printf "%s\n" "INSTALLERFW_PART0_UUID=$INSTALLERFW_PART0_UUID"
	printf "%s\n" "INSTALLERFW_PART0_MOUNTPOINT=$INSTALLERFW_PART0_MOUNTPOINT"
	printf "%s\n" "INSTALLERFW_PART0_ALIGN=$INSTALLERFW_PART0_ALIGN"
	printf "%s\n" "INSTALLERFW_PART0_BOOTFLAG=$INSTALLERFW_PART0_BOOTFLAG"
	printf "%s\n" "INSTALLERFW_PART0_SIZE=$INSTALLERFW_PART0_SIZE"
	printf "%s\n" "INSTALLERFW_PART0_TYPE_ID=$INSTALLERFW_PART0_TYPE_ID"
	printf "%s\n" "INSTALLERFW_PART0_LABEL=$INSTALLERFW_PART0_LABEL"
	printf "%s\n" "INSTALLERFW_PART0_DEVNODE=$INSTALLERFW_PART0_DEVNODE"
	printf "%s\n" "INSTALLERFW_PART0_DISK_DEVNODE=$INSTALLERFW_PART0_DISK_DEVNODE"
	printf "%s\n" "INSTALLERFW_PART0_DEVNODE_NOW=$INSTALLERFW_PART0_DEVNODE_NOW"
	printf "%s\n" "INSTALLERFW_PART0_DISK_DEVNODE_NOW=$INSTALLERFW_PART0_DISK_DEVNODE_NOW"
	printf "%s\n" "INSTALLERFW_PART0_PARTUUID=$INSTALLERFW_PART0_PARTUUID"
	printf "%s\n" "INSTALLERFW_PART1_FSOPTS=$INSTALLERFW_PART1_FSOPTS"
	printf "%s\n" "INSTALLERFW_PART1_FSTYPE=$INSTALLERFW_PART1_FSTYPE"
	printf "%s\n" "INSTALLERFW_PART1_UUID=$INSTALLERFW_PART1_UUID"
	printf "%s\n" "INSTALLERFW_PART1_MOUNTPOINT=$INSTALLERFW_PART1_MOUNTPOINT"
	printf "%s\n" "INSTALLERFW_PART1_ALIGN=$INSTALLERFW_PART1_ALIGN"
	printf "%s\n" "INSTALLERFW_PART1_BOOTFLAG=$INSTALLERFW_PART1_BOOTFLAG"
	printf "%s\n" "INSTALLERFW_PART1_SIZE=$INSTALLERFW_PART1_SIZE"
	printf "%s\n" "INSTALLERFW_PART1_TYPE_ID=$INSTALLERFW_PART1_TYPE_ID"
	printf "%s\n" "INSTALLERFW_PART1_LABEL=$INSTALLERFW_PART1_LABEL"
	printf "%s\n" "INSTALLERFW_PART1_DEVNODE=$INSTALLERFW_PART1_DEVNODE"
	printf "%s\n" "INSTALLERFW_PART1_DISK_DEVNODE=$INSTALLERFW_PART1_DISK_DEVNODE"
	printf "%s\n" "INSTALLERFW_PART1_DEVNODE_NOW=$INSTALLERFW_PART1_DEVNODE_NOW"
	printf "%s\n" "INSTALLERFW_PART1_DISK_DEVNODE_NOW=$INSTALLERFW_PART1_DISK_DEVNODE_NOW"
	printf "%s\n" "INSTALLERFW_PART1_PARTUUID=$INSTALLERFW_PART1_PARTUUID"
	printf "%s\n" "INSTALLERFW_DISTRO_NAME=$INSTALLERFW_DISTRO_NAME"
	printf "%s\n" "INSTALLERFW_KERNEL_OPTS=$INSTALLERFW_KERNEL_OPTS"
	printf "%s\n" "INSTALLERFW_INSTALLER_NAME=$INSTALLERFW_INSTALLER_NAME"
	printf "%s\n" "INSTALLERFW_PTABLE_FORMAT=$INSTALLERFW_PTABLE_FORMAT"

	cat /proc/mounts
	ls -l /dev/
	ls -l /dev/mapper
}

# This is a helper function which prints an error message and exits
fatal()
{
	printf "%s\n" "$PROG: error: $1" 1>&2
	exit 1
}

#print_debug_info

# Make sure the installer framework variables are defined
[ "${INSTALLERFW_PART_COUNT:+x}" == "x" ] ||
       fatal "installer framework environment variables not found"

# Find the required root and boot parition parameters
pnum=0
root_partuuid=
boot_mountpoint=

while [ "$pnum" -lt "$INSTALLERFW_PART_COUNT" ]; do
	mountpoint="INSTALLERFW_PART${pnum}_MOUNTPOINT"
	mountpoint="$(eval printf "%s" '$'$mountpoint)"

	# Find out all the required data for the root and boot partition
	if [ "$mountpoint" == "/" ]; then
		root_partuuid="INSTALLERFW_PART${pnum}_PARTUUID"
		root_partuuid="$(eval printf "%s" '$'$root_partuuid)"
	# The boot parition has to be at "/boot"
	elif [ "$mountpoint" == "/boot" ]; then
		boot_mountpoint="$mountpoint"

		boot_devnode="INSTALLERFW_PART${pnum}_DEVNODE_NOW"
		boot_devnode="$(eval printf "%s" '$'$boot_devnode)"

		mbr_devnode="INSTALLERFW_PART${pnum}_DISK_DEVNODE_NOW"
		mbr_devnode="$(eval printf "%s" '$'$mbr_devnode)"
	fi

	pnum="$((pnum+1))"
done

bootdir="$INSTALLERFW_MOUNT_PREFIX/$boot_mountpoint"
extlinuxdir="$bootdir/extlinux"

# Install extlinux
extlinux_binary="$INSTALLERFW_MOUNT_PREFIX/sbin/extlinux"
"$extlinux_binary" --device "$boot_devnode" -i "$extlinuxdir" || \
	fatal "cannot install extlinux to $extlinuxdir"

# Install the MBR part of extlinux
mbr_bin="$INSTALLERFW_MOUNT_PREFIX/usr/share/syslinux/gptmbr.bin"
dd if="$mbr_bin" of="$mbr_devnode" || \
	fatal "cannot install MBR: dd if=$mbr_bin of=$mbr_devnode"

# Make the newest kernel to be the one we boot
newest_kernel="$(ls -1 "$bootdir" | grep "^vmlinuz-" | sort -r | head -n1)"
ln -sf "$newest_kernel" "$bootdir/vmlinuz" || \
	fatal "cannot create symlink: $bootdir/vmlinuz --> $newest_kernel"

# Create the extlinux.conf file
cat > "$extlinuxdir/extlinux.conf" <<EOF
prompt 0
timeout 0
default tizen
label tizen
	linux ../vmlinuz
	append $INSTALLERFW_KERNEL_OPTS root=PARTUUID=$root_partuuid
EOF
