#!/bin/bash

#determine if chromium is installed
if command -v chromium >/dev/null || command -v chromium-browser >/dev/null || [ -d /snap/chromium ] || [ -d /var/lib/flatpak/app/org.chromium.Chromium ];then
  echo "Chromium is installed. Continuing..."
else
  error "User error: Chromium is not installed! Failed to find either a 'chromium' command or 'chromium-browser' command. If you are sure Chromium is installed, please reach out to Botspot for this to be fixed."
fi

#determine where the Chromium customizations folder is.
if [ -d /etc/chromium.d ];then
  folder=/etc/chromium.d
  
elif [ -d /snap/chromium ] && [ -f /snap/bin/chromium ];then
  #if Snap Chromium is installed, make the customizations folder and later make a script to source its contents
  if [ ! -d /etc/chromium.d ];then
    sudo mkdir -p /etc/chromium.d
  fi
  folder=/etc/chromium.d
  
elif [ -d /etc/chromium-browser/customizations ];then
  folder=/etc/chromium-browser/customizations
  
else
  error "User error: Cannot find the directory where Chromium keeps its flags! Usually this would be /etc/chromium.d or /etc/chromium-browser/customizations. On your system, neither of these directories exist. Please reach out to Botspot for this to be fixed."
fi

#Fix edge case where both an old version of chromium and a newer version are installed simultaneously
if [ -d /etc/chromium-browser/customizations ] && [ -d /etc/chromium.d ] && [ ! -L /etc/chromium-browser/customizations ];then
  #The $folder variable is /etc/chromium.d, but make /etc/chromium-browser/customizations pick up changes in /etc/chromium.d by using a symlink
  
  status -n "There are two Chromium customization folders on your system: /etc/chromium.d and /etc/chromium-browser/customizations.\nCreating a symlink to keep both locations synchronized..."
  
  #Move any customization files from /etc/chromium-browser/customizations to /etc/chromium.d, without overwriting anything
  sudo cp -nr /etc/chromium-browser/customizations /etc/chromium.d && \
  sudo rm -rf /etc/chromium-browser/customizations && \
  sudo ln -s /etc/chromium.d /etc/chromium-browser/customizations
  
  status_green Done
fi

#if Chromium is installed from Snap or Flatpak, make a script to source the contents of /etc/chromium.d
if [ -d /snap/chromium ] || [ -d /var/lib/flatpak/app/org.chromium.Chromium ];then
  if [ -f $HOME/.chromium-browser.init ] && [ "$(sha1sum $HOME/.chromium-browser.init | awk '{print $1}')" != 'cead3a7e98ddd3dbfeea285736c89409a7d426cd' ];then
    warning "This script needs to create this file: ~/.chromium-browser.init, but it already exists!"
    read -N 1 -p "Enter Y to replace this file, or N to exit now." answer
    echo
    
    if [ "$answer" != Y ] && [ "$answer" != y ];then
      echo "User error: $HOME/.chromium-browser.init already exists and the user did not want to overwrite it."
      exit 1
    fi
  fi

  #The ~/.chromium-browser.init file is the one single entrypoint for running scripts during a Snap Chromium's launch.
  #I encountered significant difficulty making this work. Normal Chromium-browser uses bash to source things, but Snap /snap/chromium/2003/bin/chromium.launcher is /bin/sh
  cat << "EOF" > $HOME/.chromium-browser.init
#!/bin/sh
eval "$(run-parts --list -- /etc/chromium.d | xargs cat)"
EOF
fi

#detect if dark mode is currently enabled by this tool
if [ -f "${folder}/dark_mode" ];then
  dark_mode=TRUE
else
  dark_mode=FALSE
fi

#detect if dark mode for all websites is currently enabled by this tool
if [ -f "${folder}/site_dark_mode"  ];then
  site_dark_mode=TRUE
else
  site_dark_mode=FALSE
fi

#detect current UI scale value
if [ -f "${folder}/ui_scale" ];then
  ui_scale="$(cat "${folder}/ui_scale" | grep -o '\--force-device-scale-factor=.*' | tr -cd '0123456789.\n')"
else
  ui_scale=1.00
fi

#detect if google sync is currently enabled by this tool
if [ -f "${folder}/apikeys" ];then
  google_sync=TRUE
else
  google_sync=FALSE
fi

