#!/bin/sh
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

set -e
set -x

enable_eatmydata_override() {
    chroot $rootdir apt-get install --no-install-recommends -y eatmydata
    if [ -x $rootdir/usr/bin/eatmydata ] && \
        [ ! -f $rootdir/etc/apt/apt.conf.d/95debian-edu-install-dpkg-eatmydata ]; then
        echo "info: Adding apt config to call dpkg via eatmydata"
        printf "#!/bin/sh\nexec eatmydata dpkg \"\$@\"\n" \
            > $rootdir/var/tmp/dpkg-eatmydata
        chmod 755 $rootdir/var/tmp/dpkg-eatmydata
        cat > $rootdir/etc/apt/apt.conf.d/95debian-edu-install-dpkg-eatmydata <<EOF
Dir::Bin::dpkg "/var/tmp/dpkg-eatmydata";
EOF
    else
        echo "error: unable to find /usr/bin/eatmydata after installing the eatmydata package"
    fi
}

disable_eatmydata_override() {
    for override in \
        /etc/apt/apt.conf.d/95debian-edu-install-dpkg-eatmydata \
        /var/tmp/dpkg-eatmydata ; do
        echo "info: Removing apt config to call dpkg via eatmydata"
        if [ -f $rootdir$override ] ; then
            rm -f $rootdir$override
        else
            echo "warning: missing $rootdir$override"
        fi
    done
    sync # Flush file buffers before continuing
}

set_apt_sources() {
    NEW_MIRROR="$1"
    COMPONENTS="main"
    if [ "$ENABLE_NONFREE" = "yes" ]
    then
	    COMPONENTS="main contrib non-free"
    fi

    cat <<EOF > etc/apt/sources.list
deb $NEW_MIRROR $SUITE $COMPONENTS
deb-src $NEW_MIRROR $SUITE $COMPONENTS
EOF

    if [ "$SUITE" != "unstable" ] && [ "$SUITE" != "sid" ]; then
	cat <<EOF >> etc/apt/sources.list

deb http://security.debian.org/ $SUITE/updates $COMPONENTS
deb-src http://security.debian.org/ $SUITE/updates $COMPONENTS

deb $NEW_MIRROR $SUITE-updates $COMPONENTS
deb-src $NEW_MIRROR $SUITE-updates $COMPONENTS
EOF
    fi
}

atheros_wifi() {
    # Fetch and install free software firmware for a couple USB Atheros
    # Wi-Fi devices from Trisqel repository.
    firmware_filename="open-ath9k-htc-firmware_1.3-1_all.deb"
    firmware_hash='5fea58ffefdf0ef15b504db7fbe3bc078c03e0d927bba64085e4b6f2546102f5'

    firmware_url="http://us.archive.trisquel.info/trisquel/pool/main/o/open-ath9k-htc-firmware/$firmware_filename"
    firmware_tempfile="/tmp/$firmware_filename"
    wget "$firmware_url" -O "$rootdir$firmware_tempfile"
    downloaded_firmware_hash=$(sha256sum "$rootdir$firmware_tempfile" | awk -F ' ' '{print $1}')
    if [ "$downloaded_firmware_hash" = "$firmware_hash" ]; then
        chroot "$rootdir" dpkg -i "$firmware_tempfile"
        return
    fi
    echo 'Atheros wifi firmware download verification failed'
    fuser -mvk $rootdir/. || true
    exit 1
}

mount_file_systems() {
    mount /dev     -t devfs  -o bind "$rootdir/dev"
    mount /dev/pts -t devpts -o bind "$rootdir/dev/pts"
    mount /proc    -t proc   -o bind "$rootdir/proc"
    mount /sys     -t sys    -o bind "$rootdir/sys"
}

unmount_file_systems() {
    # XXX: Should be doing strict checks but /dev/pts seems to be
    # prematurely unmounted for some reason perhaps due to issues in
    # parallel builds.  Workaround that.
    umount "$rootdir/dev/pts" || true
    umount "$rootdir/dev" || true
    umount "$rootdir/proc" || true
    umount "$rootdir/sys" || true

    case "$MACHINE" in
	raspberry2)
	    umount "$rootdir/boot/firmware" || true
	    ;;
    esac
}

# Set to true/false to control if eatmydata is used during build
use_eatmydata=true

rootdir="$1"
image="$(cd "$(dirname "$2")"; pwd)/$(basename "$2")"

# Create vfat /boot/firmware partition for devices that need it.
case "$MACHINE" in
    raspberry2)
	umount "$rootdir/boot"
	umount "$rootdir"
	kpartx -dvs "$image"

	parted -s "$image" mkpart primary 0% 60MiB

	# Reorder partitions by start offset
	sfdisk --reorder "$image"

	device=/dev/mapper/$(kpartx -avs "$image" \
				    | awk '/^add map / {print $3; exit}')
	mkfs -t vfat "$device"
	parted -s "$image" set 1 lba on

	mount -t btrfs "${device%?}3" "$rootdir"
	mount -t ext2 "${device%?}2" "$rootdir"/boot
	mkdir "$rootdir/boot/firmware"
	mount -t vfat "$device" "$rootdir/boot/firmware"

	fs_uuid=$(blkid -c /dev/null -o value -s UUID "$device")
	echo "UUID=$fs_uuid /boot/firmware vfat errors=remount-ro 0 3" \
	     >>"$rootdir"/etc/fstab
	;;
