#!/bin/bash

#disable waydroid repo so it can't update and undo the nftables change (pi-apps handles updates now)
version=waydroid_1.6.2_all.deb

#set yadflags so userinput_func and other dialog windows can use it (arrays are not exported to subprocesses)
yadflags=(--class Pi-Apps --name "Pi-Apps" --window-icon="${DIRECTORY}/icons/logo.png")

if [ "$XDG_SESSION_TYPE" != wayland ] && command -v raspi-config >/dev/null ;then
  error "User error: Waydroid only works on Wayland desktop environments. Please enable the LabWC compositor in raspi-config, reboot, then install Waydroid again."
elif [ "$XDG_SESSION_TYPE" != wayland ];then
  error "User error: Waydroid only works on Wayland desktop environments. Please switch to a Wayland compositor, then install Waydroid again."
fi

#botspot: tutorial said 4k pagesize is needed, but verify if this is the case
PAGE_SIZE="$(getconf PAGE_SIZE)"
if [[ "$PAGE_SIZE" == "16384" ]]; then
  #switch to 4K pagesize kernel
  if [ -f /boot/config.txt ] || [ -f /boot/firmware/config.txt ]; then
    if [ -f /boot/firmware/config.txt ]; then
      boot_config="/boot/firmware/config.txt"
    elif [ -f /boot/config.txt ]; then
      boot_config="/boot/config.txt"
    fi
    text="Raspberry Pi 5 PiOS images ship by default with a 16K PageSize Linux Kernel.
This kernel causes incompatibilities with some software including Waydroid https://github.com/raspberrypi/bookworm-feedback/issues/107

Would you like to automatically switch to a 4K PageSize Linux Kernel?"
    userinput_func "$text" "No, keep 16K PageSize Kernel and Exit" "Yes, switch to 4K PageSize Kernel"
    if [ "$output" == "No, keep 16K PageSize Kernel and Exit" ]; then
      error "User error: Your current running kernel is built with 16K PageSize and is incompatible with Waydroid. You must switch to a 4K PageSize kernel (and chose to not do so automatically) before installing Waydroid."
    fi
    echo "" | sudo tee --append $boot_config >/dev/null
    echo "[pi5]" | sudo tee --append $boot_config >/dev/null
    echo "kernel=kernel8.img" | sudo tee --append $boot_config >/dev/null
    reboot_because="The 4K PageSize Kernel has been enabled by adding 'kernel=kernel8.img' to $boot_config"
  else
    error "User error (reporting allowed): Your current running kernel is built with 16K PageSize and is incompatible with Waydroid. Changing kernels automatically cannot be done since no /boot/config.txt or /boot/firmware/config.txt file was found."
  fi
fi

#botspot: check what output of ls /proc/pressure is when psi!=1
if [ ! -e /proc/pressure ];then
  if [ -f /boot/firmware/cmdline.txt ];then
    boot_cmdline=/boot/firmware/cmdline.txt
  elif [ -f /boot/cmdline.txt ];then
    boot_cmdline=/boot/cmdline.txt
  else
    error "User error (reporting allowed): Waydroid needs /proc/pressure to be enabled by the kernel. This could not be enabled automatically because /boot/firmware/cmdline.txt could not be found. Please research how to enable psi=1 on your platform."
  fi
  
  text="Waydroid needs /proc/pressure to be enabled by the kernel. This can be enabled automatically, but it requires a reboot. Proceed?"
  userinput_func "$text" "No, exit now" "Yes, enable /proc/pressure"
  if [ "$output" == "No, exit now" ]; then
    error "User error (reporting allowed): Waydroid needs /proc/pressure to be enabled by the kernel. This could not be enabled automatically because user refused to enable it."
  fi
  
  #make sure to edit the first line in cmdline.txt. DON'T APPEND to the file - this puts psi=1 on a second line if the file already ended with a newline!!
  if ! grep -q '. psi=1' $boot_cmdline ;then
    sudo sed -i '1s/$/ psi=1/' $boot_cmdline
  fi
  #detect if a previous version of this script added psi=1 to a newline. If so, remove it.
  if grep -xF ' psi=1' $boot_cmdline ;then
    sudo sed -i '/^ psi=1$/d' $boot_cmdline
  fi
  reboot_because="The /proc/pressure mode has been enabled by adding 'psi=1' to $boot_cmdline"
