#!/bin/bash
# fw_type will always be developer for Mario.
# Alex and ZGB need the developer BIOS installed though.
function ask_stable_or_testing() 
{
  read -p "Choose debian release. Please enter [s]table or [t]esting: "
  case $(echo $REPLY | tr '[A-Z]' '[a-z]') in
    t|testing) echo "testing" ;;
    s|stable) echo "stable" ;;
    *)     echo "" ;;
  esac
}

function write_reboot_script()
{
reboot_script=$1
cat > ${reboot_script} <<EOF
#!/bin/bash
cgpt add -i ${KERNPART} -P 5 -T 1 -S 1 ${target_disk}
echo 'Setup complete. Enter "sudo reboot" when you are ready to reboot'
EOF
chmod +x ${reboot_script}
}

release=""
while [ -z "${release}" ]
do
  release=$(ask_stable_or_testing)
done
echo "release is ${release}"
if [ "${release}" = "stable" ]
then
  currentimage="bodhi-chromebook-rootfs-20140112.5.tar.xz"
  currentmd5="ca24a8ac69852fc5ae9d516238e07c43"
else
  currentimage="bodhi-chromebook-rootfs-20140214.tar.xz"
  currentmd5="dc724703a7e08c20841fd54617ecdaf4"
fi

echo "Chosen root filesystem image is ${currentimage}"

fw_type="`crossystem mainfw_type`"
  
if [ ! "$fw_type" = "developer" ]
  then
    echo -e "\nYou're Chromebook is not running a developer BIOS!"
    echo -e "You need to run:"
    echo -e ""
    echo -e "sudo chromeos-firmwareupdate --mode=todev"
    echo -e ""
    echo -e "and then re-run this script."
    return
  else
    echo -e "\nOh good. You're running a developer BIOS...\n"
fi

# hwid lets us know if this is a Mario (Cr-48), Alex (Samsung Series 5), ZGB (Acer), etc
hwid="`crossystem hwid`"

echo -e "Chome OS model is: $hwid\n"

chromebook_arch="`uname -m`"
if [ ! "$chromebook_arch" = "armv7l" ]
then
  echo -e "This version of Bodhi Linux is for the ARM-based Chromebooks only\n"
else
  echo -e "and you're running on a ARM-based Chromebook, awesome!\n"
fi

read -p "Press [Enter] to continue..."

powerd_status="`initctl status powerd`"
if [ ! "$powerd_status" = "powerd stop/waiting" ]
then
  echo -e "Stopping powerd to keep display from timing out..."
  initctl stop powerd
fi

powerm_status="`initctl status powerm`"
if [ ! "$powerm_status" = "powerm stop/waiting" ]
then
  echo -e "Stopping powerm to keep display from timing out..."
  initctl stop powerm
fi

setterm -blank 0

justerase=0

if [ "$1" != "" ] 
then
  target_disk=$1
else
  target_disk="`rootdev -d -s`"
fi

if [[ "${target_disk}" =~ "mmcblk" ]]
then
  PFX="p"
else
  PFX=""
fi

echo "target disk is ${target_disk}"
#Even if they specified the device, if it is the main one, don't let them hose it
if [ "${target_disk}" = "/dev/mmcblk0" ]
then
  KERNPART=6
  ROOTPART=7
  target_kern="${target_disk}${PFX}${KERNPART}"
  target_rootfs="${target_disk}${PFX}${ROOTPART}"
else
  KERNPART=1
  ROOTPART=2
  target_kern="${target_disk}${PFX}${KERNPART}"
  target_rootfs="${target_disk}${PFX}${ROOTPART}"
fi