#detect if tab previews is currently enabled by this tool
if [ -f "${folder}/tab_previews" ];then
  tab_previews=TRUE
else
  tab_previews=FALSE
fi

#detect if various performance improvements are currently enabled by this tool
if [ -f "${folder}/performance_improvements" ];then
  performance_improvements=TRUE
else
  performance_improvements=FALSE
fi

#detect if the reduce_writes script is enabled
if [ -f "${folder}/reduce_writes" ];then
  reduce_writes=TRUE
else
  reduce_writes=FALSE
fi

#detect if Widevine is enabled
if [ -d /opt/WidevineCdm ];then
  widevine=TRUE
else
  widevine=FALSE
fi
#detect if Widevine can be enabled
if [ $arch == 32 ];then
  widevine_possible=TRUE
  widevine_message=(--field="Enable Widevine DRM (for Netflix, Spotify)":CHK "$widevine")
else
  widevine_possible=FALSE
  widevine_message=()
fi

#Set text of dialog window
text="<b>Better Chromium</b> - by Botspot"

#detect if chromium is running, and if so, remind the user to relaunch it when done
if pgrep chromium >/dev/null || pgrep chromium-browser >/dev/null ;then
  text+=$'\n'"Changes will take effect after you relaunch Chromium."
fi

output="$(yad --center --form --width=410 --separator='\n' \
  --title="Better Chromium" \
  --window-icon="$(dirname "$0")/icon-64.png" \
  --text="$text" \
  --field="Enable Dark Mode":CHK "$dark_mode" \
  --field="Dark Mode for all websites":CHK "$site_dark_mode" \
  --field="<a href="\""https://chrome.google.com/webstore/search/neon%20kingdom%20-tabs?_category=themes"\"">Click to see more themes</a>:LBL" '' \
  --field="UI Scale: (default 1)":NUM "${ui_scale}!0.25..4!0.05!2" \
  --field="Tab previews":CHK "$tab_previews" \
  --field="Enable Google Sync":CHK "$google_sync" \
  --field="Performance Improvements":CHK "$performance_improvements" \
  --field="Reduce SD card writes":CHK "$reduce_writes" \
  "${widevine_message[@]}")"

button=$?
if [ "$button" != 0 ];then
  echo "User error: Exiting now without making any changes."
  exit 1
fi

echo "Received values:"
dark_mode="$(sed -n 1p <<<"$output")"
echo "dark_mode: $dark_mode"
site_dark_mode="$(sed -n 2p <<<"$output")"
echo "site_dark_mode: $site_dark_mode"
#skip line 3 because that was an empty field from "Click to see more themes" links
ui_scale="$(sed -n 4p <<<"$output")"
echo "ui_scale: $ui_scale"
tab_previews="$(sed -n 5p <<<"$output")"
echo "tab_previews: $tab_previews"
google_sync="$(sed -n 6p <<<"$output")"
echo "google_sync: $google_sync"
performance_improvements="$(sed -n 7p <<<"$output")"
echo "performance_improvements: $performance_improvements"
reduce_writes="$(sed -n 8p <<<"$output")"
echo "reduce_writes: $reduce_writes"
widevine="$(sed -n 9p <<<"$output")"
echo "widevine: $widevine"
echo

#if user enabled reduce_writes or performance_improvements, and ZRAM is not installed, then recommend the More RAM app
if [ ! -f /usr/bin/zram.sh ] && [ "$performance_improvements" == TRUE ] ;then
  
  yad --center --width=410 --separator='\n' \
  --title="Better Chromium" \
  --window-icon="$(dirname "$0")/icon-64.png" \
  --text="You've chosen to improve Chromium's performance by adding a few flags to it. Further improvement is possible by installing the <b>More RAM</b> app on Pi-Apps. This increases usable RAM while avoiding a swap file." \
  --button="Thanks for the tip - I'll check out <b>More RAM</b>.":0 &>/dev/null &
elif [ ! -f /usr/bin/zram.sh ] && [ "$reduce_writes" == TRUE ] ;then
  
  yad --center --width=410 --separator='\n' \
  --title="Better Chromium" \
  --window-icon="$(dirname "$0")/icon-64.png" \
  --text="You've chosen to reduce writes to the SD card. Further improvement is possible by installing the <b>More RAM</b> app on Pi-Apps. This increases usable RAM while avoiding a swap file." \
  --button="Thanks for the tip - I'll check out <b>More RAM</b>.":0 &>/dev/null &