esac

mount_file_systems
trap unmount_file_systems EXIT

cd "$rootdir"

echo info: building $MACHINE

export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true
export LC_ALL=C LANGUAGE=C LANG=C

# Override libpam-tmpdir setting during build, as the directories
# are not created yet.
export TMP=/tmp/ TMPDIR=/tmp/

username=fbx
echo "info: creating initial user $username with disabled password!"
chroot $rootdir adduser --gecos $username --disabled-password $username
chroot $rootdir adduser $username sudo

case "$MACHINE" in
    virtualbox)
        # hide irrelevant console keyboard messages.
        echo "echo \"4 4 1 7\" > /proc/sys/kernel/printk" \
            >> /etc/init.d/rc.local
        ;;
esac

set_apt_sources $BUILD_MIRROR
chroot $rootdir apt-get update

cat > $rootdir/usr/sbin/policy-rc.d <<EOF
#!/bin/sh
exit 101
EOF
chmod a+rx $rootdir/usr/sbin/policy-rc.d

if $use_eatmydata ; then
    enable_eatmydata_override
fi

if [ -n "$CUSTOM_PLINTH" ]; then
    cp "$CUSTOM_PLINTH" "$rootdir"/tmp
    chroot "$rootdir" apt-get install -y gdebi-core
    chroot "$rootdir" gdebi -n /tmp/"$(basename $CUSTOM_PLINTH)"
fi

if [ -n "$CUSTOM_SETUP" ]; then
    cp "$CUSTOM_SETUP" "$rootdir"/tmp
    chroot "$rootdir" apt-get install -y gdebi-core
    chroot "$rootdir" gdebi -n /tmp/"$(basename $CUSTOM_SETUP)"
else
    chroot "$rootdir" apt-get install -y freedombox-setup
fi

atheros_wifi

script_dir=$(cd "$(dirname "$0")" && pwd)
cp "$script_dir"/hardware-setup $rootdir/tmp
chroot $rootdir /tmp/hardware-setup 2>&1 | \
    tee $rootdir/var/log/hardware-setup.log

rm $rootdir/usr/sbin/policy-rc.d

chroot $rootdir /usr/lib/freedombox/setup 2>&1 | \
    tee $rootdir/var/log/freedombox-setup.log

# Remove SSH keys from the image, freedomxbox-setup does not do that
# anymore.
rm $rootdir/etc/ssh/ssh_host_* || true

# Move hostname to 127.0.1.1 line of /etc/hosts.
# TODO: Can this be changed in vmdebootstrap?
sed -i "s/127.0.0.1.*/127.0.0.1	localhost/" "$rootdir"/etc/hosts
if ! grep -q 127.0.1.1 "$rootdir"/etc/hosts ; then
    sed -i "/127.0.0.1.*/a \
127.0.1.1	freedombox" "$rootdir"/etc/hosts
fi

# copy u-boot to beginning of image
case "$MACHINE" in
    beaglebone)
        dd if=$rootdir/usr/lib/u-boot/am335x_boneblack/MLO of="$image" \
           count=1 seek=1 conv=notrunc bs=128k
        dd if=$rootdir/usr/lib/u-boot/am335x_boneblack/u-boot.img of="$image" \
           count=2 seek=1 conv=notrunc bs=384k
        ;;
    cubietruck)
        dd if=$rootdir/usr/lib/u-boot/Cubietruck/u-boot-sunxi-with-spl.bin of="$image" \
           seek=8 conv=notrunc bs=1k
        ;;
    a20-olinuxino-lime)
        dd if=$rootdir/usr/lib/u-boot/A20-OLinuXino-Lime/u-boot-sunxi-with-spl.bin \
           of="$image" seek=8 conv=notrunc bs=1k
        ;;
    a20-olinuxino-lime2)
        dd if=$rootdir/usr/lib/u-boot/A20-OLinuXino-Lime2/u-boot-sunxi-with-spl.bin \
           of="$image" seek=8 conv=notrunc bs=1k
        ;;
    a20-olinuxino-micro)
        dd if=$rootdir/usr/lib/u-boot/A20-OLinuXino_MICRO/u-boot-sunxi-with-spl.bin \
           of="$image" seek=8 conv=notrunc bs=1k
        ;;
    cubieboard2)
        dd if=$rootdir/usr/lib/u-boot/Cubieboard2/u-boot-sunxi-with-spl.bin of="$image" \
           seek=8 conv=notrunc bs=1k
        ;;
    pcduino3)
        dd if=$rootdir/usr/lib/u-boot/Linksprite_pcDuino3/u-boot-sunxi-with-spl.bin of="$image" \
           seek=8 conv=notrunc bs=1k
        ;;
esac

if $use_eatmydata ; then
    disable_eatmydata_override
fi

set_apt_sources $MIRROR
chroot $rootdir apt-get update

cd /
echo "info: killing leftover processes in chroot"
# 2014-11-04 this killed /usr/lib/erlang/erts-6.2/bin/epmd, see
# <URL: https://www.ejabberd.im/epmd?q=epmd > to learn more.
fuser -mvk $rootdir/. || true
