#!/bin/sh
# Part of spindle http://asbradbury.org/projects/spindle
#
# See LICENSE file for copyright and license details

set -ex

. ./common

WORKDIR=work
OUTDIR=out
CURIMG=stage3.$IMGFORMAT

configure_apt() {
  onvm_chroot sh -l -ex - <<\EOF
cat <<\EOF1 > /etc/apt/apt.conf.d/50raspi
# never use pdiffs. Current implementation is very slow on low-powered devices
Acquire::PDiffs "0";

# download up to 5 pdiffs:
#Acquire::PDiffs::FileLimit "5";
EOF1
EOF
}

set_debconf_selections() {
  ssh_in_to_qemu chroot /mnt sh -l -ex - <<EOF
debconf-set-selections <<SELEOF
# System's default wordlist:
# Choices: english (Webster's Second International English wordlist), Manual symlinks setting
dictionaries-common	dictionaries-common/default-wordlist	select	english (Webster's Second International English wordlist)
# Use Control+Alt+Backspace to terminate the X server?
keyboard-configuration keyboard-configuration/ctrl_alt_bksp boolean true
# Backend to use for TrueType handling on X:
# Choices: freetype, xtt
x-ttcidfont-conf	x-ttcidfont-conf/tt_backend	select	freetype
# Character set to support:
# Choices: . Arabic, # Armenian, # Cyrillic - KOI8-R and KOI8-U, # Cyrillic - non-Slavic languages, # Cyrillic - Slavic languages (also Bosnian and Serbian Latin), . Ethiopic, # Georgian, # Greek, # Hebrew, # Lao, # Latin1 and Latin5 - western Europe and Turkic languages, # Latin2 - central Europe and Romanian, # Latin3 and Latin8 - Chichewa; Esperanto; Irish; Maltese and Welsh, # Latin7 - Lithuanian; Latvian; Maori and Marshallese, . Latin - Vietnamese, # Thai, . Combined - Latin; Slavic Cyrillic; Hebrew; basic Arabic, . Combined - Latin; Slavic Cyrillic; Greek, . Combined - Latin; Slavic and non-Slavic Cyrillic
console-setup	console-setup/codeset47	select	. Combined - Latin; Slavic Cyrillic; Greek
# Time zone:
# Choices: GMT, GMT+0, GMT+1, GMT+10, GMT+11, GMT+12, GMT+2, GMT+3, GMT+4, GMT+5, GMT+6, GMT+7, GMT+8, GMT+9, GMT-0, GMT-1, GMT-10, GMT-11, GMT-12, GMT-13, GMT-14, GMT-2, GMT-3, GMT-4, GMT-5, GMT-6, GMT-7, GMT-8, GMT-9, GMT0, Greenwich, UCT, UTC, Universal, Zulu
tzdata	tzdata/Zones/Etc	select	UTC
# for internal use
console-setup   console-setup/store_defaults_in_debconf_db      boolean true
# Font for the console:
# Choices: Fixed, Terminus, TerminusBold, TerminusBoldVGA, VGA, Do not change the boot/kernel font
console-setup	console-setup/fontface47	select	Do not change the boot/kernel font
# Enable subpixel rendering for screen:
# Choices: Automatic, Always, Never
fontconfig-config	fontconfig/subpixel_rendering	select	Automatic
# Method for toggling between national and Latin mode:
# Choices: Caps Lock, Right Alt (AltGr), Right Control, Right Shift, Right Logo key, Menu key, Alt+Shift, Control+Shift, Control+Alt, Alt+Caps Lock, Left Control+Left Shift, Left Alt, Left Control, Left Shift, Left Logo key, Scroll Lock key, No toggling
keyboard-configuration	keyboard-configuration/toggle	select	No toggling
# Font size:
# Choices: 13, 14, 15, 16, 18
console-setup	console-setup/fontsize-text47	select	16
# Locales to be generated:
# Choices: <SNIP>
locales	locales/locales_to_be_generated	multiselect	en_GB.UTF-8 UTF-8
# Keyboard model:
# Choices: <SNIP>
keyboard-configuration	keyboard-configuration/model	select	Generic 105-key (Intl) PC
# Users allowed to start the X server:
# Choices: Root Only, Console Users Only, Anybody
x11-common	x11-common/xwrapper/allowed_users	select	Anybody
# Compose key:
# Choices: No compose key, Right Alt (AltGr), Right Control, Right Logo key, Menu key, Left Logo key, Caps Lock
keyboard-configuration	keyboard-configuration/compose	select	No compose key
# Country of origin for the keyboard:
# Choices: <SNIP>
keyboard-configuration  keyboard-configuration/layout select English (UK)
# for internal use
keyboard-configuration  keyboard-configuration/layoutcode string gb
# Keymap to use:
# Choices: <SNIP>
keyboard-configuration	keyboard-configuration/xkb-keymap	select	British English
# Choices: English (UK), English (UK) - English (UK\, Colemak), English (UK) - English (UK\, Dvorak), English (UK) - English (UK\, Dvorak with UK punctuation), English (UK) - English (UK\, extended WinKeys), English (UK) - English (UK\, international with dead keys), English (UK) - English (UK\, Macintosh), English (UK) - English (UK\, Macintosh international), Other
keyboard-configuration  keyboard-configuration/variant select English (UK)
# Geographic area:
# Choices: Africa, America, Antarctica, Australia, Arctic, Asia, Atlantic, Europe, Indian, Pacific, SystemV, US, Etc
tzdata	tzdata/Areas	select	Etc
# Method for temporarily toggling between national and Latin input:
# Choices: No temporary switch, Both Logo keys, Right Alt (AltGr), Right Logo key, Left Alt, Left Logo key
keyboard-configuration	keyboard-configuration/switch	select	No temporary switch
# Encoding to use on the console:
# Choices: ARMSCII-8, CP1251, CP1255, CP1256, GEORGIAN-ACADEMY, GEORGIAN-PS, IBM1133, ISIRI-3342, ISO-8859-1, ISO-8859-10, ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, KOI8-R, KOI8-U, TIS-620, UTF-8, VISCII
console-setup	console-setup/charmap47	select	UTF-8
# Font tuning method for screen:
# Choices: Native, Autohinter, None
fontconfig-config	fontconfig/hinting_type	select	Native
# Font size:
# Choices: 
console-setup	console-setup/fontsize-fb47	select	16
# The desktop environment to install when the desktop task is selected
# Choices: gnome, kde, xfce
tasksel	tasksel/desktop	multiselect	xfce
# Key to function as AltGr:
# Choices: The default for the keyboard layout, No AltGr key, Right Alt (AltGr), Right Control, Right Logo key, Menu key, Left Alt, Left Logo key, Keypad Enter key, Both Logo keys, Both Alt keys
keyboard-configuration	keyboard-configuration/altgr	select	The default for the keyboard layout
# Default locale for the system environment:
# Choices: None, en_GB.UTF-8
locales	locales/default_environment_locale select	en_GB.UTF-8
SELEOF
EOF
}

install_packages() {
  # we may want to break out DEBIAN_FRONTEND=noninteractive
  ssh_in_to_qemu chroot /mnt sh -l -ex - <<\EOF
apt-get update
# install some utils
apt-get install -y dialog
apt-get install -y ssh locales less fbset sudo psmisc strace module-init-tools ifplugd ed ncdu
apt-get install -y console-setup keyboard-configuration debconf-utils parted unzip
apt-get install -y build-essential manpages-dev python bash-completion gdb pkg-config
apt-get install -y python-rpi.gpio v4l-utils
apt-get install -y lua5.1
[ "$(dpkg --print-architecture)" = armhf ] && apt-get install -y luajit
apt-get install -y hardlink ca-certificates curl
apt-get install -y fake-hwclock ntp nfs-common usbutils

apt-get install -y --no-install-recommends cifs-utils
echo "deb http://archive.raspberrypi.org/debian/ wheezy main untested" > /etc/apt/sources.list.d/raspi.list
apt-get update
apt-get install -y libraspberrypi-dev libraspberrypi-doc libfreetype6-dev
echo "deb http://archive.raspberrypi.org/debian/ wheezy main" > /etc/apt/sources.list.d/raspi.list
printf "# Uncomment line below then 'apt-get update' to enable 'apt-get source'\n" >> /etc/apt/sources.list.d/raspi.list
printf "#deb-src http://archive.raspberrypi.org/debian/ wheezy main\n" >> /etc/apt/sources.list.d/raspi.list
apt-get update
# Install stuff for wireless
apt-get install -y wpasupplicant wireless-tools firmware-atheros firmware-brcm80211 \
  firmware-libertas firmware-ralink firmware-realtek
/etc/init.d/fake-hwclock stop # save current time
update-rc.d hwclock.sh disable
# Don't need to start these by default, wastes boot time
update-rc.d nfs-common disable
update-rc.d rpcbind disable
apt-get install -y dosfstools
EOF
}

cache_keymap() {
  onvm_chroot sh -l -e - <<\EOF
setupcon --force --save-only -v
/etc/init.d/fake-hwclock stop # save current time
EOF
}

add_pi_user_to_groups() {
  onvm_chroot sh -l -ex - <<\EOF
groupadd -f -r input
for GRP in adm dialout cdrom audio users sudo video games plugdev input; do
  adduser pi $GRP
done
EOF
}

configure_useradd() {
  onvm_chroot sh -l -ex - <<\EOF
sed -i /etc/default/useradd -e 's/^# SKEL=/SKEL=/'
sed -i /etc/default/useradd -e 's|^SHELL=.*$|SHELL=/bin/bash|'
EOF
}

make_udev_input_rule() {
  onvm_chroot sh -l -e - <<EOF
printf 'SUBSYSTEM=="input", GROUP="input", MODE="0660"\n' > /etc/udev/rules.d/99-input.rules
EOF
}

configure_wifi() {
  onvm_chroot sh -l -e - <<EOF
cat <<\EOF1 >> /etc/network/interfaces

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
EOF1
cat <<\EOF2 > /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
EOF2
chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf
adduser pi netdev
EOF
}

apply_noobs_os_config() {
  onvm_chroot sh -l -ex - <<\EOF
cat <<\EOF1 > /etc/init.d/apply_noobs_os_config
#!/bin/sh
### BEGIN INIT INFO
# Provides:          apply_noobs_os_config
# Required-Start:
# Required-Stop:
# Default-Start: 2
# Default-Stop:
# Short-Description: Apply config from /boot/os_config.json
# Description:
### END INIT INFO

. /lib/lsb/init-functions

set -e

case "$1" in
  start)
    log_daemon_msg "Applying config from /boot/os_config.json (if it exists)"
    if raspi-config --apply-os-config; then
      rm /etc/init.d/apply_noobs_os_config && update-rc.d apply_noobs_os_config remove
      log_end_msg 0
    else
      log_end_msg 1
    fi
    ;;
  *)
    echo "Usage: $0 start" >&2
    exit 3
    ;;