fi

#
#write changes to chromium flag folder
#
status "Writing changes..."
#add zzzz_combine_values script in all cases to combine --enable-features arguments
echo "Creating workaround script at ${folder}/zzzz_combine_values"
cat << "EOF" | sudo tee "${folder}/zzzz_combine_values" >/dev/null
#This script combines multiple invocations of --enable-features and --disable-features into one argument so that Chromium does not ignore any.
#Written by Botspot for the Pi-Apps Better Chromium script.

IFS=' '
enable=''
disable=''
new_flags=''
for word in $CHROMIUM_FLAGS ;do
  if [[ "$word" == '--enable-features='* ]];then
    enable+=",${word/--enable-features=/}"
  elif [[ "$word" == '--disable-features='* ]];then
    enable+=",${word/--disable-features=/}"
  else
    new_flags+=" $word"
  fi
done

#remove initial comma
enable="${enable/,/}"
disable="${disable/,/}"

CHROMIUM_FLAGS="$new_flags"
[ ! -z "$enable" ] && CHROMIUM_FLAGS+=" --enable-features=$enable"
[ ! -z "$disable" ] && CHROMIUM_FLAGS+=" --disable-features=$disable"
EOF

#dark mode
if [ "$dark_mode" == TRUE ];then
  #I found this flag on https://peter.sh/experiments/chromium-command-line-switches
  echo "Adding --force-dark-mode to ${folder}/dark_mode"
  
  cat << EOF | sudo tee "${folder}/dark_mode" >/dev/null
export CHROMIUM_FLAGS="\$CHROMIUM_FLAGS --force-dark-mode"
EOF
else
  #dark mode set to false - so remove the file
  if [ -f "${folder}/dark_mode" ];then
    status "Removing ${folder}/dark_mode"
  fi
  sudo rm -f "${folder}/dark_mode"
fi

#dark mode for all websites
if [ "$site_dark_mode" == TRUE ];then
  #I found this flag on https://peter.sh/experiments/chromium-command-line-switches
  echo "Adding --enable-features=WebContentsForceDark:inversion_method/cielab_based/image_behavior/none/foreground_lightness_threshold/150/background_lightness_threshold/150 to ${folder}/site_dark_mode"
  
  cat << EOF | sudo tee "${folder}/site_dark_mode" >/dev/null
export CHROMIUM_FLAGS="\$CHROMIUM_FLAGS --enable-features=WebContentsForceDark:inversion_method/cielab_based/image_behavior/none/foreground_lightness_threshold/150/background_lightness_threshold/150" #WebContentsForceDark:increase_text_contrast/true"
EOF
else
  #dark mode set to false - so remove the file
  if [ -f "${folder}/site_dark_mode" ];then
    status "Removing ${folder}/site_dark_mode"
  fi
  sudo rm -f "${folder}/site_dark_mode"
fi

#UI scale
if [ "$ui_scale" != 1.00 ];then
  #I found this flag on https://peter.sh/experiments/chromium-command-line-switches
  echo "Adding --device-scale-factor=${ui_scale} to ${folder}/ui_scale"
  
  cat << EOF | sudo tee "${folder}/ui_scale" >/dev/null
export CHROMIUM_FLAGS="\$CHROMIUM_FLAGS --force-device-scale-factor=${ui_scale}"
EOF
else
  #ui scale set to 1.00 (default), so remove file
  if [ -f "${folder}/ui_scale" ];then
    status "Removing ${folder}/ui_scale"
  fi
  sudo rm -f "${folder}/ui_scale"
fi

#Tab previews
if [ "$tab_previews" == TRUE ];then
  #I found this flag after experimenting with chrome://flags and chrome://version
  echo "Adding --enable-features=TabHoverCardImages to ${folder}/tab_previews"
  
  cat << EOF | sudo tee "${folder}/tab_previews" >/dev/null
export CHROMIUM_FLAGS="\$CHROMIUM_FLAGS --enable-features=TabHoverCardImages"
EOF
else
  #tab previews set to false - so remove the file
  if [ -f "${folder}/tab_previews" ];then
    status "Removing ${folder}/tab_previews"
  fi
  sudo rm -f "${folder}/tab_previews"
fi