if [ ! "${target_disk}" = "/dev/mmcblk0" ]
then
  echo "Got ${target_disk} as target drive"
  echo ""
  echo "WARNING! All data on this device will be wiped out! Continue at your own risk!"
  echo ""
  read -p "Press [Enter] to install Bodhi on ${target_disk} or CTRL+C to quit"

  ext_size="`blockdev --getsz ${target_disk}`"
  aroot_size=$((ext_size - 65600 - 33))
  parted --script ${target_disk} "mktable gpt"
  cgpt create ${target_disk} 
  cgpt add -i ${KERNPART} -b 64 -s 32768 -S 1 -P 5 -l KERN-A -t "kernel" ${target_disk}
  cgpt add -i ${ROOTPART} -b 65600 -s $aroot_size -l ROOT-A -t "rootfs" ${target_disk}
  sync
  blockdev --rereadpt ${target_disk}
  partprobe ${target_disk}
  crossystem dev_boot_usb=1
else
  # Do partitioning (if we haven't already)
  ckern_size="`cgpt show -i ${KERNPART} -n -s -q ${target_disk}`"
  croot_size="`cgpt show -i ${ROOTPART} -n -s -q ${target_disk}`"
  state_size="`cgpt show -i 1 -n -s -q ${target_disk}`"

  max_ubuntu_size=$(($state_size/1024/1024/2))
  rec_ubuntu_size=$(($max_ubuntu_size - 1))
  # If KERN-C and ROOT-C are one, we partition, otherwise assume they're what they need to be...
  if [ "$ckern_size" =  "1" -o "$croot_size" = "1" ]
  then
    while :
    do
      read -p "Enter the size in gigabytes you want to reserve for Bodhi. Acceptable range is 5 to $max_ubuntu_size  but $rec_ubuntu_size is the recommended maximum: " ubuntu_size
      if [ ! $ubuntu_size -ne 0 2>/dev/null ]
      then
        echo -e "\n\nNumbers only please...\n\n"
        continue
      fi
      if [ $ubuntu_size -lt 5 -o $ubuntu_size -gt $max_ubuntu_size ]
      then
        echo -e "\n\nThat number is out of range. Enter a number 5 through $max_ubuntu_size\n\n"
        continue
      fi
      break
    done
    # We've got our size in GB for ROOT-C so do the math...

    #calculate sector size for rootc
    rootc_size=$(($ubuntu_size*1024*1024*2))

    #kernc is always 16mb
    kernc_size=32768

    #new stateful size with rootc and kernc subtracted from original
    stateful_size=$(($state_size - $rootc_size - $kernc_size))

    #start stateful at the same spot it currently starts at
    stateful_start="`cgpt show -i 1 -n -b -q ${target_disk}`"

    #start kernc at stateful start plus stateful size
    kernc_start=$(($stateful_start + $stateful_size))

    #start rootc at kernc start plus kernc size
    rootc_start=$(($kernc_start + $kernc_size))

    #Do the real work
    
    echo -e "\n\nModifying partition table to make room for Bodhi." 
    echo -e "Your Chromebook will reboot, wipe your data and then"
    echo -e "you should re-run this script..."
    umount /mnt/stateful_partition
    
    # stateful first
    cgpt add -i 1 -b $stateful_start -s $stateful_size -l STATE ${target_disk}

    # now kernc
    cgpt add -i 6 -b $kernc_start -s $kernc_size -l KERN-C ${target_disk}

    # finally rootc
    cgpt add -i 7 -b $rootc_start -s $rootc_size -l ROOT-C ${target_disk}

    reboot
    exit
  else
    #Make sure it is ext4, since our boot parameters specify that. If not, will
    #have to re-partition
    finfo=$(fsck -N ${target_rootfs} 2>/dev/null)
    if [[ "${finfo}" =~ "ext4" ]]
    then
      justerase=1
      echo "Found existing ext4 root partition. Will just replace root filesystem"
    fi
  fi
fi

if [ ! -d /mnt/stateful_partition/bodhi ]
then
  mkdir /mnt/stateful_partition/bodhi
fi

cd /mnt/stateful_partition/bodhi

# Download and copy bodhi root filesystem
wget http://sourceforge.net/projects/bodhilinux/files/ARMHF/Chromebook/$currentimage

md5=`md5sum $currentimage | awk '{ print $1 }'`

if [ "$md5" != "$currentmd5" ]
then
    echo "Bad check sum. Cleaning up files and exiting - please try again."
    rm $currentimage
    exit 1