esac
EOF1
chmod +x /etc/init.d/apply_noobs_os_config
update-rc.d apply_noobs_os_config start 2
EOF
}

remove_ssh_host_keys() {
  onvm_chroot sh -l -ex - <<\EOF
rm -f /etc/ssh/ssh_host_*_key*
cat <<\RCL | tee /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

exit 0
RCL
update-rc.d ssh disable # to be re-enabled at first boot when we regenerate ssh host keys
cat <<\EOF1 > /etc/init.d/regenerate_ssh_host_keys
#!/bin/sh
### BEGIN INIT INFO
# Provides:          regenerate_ssh_host_keys
# Required-Start:
# Required-Stop:
# Default-Start: 2
# Default-Stop:
# Short-Description: Regenerate ssh host keys
# Description:
### END INIT INFO

. /lib/lsb/init-functions

set -e

case "$1" in
  start)
    log_daemon_msg "Regenerating ssh host keys (in background)"
    nohup sh -c "yes | ssh-keygen -q -N '' -t dsa -f /etc/ssh/ssh_host_dsa_key && \
      yes | ssh-keygen -q -N '' -t rsa -f /etc/ssh/ssh_host_rsa_key && \
      yes | ssh-keygen -q -N '' -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key && \
      update-rc.d ssh enable && sync && \
      rm /etc/init.d/regenerate_ssh_host_keys && \
      update-rc.d regenerate_ssh_host_keys remove && \
      printf '\nfinished\n' && invoke-rc.d ssh start" > /var/log/regen_ssh_keys.log 2>&1 &
    log_end_msg $?
    ;;
  *)
    echo "Usage: $0 start" >&2
    exit 3
    ;;