fi

if [ ! -z "$reboot_because" ];then
  echo "$reboot_because"
  echo "Please reboot now and install the Waydroid app again."
  sleep infinity
fi

#waydroid needs /dev/binder
enable_module binder_linux

if ! grep -q ' binder$' /proc/devices ;then
  error "User error (reporting allowed): Could not enable the binder kernel module. Please find a way to get it configured on your device. This may require a kernel recompilation, or if on Ubuntu, additional kernel modules may need to be installed with something like: sudo apt install linux-modules-extra-raspi"
fi

if [ ! -f /var/lib/waydroid/images/vendor.img ];then
  text="<i>To Google, or not to Google... that is the question.</i>"$'\n'"(Aurora Store offers all Google Play Store apps without requiring a sign-in.)"
  userinput_func "$text" "Use an Android version with Google's apps installed" "No Google, install Aurora Store" "No Google, don't preinstall anything"
  if [ "$output" == "Use an Android version with Google's apps installed" ]; then
    init_google=yes
  elif [ "$output" == "No Google, install Aurora Store" ];then
    init_google=no
    install_aurora=yes
  else
    init_google=no
    install_aurora=no
  fi
fi

sudo curl -Sf https://repo.waydro.id/waydroid.gpg --output /usr/share/keyrings/waydroid.gpg || error "Failed to download waydroid.gpg to keyrings directory!"
echo "deb [signed-by=/usr/share/keyrings/waydroid.gpg] https://repo.waydro.id/ $(get_codename) main" | sudo tee /etc/apt/sources.list.d/waydroid.list >/dev/null

install_packages waydroid nftables || exit 1

#enable nftables in waydroid script
sudo sed -i 's/^LXC_USE_NFT="false"/LXC_USE_NFT="true"/g' /usr/lib/waydroid/data/scripts/waydroid-net.sh

#ensure dnsmasq cannot interfere with waydroid
echo 'bind-interfaces
except-interface=waydroid0' | sudo tee /etc/dnsmasq.d/waydroid.conf

#disable waydroid repo so it can't update and undo the nftables change (pi-apps handles updates now)
sudo rm /etc/apt/sources.list.d/waydroid.list

if [ "$init_google" == yes ];then
  sudo waydroid --details-to-stdout init -c https://ota.waydro.id/system -v https://ota.waydro.id/vendor -s GAPPS || sudo waydroid init -s GAPPS || error "Waydroid failed to initialize"
elif [ "$init_google" == no ];then
  sudo waydroid --details-to-stdout init -c https://ota.waydro.id/system -v https://ota.waydro.id/vendor -s VANILLA || sudo waydroid init -s VANILLA || error "Waydroid failed to initialize"
fi

waydroid session stop
waydroid session start &

#watch to see if Android boots up okay
status "Starting Android session, please wait... "
i=0
while [ "$(waydroid prop get sys.boot_completed 2>/dev/null)" != "1" ];do
  sleep 1
  i=$((i+1))
  if [ "$i" -ge 10 ] && ! waydroid status | grep -q "^Session:.*RUNNING$" ;then
    error "Waydroid session failed to start in 10 seconds!
Output from running sudo /usr/lib/waydroid/data/scripts/waydroid-net.sh start:
$(sudo /usr/lib/waydroid/data/scripts/waydroid-net.sh start 2>&1)
Today's contents of /var/lib/waydroid/waydroid.log:
$(grep "$(date '+%d %b %Y')" /var/lib/waydroid/waydroid.log)"
  fi
done
status_green Done

#fix for wayfire compositor (prop set seems to need to run after waydroid session start, see https://forums.raspberrypi.com/viewtopic.php?p=2379548#p2379548)
waydroid prop set persist.waydroid.multi_windows true || error "Waydroid failed to set persist.waydroid.multi_windows config option, most likely something else is wrong."

#allow waydroid direct usb access to things like game controllers
waydroid prop set persist.waydroid.udev true
waydroid prop set persist.waydroid.uevent true