#google_sync
if [ "$google_sync" == TRUE ];then
  #add a file from official Debian version of the chromium package
  echo "Adding GOOGLE_API_KEY, GOOGLE_DEFAULT_CLIENT_ID, and GOOGLE_DEFAULT_CLIENT_SECRET to ${folder}/apikeys"
  
  cat << EOF | sudo tee "${folder}/apikeys" >/dev/null
# API keys found in chromium source code https://chromium.googlesource.com/experimental/chromium/src/+/b08bf82b0df37d15a822b478e23ce633616ed959/google_apis/google_api_keys.cc

export GOOGLE_API_KEY="AIzaSyCkfPOPZXDKNn8hhgu3JrA62wIgC93d44k"
export GOOGLE_DEFAULT_CLIENT_ID="77185425430.apps.googleusercontent.com"
export GOOGLE_DEFAULT_CLIENT_SECRET="OTJgUOQcT7lO7GsGZq2G4IlT"
EOF
  echo "Adding ${folder}/enable_sync script to enable sync settings when Chromium launches"
  cat << "EOF" | sudo tee "${folder}/enable_sync" >/dev/null
#!/bin/bash

profiles="$(find "$HOME/.config/chromium/" -maxdepth 1 -type d '(' -name Default -o -name 'Profile *' ')' | sed 's+.*/++g')"
IFS=$'\n'
for profile in $profiles ;do
  [ ! -f "$HOME/.config/chromium/$profile/Preferences" ] && continue
  sed -i 's/"signin":{"allowed":false}/"signin":{"allowed":true,"allowed_on_next_startup":true}/g' "$HOME/.config/chromium/$profile/Preferences"
  sed -i 's/"signin":{"allowed":false,"allowed_on_next_startup":false}/"signin":{"allowed":true,"allowed_on_next_startup":true}/g' "$HOME/.config/chromium/$profile/Preferences"
  sed -i 's/"signin":{"AccountReconcilor":{"kDiceMigrationOnStartup2":true},"allowed":false,"allowed_on_next_startup":false}/"signin":{"AccountReconcilor":{"kDiceMigrationOnStartup2":true},"allowed":true,"allowed_on_next_startup":true}/g' "$HOME/.config/chromium/$profile/Preferences"
done
EOF
else
  #google sync set to false, so remove the file
  if [ -f "${folder}/apikeys" ];then
    status "Removing ${folder}/apikeys"
  fi
  #remove the script that enables sync setting
  if [ -f "${folder}/enable_sync" ];then
    status "Removing ${folder}/enable_sync"
  fi
  
  status "Disabling sync settings for all chromium profiles"
  #turn off sync setting for every profile
  profiles="$(find "$HOME/.config/chromium/" -maxdepth 1 -type d '(' -name Default -o -name 'Profile *' ')' | sed 's+.*/++g')"
  IFS=$'\n'
  for profile in $profiles ;do
    [ ! -f "$HOME/.config/chromium/$profile/Preferences" ] && continue
    sed -i 's/"signin":{"allowed":true}/"signin":{"allowed":false,"allowed_on_next_startup":false}/g' "$HOME/.config/chromium/$profile/Preferences"
    sed -i 's/"signin":{"allowed":true,"allowed_on_next_startup":true}/"signin":{"allowed":false,"allowed_on_next_startup":false}/g' "$HOME/.config/chromium/$profile/Preferences"
    sed -i 's/"signin":{"AccountReconcilor":{"kDiceMigrationOnStartup2":true},"allowed":true,"allowed_on_next_startup":true}/"signin":{"AccountReconcilor":{"kDiceMigrationOnStartup2":true},"allowed":false,"allowed_on_next_startup":false}/g' "$HOME/.config/chromium/$profile/Preferences"
  done
  sudo rm -f "${folder}/apikeys" "${folder}/enable_sync"
fi