esac
EOF1
chmod +x /etc/init.d/regenerate_ssh_host_keys
update-rc.d regenerate_ssh_host_keys start 2
EOF
}

configure_ifplugd() {
  onvm_chroot sh -l -ex - <<\EOF
sed /etc/default/ifplugd -i -e 's/^INTERFACES.*/INTERFACES="auto"/'
sed /etc/default/ifplugd -i -e 's/^HOTPLUG_INTERFACES.*/HOTPLUG_INTERFACES="all"/'
EOF
}

add_opt_vc_lib_to_ld_so() {
  onvm_chroot sh -l -ex - <<EOF
echo "/opt/vc/lib" > /etc/ld.so.conf.d/vmcs.conf
ldconfig
EOF
}

setup_sudoers() {
  onvm_chroot sh -l -ex - <<EOF
chmod +w /etc/sudoers
echo "pi ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
chmod -w /etc/sudoers
usermod --pass='*' root # don't need root password any more
EOF
}

# We use a swap file rather than a swap partition for greater flexibility
setup_swap() {
  onvm_chroot sh -l -e - <<EOF
apt-get -y install dphys-swapfile
echo "CONF_SWAPSIZE=100" > /etc/dphys-swapfile
EOF
}

setup_console_setup() {
  onvm_chroot sh -l -e - <<\EOF1
cat <<\EOF2 > /etc/default/console-setup
# CONFIGURATION FILE FOR SETUPCON

# Consult the console-setup(5) manual page.

ACTIVE_CONSOLES="/dev/tty[1-6]"

CHARMAP="UTF-8"

CODESET="guess"
FONTFACE=""
FONTSIZE=""

VIDEOMODE=

# The following is an example how to use a braille font
# FONT='lat9w-08.psf.gz brl-8x8.psf'
EOF2
EOF1
}

