#! /bin/sh

if [ -z "$1" ]; then
  printf "%s\n" "Usage: app-cleaner.sh /path/to/app.app"
  exit 1
fi

IFS=$'\n'

red=$'\e[1;31m'
nc=$'\e[0m'

if [ ! -e "$1/Contents/Info.plist" ]; then
  printf "%s\n" "Cannot find app plist"
  exit 1
fi

bundle_identifier=$(/usr/libexec/PlistBuddy -c "Print CFBundleIdentifier" "$1/Contents/Info.plist" 2> /dev/null)

if [ "$bundle_identifier" = "" ]; then
  printf "%s\n" "Cannot find app bundle identifier"
  exit 1
fi

printf "%s\n" "Checking for running processes..."
sleep 1

app_name=$(basename $1 .app)

processes=($(pgrep -afil "$app_name" | grep -v "app-cleaner.sh"))

if [ ${#processes[@]} -gt 0 ]; then
  printf "%s\n" "${processes[@]}"
  printf "${red}%s${nc}" "Kill running processes (y or n)? "
  read -r answer
  if [ "$answer" = "y" ]; then
    printf "%s\n" "Killing running processes..."
    sleep 1
    for process in "${processes[@]}"; do
      echo $process | awk '{print $1}' | xargs kill
    done
  fi
fi

home_dir=~

paths=()

paths+=($(find /private/var/db/receipts -iname "*$app_name*.bom" -maxdepth 1 -prune 2>&1 | grep -av "Permission denied"))
paths+=($(find /private/var/db/receipts -iname "*$bundle_identifier*.bom" -maxdepth 1 -prune 2>&1 | grep -av "Permission denied"))

if [ ${#paths[@]} -gt 0 ]; then
  printf "%s\n" "Saving bill of material logs to desktop..."
  sleep 1
  for path in "${paths[@]}"; do
    mkdir -p "$home_dir/Desktop/$app_name"
    lsbom -f -l -s -p f $path > "$home_dir/Desktop/$app_name/$(basename $path).log"
  done
fi

printf "%s\n" "Finding app data..."
sleep 1

locations=(
  "$home_dir/Library"
  "$home_dir/Library/Application Support"
  "$home_dir/Library/Application Support/CrashReporter"
  "$home_dir/Library/Containers"
  "$home_dir/Library/Caches"
  "$home_dir/Library/Group Containers"
  "$home_dir/Library/Internet Plug-Ins"
  "$home_dir/Library/LaunchAgents"
  "$home_dir/Library/Logs"
  "$home_dir/Library/Preferences"
  "$home_dir/Library/Saved Application State"
  "$home_dir/Library/WebKit"
  "/Library"
  "/Library/Application Support"
  "/Library/Application Support/CrashReporter"
  "/Library/Caches"
  "/Library/Extensions"
  "/Library/Internet Plug-Ins"
  "/Library/LaunchAgents"
  "/Library/LaunchDaemons"
  "/Library/Logs"
  "/Library/Preferences"
  "/private/var/db/receipts"
  "/usr/local/bin"
  "/usr/local/etc"
  "/usr/local/opt"
  "/usr/local/sbin"
  "/usr/local/share"
  "/usr/local/var"
)

paths=($1)

for location in "${locations[@]}"; do
  paths+=($(find "$location" -iname "*$app_name*" -maxdepth 1 -prune 2>&1 | grep -av "No such file or directory" | grep -av "Permission denied"))
done

for location in "${locations[@]}"; do
  paths+=($(find "$location" -iname "*$bundle_identifier*" -maxdepth 1 -prune 2>&1 | grep -av "No such file or directory" | grep -av "Permission denied"))
done

paths=($(printf "%s\n" "${paths[@]}" | sort -u));

printf "%s\n" "${paths[@]}"

printf "${red}%s${nc}" "Move app data to trash (y or n)? "
read -r answer
if [ "$answer" = "y" ]; then
  printf "%s\n" "Moving app data to trash..."
  sleep 1
  for path in "${paths[@]}"; do
    osascript -e "tell application \"Finder\" to delete POSIX file \"$path\"" > /dev/null
  done
  printf "%s\n" "Done"
fi