#!/bin/bash

set -e
set -u

usage() {
	echo "Usage: make-chroot.sh directory" >&2
	echo "The directory must not exist" >&2
	exit 1
}


if [ $# != 1 ] ; then
	usage
fi

thedir=$1

if [ -e "$thedir" ] ; then
	usage
fi

umountfs() {
    umount "$thedir/dev" || true
    umount "$thedir/sys" || true
    umount "$thedir/proc" || true
}

echo "The directory is $thedir"

trap umountfs EXIT

INCLUDE="pulseaudio,alsa-utils,sox,powertop,linux-image-amd64,ntfs-3g,cpufrequtils,mdadm"
INCLUDE="$INCLUDE,build-essential,dh-autoreconf,g++,ladspa-sdk"
INCLUDE="$INCLUDE,libasound2-dev,libbluetooth-dev,libdbus-1-dev"
INCLUDE="$INCLUDE,libsbc-dev,libspeexdsp-dev,libcap-dev,libudev-dev"

debootstrap --include="$INCLUDE" jessie "$thedir" http://http.debian.net/debian
ln -sf sbin/init "$thedir/init"

mount -t proc proc "$thedir/proc"
mount -t sysfs sysfs "$thedir/sys"
mount -t devtmpfs devtmpfs "$thedir/dev"

echo debian > "$thedir/etc/hostname"
echo "127.0.1.1 debian" >> "$thedir/etc/hosts"
echo 'GOVERNOR="powersave"' > "$thedir/etc/default/cpufrequtils"
chroot "$thedir" passwd -d root

(
set -e
set -u
ADHD_COMMIT="8011c4875739dfb86a9a26c12b82e29657ceb47c"
SNAPSHOT="http://snapshot.debian.org/archive/debian/20150925T153926Z/pool/main/"
cd "$thedir/root"

wget "$SNAPSHOT/d/dbus/libdbus-1-3_1.10.0-3_amd64.deb"
wget "$SNAPSHOT/d/dbus/libdbus-1-dev_1.10.0-3_amd64.deb"
wget "$SNAPSHOT/o/orc/liborc-0.4-0_0.4.24-1_amd64.deb"

for v in 5.0-13 6.0-5 7.0-1 ; do
    for p in pulseaudio pulseaudio-utils libpulse0 libpulsedsp ; do
        wget "$SNAPSHOT/p/pulseaudio/${p}_${v}_amd64.deb"
    done
done
sha1sum -c << "EOF"
3d95943b68ab32ef580f9ed30f54faf3ad07afab  libdbus-1-3_1.10.0-3_amd64.deb
2cb1510f309ea2296f5821bd78b92893d166b727  libdbus-1-dev_1.10.0-3_amd64.deb
c5646dd9176c2c0ec1e5a21c4cabd14419d01f66  liborc-0.4-0_0.4.24-1_amd64.deb
b72426dda82ecbbe8c42e20896bdf43fc3ddb905  libpulse0_5.0-13_amd64.deb
6b38642a9447edd3a39bdb00b40f60b3bcc7d151  libpulse0_6.0-5_amd64.deb
6810af98d50a3c3852b8385fcc3e592cc2d9ff29  libpulse0_7.0-1_amd64.deb
5e0b09cd169de457eced143690f3499747e99c4d  libpulsedsp_5.0-13_amd64.deb
91c9fadb85346f6c3260f008af2979d57f8521af  libpulsedsp_6.0-5_amd64.deb
a7eaef3577707094aa3ff876cb47ebf906515d5f  libpulsedsp_7.0-1_amd64.deb
2520ace8a1c9263b9016ffada878309dc1f4be79  pulseaudio_5.0-13_amd64.deb
49ce8f05d677ff9608153bb34078c23e3243bbf6  pulseaudio_6.0-5_amd64.deb
ce8daf76ccb55e697b9c6ed80376954710934d39  pulseaudio_7.0-1_amd64.deb
1f4a193ae590e57041b4fbbd8eb26c82a4159bd1  pulseaudio-utils_5.0-13_amd64.deb
54a261b9febf9ead9bd516cd4d95e7ce8249d7ae  pulseaudio-utils_6.0-5_amd64.deb
3672185f098490ae2f6bfa04305fb1cfd7daa0ff  pulseaudio-utils_7.0-1_amd64.deb
EOF

wget "http://zarb.org/~gc/fb/new.ogg"
echo f9b1ac303232d9f0e8fa126f850e3563170e6209 new.ogg | sha1sum -c

wget http://ndevilla.free.fr/iniparser/iniparser-3.1.tar.gz
echo 41eae7b414cad9cd42ae2c2a64394c10d7ab655e iniparser-3.1.tar.gz | sha1sum -c

wget -O adhd.tar.gz "https://chromium.googlesource.com/chromiumos/third_party/adhd/+archive/${ADHD_COMMIT}.tar.gz"
# Checking integrity of adhd.tar.gz is unfortunately not possible

cat > iniparser-3.0b-cpp.patch <<"EOF"
diff -ur iniparser3.0b/src/dictionary.c iniparser3.0b-patched/src/dictionary.c
--- iniparser3.0b/src/dictionary.c	2007-11-24 05:39:18.000000000 +0800
+++ iniparser3.0b-patched/src/dictionary.c	2009-04-01 21:38:09.000000000 +0800
@@ -38,6 +38,9 @@
 /*---------------------------------------------------------------------------
   							Private functions
  ---------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /* Doubles the allocated size associated to a pointer */
 /* 'size' is the current allocated size. */
@@ -401,5 +404,10 @@
 	dictionary_del(d);
 	return 0 ;
 }
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif
 /* vim: set ts=4 et sw=4 tw=75 */
diff -ur iniparser3.0b/src/iniparser.h iniparser3.0b-patched/src/iniparser.h
--- iniparser3.0b/src/iniparser.h	2007-11-24 05:38:19.000000000 +0800
+++ iniparser3.0b-patched/src/iniparser.h	2009-04-01 21:38:02.000000000 +0800
@@ -41,6 +41,10 @@
 #define iniparser_getstr(d, k)  iniparser_getstring(d, k, NULL)
 #define iniparser_setstr        iniparser_setstring
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*-------------------------------------------------------------------------*/
 /**
   @brief    Get number of sections in a dictionary
@@ -277,4 +281,8 @@
 /*--------------------------------------------------------------------------*/
 void iniparser_freedict(dictionary * d);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
EOF

cat > cras.mk.pacth << "EOF"
diff --git a/cras/cras.mk b/cras/cras.mk
index 8ad715e..a1520ff 100644
--- a/cras/cras.mk
+++ b/cras/cras.mk
@@ -16,6 +16,7 @@ $(ADHD_DIR)/cras/Makefile: $(ADHD_DIR)/cras/configure
 	    --build=$(CBUILD)			\
 	    --host=$(CHOST)			\
 	    --prefix=/usr			\
+	    --libdir=/usr/lib/x86_64-linux-gnu  \
 	    --mandir=/usr/share/man		\
 	    --infodir=/usr/share/info		\
 	    --datadir=/usr/share		\
EOF

cat > build.sh <<"EOF"
#!/bin/bash
set -e
cd /root

# Dependencies of PulseAudio 7
dpkg -i libdbus-1-3_1.10.0-3_amd64.deb libdbus-1-dev_1.10.0-3_amd64.deb liborc-0.4-0_0.4.24-1_amd64.deb
tar xf iniparser-3.1.tar.gz
cd iniparser
patch -Np1 -i ../iniparser-3.0b-cpp.patch
make
cp src/*.h /usr/include
cp libiniparser.so.0 /usr/lib/x86_64-linux-gnu
ln -sf libiniparser.so.0 /usr/lib/x86_64-linux-gnu/libiniparser.so
ldconfig
cd ..
mkdir adhd
cd adhd
tar xf ../adhd.tar.gz
patch -Np1 -i ../cras.mk.pacth
make
make install
cd ..
EOF
chmod +x build.sh

cat > ../usr/share/alsa/alsa.conf.d/90-cras.conf << "EOF"
pcm.cras {
    type cras
}

ctl.cras {
    type cras
}
EOF

cat > ../etc/rc.local << "EOF"
#!/bin/sh

grep -q dobenchmark /proc/cmdline || exit 0
sleep 5

export TERM=linux
powertop --quiet --auto-tune </dev/tty1 >/dev/tty1 2>&1
( sleep 5 ; setterm --blank force </dev/tty1 >/dev/tty1 2>&1 ) &
/root/test.sh &
exit 0
EOF
chmod +x ../etc/rc.local

cat > test.sh << "EOF"
#!/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin

cd /root
mkdir /var/run/cras
sox new.ogg new.wav

echo 0 > /sys/class/graphics/fbcon/cursor_blink

for a in `find /proc/asound -name prealloc` ; do
    echo 1024 > "$a"
done

startdate=`date +%s`

test_case=pulse
eval `grep -o 'test_case=[^ ]*' /proc/cmdline`

pa_version="5"
eval `grep -o 'pa_version=[^ ]*' /proc/cmdline`

latency_msec=1000
eval `grep -o 'latency_msec=[^ ]*' /proc/cmdline`

resampler=""
eval `grep -o 'resampler=[^ ]*' /proc/cmdline`

cras_output="5:0"
eval `grep -o 'cras_output=[^ ]*' /proc/cmdline`

save=/dev/sda1
eval `grep -o 'save=[^ ]*' /proc/cmdline`

case "$pa_version" in
5)
    v=5.0-13
    ;;
6)
    v=6.0-5
    ;;
*)
    v=7.0-1
    ;;
esac

dpkg -i libpulse0_${v}_amd64.deb libpulsedsp_${v}_amd64.deb \
        pulseaudio_${v}_amd64.deb pulseaudio-utils_${v}_amd64.deb

if [ "$resampler" != "" ] ; then
    echo "resample-method = $resampler" >> /etc/pulse/daemon.conf
    echo "default-sample-rate = 48000" >> /etc/pulse/daemon.conf
    echo "alternate-sample-rate = 48000" >> /etc/pulse/daemon.conf
fi

# Approximation, valid for two periods only
period_size=$(( ( 441 * $latency_msec + 221 ) / 640 * 32 ))
buffer_size=$(( $period_size * 2 ))

aplay_opts=""
case "$test_case" in
alsa)
    for card in 2 1 0 ; do
        if [ -e /dev/snd/pcmC${card}D0p ] ; then
	    aplay_opts="-M -D hw:$card --period-size $period_size --buffer-size $buffer_size"
	fi
    done
    ;;
pulse)
    pulseaudio --start
    sleep 3
    ;;
cras)
    cras &
    sleep 3
    cras_test_client --select_output "$cras_output"
    sleep 1
    aplay_opts="-D cras --period-size $period_size --buffer-size $buffer_size"
    aplay $aplay_opts -d 1 -f cd /dev/zero
    speel 1
    ;;
esac

startdate=`date +%s`

# For testing in qemu
echo 42000000 > /root/energy_now
energy_file=/root/energy_now
if [ -f /sys/class/power_supply/BAT1/energy_now ] ; then
    energy_file=/sys/class/power_supply/BAT1/energy_now
fi

read energy_now < "$energy_file"
energy_stop=$(( $energy_now * 3 / 4 ))

alsactl init   # so that all sound servers play at the same volume

sleep 1
echo "# `cat /proc/cmdline`" > report.txt

while :; do
    now=`date +%s`
    read energy_now < "$energy_file"
    echo $(( $now - $startdate )) $energy_now >> report.txt
    if [ "$energy_now" -lt "$energy_stop" ] ; then
        mdadm --assemble --scan
        ntfs-3g "$save" /mnt || mount -o rw "$save" /mnt || echo "The report will not be saved"
	mkdir /mnt/battery-reports
	cp report.txt /mnt/battery-reports/report-$startdate.txt
	umount /mnt || true
	sync
	systemctl poweroff
	sleep 1000
	break
    fi
    case "$test_case" in
    alsa|cras)
        aplay $aplay_opts new.wav
	;;
    pulse)
        paplay --latency=$(( $buffer_size * 4 )) new.wav
	;;
    esac
done

EOF
chmod +x test.sh
)

chroot "$thedir" /root/build.sh
umountfs

find "$thedir/var/cache/apt/archives" -type f -name "*.deb" -delete
rm -rf "$thedir/root/adhd" "$thedir/root/iniparser"
rm -f "$thedir"/boot/config-* "$thedir"/boot/initrd.img-* "$thedir"/boot/System.map-*

( cd "$thedir" ; find . | cpio --create -H newc | gzip -9 ) > initramfs.img
cp "$thedir"/boot/vmlinuz* vmlinuz