#performance improvements
if [ "$performance_improvements" == TRUE ];then
  #various chromium flags from https://forums.raspberrypi.com/viewtopic.php?t=199543 - I removed a few because they reduced stability or WebGL performance
  #More flags added from https://www.ghacks.net/2017/02/13/how-to-speed-up-the-vivaldi-web-browser/
  #Some VA-API flags from https://ubuntuhandbook.org/index.php/2022/07/chromium-snap-package-to-finally-get-back-vaapi-hardware-decoding/
  
  flags="--ignore-gpu-blacklist --enable-checker-imaging --cc-scroll-animation-duration-in-seconds=0.6 --disable-quic --enable-tcp-fast-open --enable-experimental-canvas-features --enable-scroll-prediction --enable-simple-cache-backend --max-tiles-for-interest-area=512 --num-raster-threads=4 --default-tile-height=512 --enable-features=VaapiVideoDecoder,VaapiVideoEncoder --disable-features=UseChromeOSDirectVideoDecoder --enable-accelerated-video-decode --enable-low-res-tiling --process-per-site"
  #The --process-per-site flag significantly decreases RAM usage and number of chromium processes, without any noticeable disadvantages.
  #Not using --enable-low-end-device-mode even though it helps, because scrolling image-heavy pages would crash with "background allocation failure" error.
  
  echo "Adding $flags to ${folder}/performance_improvements"
  cat << EOF | sudo tee "${folder}/performance_improvements" >/dev/null
export CHROMIUM_FLAGS="\$CHROMIUM_FLAGS $flags"
EOF
else
  #performance improvements set to false, so remove file
  if [ -f "${folder}/performance_improvements" ];then
    status "Removing ${folder}/performance_improvements"
  fi
  sudo rm -f "${folder}/performance_improvements"
fi

#reduce sd card writes
if [ "$reduce_writes" == TRUE ];then
  #mount chromium files to tmpfs (script will run with user's privileges whenever Chromium is launched)
  #From: https://forums.raspberrypi.com/viewtopic.php?p=1865820
  echo "Adding ${folder}/reduce_writes script to mount cache/ServiceWorker to /dev/shm when Chromium launches"
  cat << "EOF" | sudo tee "${folder}/reduce_writes" >/dev/null
#!/bin/bash

if [ ! -d /dev/shm ];then
  echo 'Better chromium "Reduce Writes" script: cannot mount folders to /dev/shm because that folder is missing!'
else
  rm -rf /dev/shm/chromium
  mkdir -p /dev/shm/chromium
  
  profiles="$(find "$HOME/.config/chromium/" -maxdepth 1 -type d '(' -name Default -o -name 'Profile *' ')' | sed 's+.*/++g')"
  IFS=$'\n'
  for profile in $profiles ;do
  
    rm -rf "$HOME/.config/chromium/$profile/Service Worker"
    mkdir -p "/dev/shm/chromium/$profile/serviceWorker"
    ln -s "/dev/shm/chromium/$profile/serviceWorker" "$HOME/.config/chromium/$profile/Service Worker"
  done
  
  mkdir -p /dev/shm/chromium/cache
  rm -rf "$HOME/.cache/chromium"
  ln -s /dev/shm/chromium/cache/ "$HOME/.cache/chromium"
fi
EOF
else
  if [ -f "${folder}/reduce_writes" ];then
    status "Removing ${folder}/reduce_writes"
  fi
  sudo rm -f "${folder}/reduce_writes"
  
  #clean up old symlinks
  profiles="$(find "$HOME/.config/chromium/" -maxdepth 1 -type d '(' -name Default -o -name 'Profile *' ')' | sed 's+.*/++g')"
  IFS=$'\n'
  for profile in $profiles ;do
    if [ -L "$HOME/.config/chromium/$profile/Service Worker" ];then
      rm -rf "$HOME/.config/chromium/$profile/Service Worker"
    fi
  done
  if [ -L "$HOME/.cache/chromium" ];then
    rm -rf "$HOME/.cache/chromium"
  fi
fi

#widevine
if [ "$widevine_possible" == TRUE ] && [ "$widevine" == TRUE ] && [ ! -d /opt/WidevineCdm ];then
  #install Chromium Widevine app
  "${DIRECTORY}/manage" install "Chromium Widevine"
  
elif [ "$widevine_possible" == TRUE ] && [ "$widevine" == FALSE ];then
  #disable Chromium Widevine
  if package_installed libwidevinecdm0 ;then
    sudo apt purge -y libwidevinecdm0
  fi
  
  if [ -d /opt/WidevineCdm ];then
    #uninstall Chromium Widevine app
    "${DIRECTORY}/manage" uninstall "Chromium Widevine"
  fi
fi

if pgrep chromium >/dev/null || pgrep chromium-browser >/dev/null ;then
  status "Changes will take effect after you relaunch Chromium."
fi
true