# Spread the word about my favourite inputrc tweak
tweak_inputrc() {
  onvm_chroot sh -l -e - <<\EOF1
cat <<\EOF2 >> /etc/inputrc

# mappings for up and down arrows search history
# "\e[B": history-search-forward
# "\e[A": history-search-backward
EOF2
EOF1
}

# It's not to have the sbin dirs in $PATH as that gives us ifconfig
fiddle_default_PATH() {
  # This sed match is clearly brittle and specific to the current debian 
  # /etc/profile
  onvm_chroot sh -l -ex - <<EOF
sed /etc/profile -i -e \
  's|PATH="/usr/.*games.*$|PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games"|'
# need to fix ENV_PATH in /etc/login.defs
sed -i /etc/login.defs -e "s|^ENV_PATH.*|ENV_PATH        PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games|"
EOF
}

add_qt5_apt_source() {
  onvm_chroot sh -l -e <<\EOF
echo "deb http://archive.qmh-project.org/rpi-wheezy/debian/ unstable main" >> /etc/apt/sources.list.d/qt5pi.list
apt-get update
EOF
}

install_memcpy_replacement() {
  onvm_chroot sh -l -e <<\EOF
apt-get install -y raspi-copies-and-fills
mv /etc/ld.so.preload /etc/ld.so.preload.disable
EOF
}

adjust_sysctl() {
  onvm_chroot sh -l -e <<\EOF
  printf "\n# rpi tweaks\nvm.swappiness=1\n" >> /etc/sysctl.conf
  printf "vm.min_free_kbytes = 8192\n" >> /etc/sysctl.conf
  # Only print important messages to console
  sed /etc/sysctl.conf -i -e "s/\#kernel\.printk/kernel.printk/"
EOF
}

set_default_kernel_modules() {
  onvm_chroot sh -e - <<EOF
  printf 'snd-bcm2835\n' >> /etc/modules
EOF
}

configure_sound() {
  onvm_chroot sh -e - <<EOF
cat <<\EOF1 > /etc/asound.conf
pcm.mmap0 {
    type mmap_emul;
    slave {
      pcm "hw:0,0";
    }
}

pcm.!default {
  type plug;
  slave {
    pcm mmap0;
  }
}
EOF1
EOF
}

cd $WORKDIR
dotask branch_image ../$OUTDIR/stage2.$IMGFORMAT $CURIMG
dotask run_qemu $CURIMG
dotask mount_apt_cache
dotask disable_starting_services
dotask configure_apt
dotask set_debconf_selections
dotask install_packages
dotask configure_ifplugd
dotask add_pi_user_to_groups
dotask configure_useradd
dotask make_udev_input_rule
dotask configure_wifi
#dotask add_opt_vc_lib_to_ld_so
dotask setup_sudoers
dotask setup_swap
dotask setup_console_setup
dotask cache_keymap
dotask tweak_inputrc
dotask fiddle_default_PATH
[ -n "$RASPBIAN" ] && dotask install_memcpy_replacement
dotask save_space_using_hardlink
#[ -z "$RASPBIAN" ] && dotask add_qt5_apt_source
dotask adjust_sysctl
dotask allow_starting_services
dotask remove_ssh_host_keys
dotask apply_noobs_os_config
dotask set_default_kernel_modules
# Latest firmware does not need mmap emulation, so skip asound.conf creation
#dotask configure_sound
dotask update_issue
dotask fingerprint_debian
dotask shutdown_qemu
dotask finish_image