if [ "$init_google" == yes ];then
  id=''
  i=0
  while [ -z "$id" ];do
    id="$(sudo waydroid shell -- sh -c "sqlite3 /data/data/*/*/gservices.db 'select * from main where name = \"android_id\";'" 2>/dev/null | awk -F'|' '{print $2}')"
    if [ ! -z "$id" ];then
      break
    elif [ $((i%6)) == 2 ];then
      warning "Android has booted, but it's taking longer than usual for the Lineage OS image to get assigned a android_id from Google's servers. Make sure you are connected to the Internet. Will keep trying... (attempt $i of 90)"
    elif [ "$i" == 90 ];then
      error "Failed to get android_id from the Lineage OS image. Perhaps it did not initialize fully? Please refer to errors above. Raw output was '$(sudo waydroid shell -- sh -c "sqlite3 /data/data/*/*/gservices.db 'select * from main where name = \"android_id\";'" 2>&1)'"
    fi
    sleep 10
    i=$((i+1))
  done
  #id is now set beyond this point
  x-www-browser 'https://www.google.com/android/uncertified' &
  
  echo "$id" | yad "${yadflags[@]}" --text='A browser should have opened <a href="https://www.google.com/android/uncertified">google.com/android/uncertified</a>.'$'\n''Paste this Android ID into the box, then click Register:' \
    --text-info --fontname='' --fixed --button=Done:0
  
  echo -e "Now please be patient for Google to register the device. In a few minutes, first click the menu launcher to Stop Waydroid, then open the Google Play Store in the main menu and try to login. Try again later if it fails. Search the Internet for further help." | \
    yad "${yadflags[@]}" --text-info --fontname='' --width=400 --height=300 --wrap --button=OK:0 &
  yadpid=$!
elif [ "$install_aurora" == yes ];then
  echo "You have picked the 'Waydroid without Google' option. Right now, any apps that try to use Google Play APIs will likely fail to launch. This is fixable, but it involves something called MicroG, and I could not figure out how to make it work in Waydroid. Others have done it before, and AI makes it sound easy, but I just don't have the time to figure it out.
IF YOU THINK YOU COULD HELP WITH THAT, please get in touch so that everybody can enjoy a more functional Google-free experience.

Thanks!
-Botspot" | yad "${yadflags[@]}" --text-info --wrap --width=600 --height=400 --fontname='' "${yadflags[@]}" --button=OK:0 &
  yadpid=$!
  
  wget -O /tmp/AuroraStore.apk https://auroraoss.com/downloads/AuroraStore/Release/AuroraStore-4.7.5.apk || error "Failed to download AuroraStore.apk"
  waydroid app install /tmp/AuroraStore.apk || waydroid app install /tmp/AuroraStore.apk || error "Failed to install AuroraStore.apk"
  
  #try installing MicroG (doesn't seem to make a difference for apps that need playstore APIs)
  #git clone https://github.com/casualsnek/waydroid_script
  #cd waydroid_script
  #python3 -m venv venv
  #venv/bin/pip install -r requirements.txt
  #sudo venv/bin/python3 main.py install microg
  
fi

#make menu launcher to stop Waydroid
echo "[Desktop Entry]
Type=Application
Name=Stop Waydroid
Exec=waydroid session stop
Icon=process-stop
Categories=X-WayDroid-App;
X-Purism-FormFactor=Workstation;Mobile;" | sudo tee /usr/share/applications/stop-waydroid.desktop >/dev/null

#ensure the Waydroid menu launcher is not hidden for no good reason https://github.com/waydroid/waydroid/issues/1407
sudo cp -n /usr/share/applications/Waydroid.desktop ~/.local/share/applications/Waydroid.desktop
sed -i 's/NoDisplay=true/NoDisplay=false/g' ~/.local/share/applications/Waydroid.desktop
#lock the file to prevent waydroid from hiding it again
sudo chmod -w ~/.local/share/applications/Waydroid.desktop

waydroid session stop
if [ ! -z "$yadpid" ];then
  wait $yadpid #don't allow the script to exit until user reads and closes the last dialog
fi
true