fi

echo "Target Kernel Partition: $target_kern  Target Root FS: ${target_rootfs}"

if [ ! -d /tmp/urfs ]
then
  mkdir /tmp/urfs
fi
if [ ${justerase} -eq 0 ]
then
  mkfs.ext4 ${target_rootfs}
fi
mount -t ext4 ${target_rootfs} /tmp/urfs
if [ ${justerase} -eq 1 ]
then
   rm -rf /tmp/urfs/.??*
   rm -rf /tmp/urfs/*
fi

mv ${currentimage} /tmp/urfs/

cd /tmp/urfs

echo "extracting root filesystem from ${currentimage}"
tar -Jxvf ${currentimage}
rm ${currentimage}

#Fix dbus permissions for removable storage
if [ "${release}" = "stable" ]
then
  wget http://sourceforge.net/projects/bodhilinux/files/ARMHF/Chromebook/chromebook-dbus.sh
  chroot . bash chromebook-dbus.sh
  rm chromebook-dbus.sh
else
  chroot . dpkg-reconfigure bodhi-chromebook-polkit
fi

rm -rf /tmp/urfs/lib/modules/*
rm -rf /tmp/urfs/lib/firmware/*
cp -ar /lib/modules/* /tmp/urfs/lib/modules/
cp -ar /lib/firmware/* /tmp/urfs/lib/firmware/

cd
umount /tmp/urfs

#set -x
kernel_image=/boot/vmlinuz-`uname -r`
ls ${kernel_image}
ls_boot=$?

UUID=$(cgpt show -i ${ROOTPART} -u ${target_disk})
if [ $? -eq 0 ]
then
  BOOTDEV="PARTUUID=${UUID}"
else
  BOOTDEV=${target_rootfs}
fi
echo "console=tty1 debug verbose root=${BOOTDEV} printk.time=1 rootwait rw rootfstype=ext4 lsm.module_locking=0" > /tmp/config
if [ ${ls_boot} -eq 0 ]
then
echo "Packing kernel"
vbutil_kernel --pack /tmp/newkern \
--keyblock /usr/share/vboot/devkeys/kernel.keyblock \
--version 1 \
--signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \
--config /tmp/config \
--vmlinuz ${kernel_image} \
--arch arm
else
  echo "Repacking running kernel"
# need to use "cgpt show /dev/mmcblk0" to determine kernel with highest priority to choose which one to copy. We are assuming partitions 2 and 4 are kernels
  ptwo=`cgpt show -i 2 -P /dev/mmcblk0`
  pfour=`cgpt show -i 4 -P /dev/mmcblk0`
  echo "Priority of partition 2 is ${ptwo}, priority of partition 4 is ${pfour}"
  rblock=2
  if [ ${ptwo} -eq 0 ]
  then
    rblock=4
  else
    if [ ${pfour} -gt ${ptwo} ]
    then
      rblock=4
    fi
  fi
  echo "Determined that partition ${rblock} is running kernel"
  dd if=/dev/mmcblk0p${rblock} of=/tmp/oldblob
  echo "Repacking running kernel"
  vbutil_kernel --repack /tmp/newkern \
--keyblock /usr/share/vboot/devkeys/kernel.keyblock \
--version 1 \
--signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \
--config /tmp/config \
--oldblob /tmp/oldblob
fi

if [ $? -ne 0 ]
then
  echo "vbutil_kernel failed"
  exit 99
fi

echo "Copying new kernel to $target_kern"
dd if=/tmp/newkern of=$target_kern

#echo "target kernel is ${target_kern}, target disk is ${target_disk}" >/home/chronos/user/bodhiboot.info

#Set Bodhi partition as top priority for booting
cgpt add -i ${KERNPART} -P 5 -T 1 -S 1 ${target_disk}
if [ "${target_disk}" = "/dev/mmcblk0" ]
then
  write_reboot_script "/home/chronos/user/setup_reboot_to_bodhi.sh"
fi
echo 'Installation complete. You can look around now and then reboot when ready (enter "sudo reboot")'
#reboot
