#!/bin/bash

function removePathIfExists {
    local description=$1
    local path=$2
    local user=$3
    local skipCheck=$4

    if test -z "${skipCheck}"; then
        /bin/echo Checking "${description}" path "${path}"
        exists "${path}" "${user}"
    fi
    if test $? -eq 1 -o -n "${skipCheck}"; then
        /bin/echo Removing "${description}"
        execute /usr/bin/sudo -u "${user}" -- /bin/rm -rvf "${path}"
    else
        /bin/echo Nothing found
    fi
}

function removeJobIfExists {
    local description=$1
    local plist=$2
    if test -f "${plist}"; then
        /bin/echo Unloading "$description"
        execute /usr/bin/sudo /bin/launchctl unload "${plist}"
        /bin/echo Deleting "$description" job definition
        execute /usr/bin/sudo -- rm -vf "${plist}"
    fi
}

function execute {
    /bin/echo -n  [3m
    if (( dry_run == 1 )); then
        /bin/echo \[DRYRUN\] "$@"
    else
        "$@"
    fi
    /bin/echo -n  [0m
}

function removePrefsIfExists {
    local app=$1
    local app_id=$2
    local user=$3
    local home=$4

    /usr/bin/sudo -u "${user}" -- /usr/bin/defaults read "${app_id}" >/dev/null 2>/dev/null
    if test $? -eq 0; then
        /bin/echo Found "${app}" preferences for user "${user}"
        /bin/echo Deleting "${app}" preferences
        execute /usr/bin/sudo -u "${user}" -- /usr/bin/defaults delete "${app_id}"
        execute /usr/bin/sudo -u "${user}" -- /bin/rm -v "${home}/Library/Preferences/${app_id}.plist"
    fi
}

function exists {
    local path=$1
    local user=$2
    if test -z "${user}"; then
        user="root"
    fi

    local dir
    dir=$(/usr/bin/dirname "${path}")
    if test -z "$dir"; then
        dir="."
    fi
    local file
    file=$(/usr/bin/basename "${path}")
    matches=$( /usr/bin/sudo -u "${user}" -- /usr/bin/find "${dir}" -maxdepth 1 -name "$file" -print | wc -l )
    if test "${matches}" -gt 0; then
        return 1
    else
        return 0
    fi
}

function processUser {
    local user=$1

    local home
    home=$(/usr/bin/dscl localonly -read "/Local/Default/Users/${user}" NFSHomeDirectory \
            | /usr/bin/sed 's/^NFSHomeDirectory: //')

    /bin/echo [1mProcessing user "${user}[0m"

    if (( remove_logs == 1 )); then
        removePathIfExists "user logs" "${home}/Library/Logs/${APP}/" "${user}"
    fi

    if (( remove_prefs == 1 )); then
        removePrefsIfExists "${APP}" "${BUNDLE_ID}" "${user}" "$home"
        removePathIfExists "${APP} Shared Preferences" "${home}/Library/Preferences/${BUNDLE_ID}.shared.plist" "${user}"
        removePrefsIfExists "QuickLaunch" "com.soma-zone.QuickLaunch" "${user}" "$home"
        removePrefsIfExists "JobWatch" "com.soma-zone.JobWatch" "${user}" "$home"
    fi

    if (( remove_templates == 1 )); then
        removePathIfExists "Templates" "${home}/Library/Application Support/${APP}" "${user}"
    fi

    removePathIfExists "Saved Application State" "${home}/Library/Saved Application State/${BUNDLE_ID}.savedState" "${user}"
    removePathIfExists "Help Viewer data" "${home}/Library/Containers/com.apple.helpviewer/Data/${BUNDLE_ID}.*" "${user}"
    removePathIfExists "HTTP Storage" "${home}/Library/HTTPStorages/${BUNDLE_ID}" "${user}"
    removePathIfExists "Application Scripts" "${home}/Library/Application Scripts/${BUNDLE_ID}" "${user}"
    removePathIfExists "Cache" "${home}/Library/Caches/${BUNDLE_ID}" "${user}"
    removePathIfExists "WebKit Caches" "${home}/Library/WebKit/${BUNDLE_ID}" "${user}"
    sudo -u "${user}" -- find "${home}/Library/Application Support/CrashReporter" -name 'LaunchControl_*' -delete
    sudo -u "${user}" -- find "${home}/Library/Application Support/CrashReporter" -name 'QuickLaunch_*' -delete
    sudo -u "${user}" -- find "${home}/Library/Application Support/CrashReporter" -name 'JobWatch_*' -delete
}

function usage {
    echo "$0 --all"
    echo "$0 [--remove-prefs] [--remove-group] [--remove-logs] [--remove-caches] [--remove-monitor]"
}

function eval_setting {
    local name=$1
    local val=$2

    /bin/echo -n "    $name: "
    if (( val == 0 )); then
        /bin/echo "no"
    else
        /bin/echo "yes"
    fi
}

function init {
    APP="LaunchControl"
    BUNDLE_ID="com.soma-zone.${APP}"

    dry_run=0
    if (( $# == 0 )); then
        remove_templates=1
        remove_prefs=1
        remove_logs=1
        remove_helper=1
        remove_app=1
    else
        remove_templates=0
        remove_prefs=0
        remove_logs=0
        remove_helper=0
        remove_app=0
    fi
    for arg in "$@"; do
        if test "$arg" == "--all"; then
            remove_templates=1
            remove_prefs=1
            remove_logs=1
            remove_app=1
            remove_helper=1
        elif test "$arg" == "--remove-templates"; then
            remove_templates=1
        elif test "$arg" == "--keep-templates"; then
            remove_templates=0
        elif test "$arg" == "--remove-prefs"; then
            remove_prefs=1
        elif test "$arg" == "--keep-prefs"; then
            remove_prefs=0
        elif test "$arg" == "--remove-logs"; then
            remove_logs=1
        elif test "$arg" == "--remove-helper"; then
            remove_helper=1
        elif test "$arg" == "--remove-app"; then
            remove_app=1
        elif test "$arg" == "--keep-app"; then
            remove_app=0
        elif test "$arg" == "--dry-run"; then
            dry_run=1
        elif test "$arg" == "--help" -o "$arg" == "-h"; then
            usage
            exit 0
        elif test "${arg:0:1}" == "-"; then
            echo "Unknown option: $arg"
            usage
            exit 1
        else
            echo "Invalid argument: $arg"
            usage
            exit 1
        fi
    done
}

init "$@"

/bin/echo "This script will remove the following components of ${APP} from your system:"
eval_setting "Templates" "$remove_templates"
eval_setting "Settings" "$remove_prefs"
eval_setting "Logs" "$remove_logs"
eval_setting "Helper" "$remove_helper"
eval_setting "Application" "$remove_app"
/bin/echo
/bin/echo -n "Do you want to continue? (yes/NO): "
read -r reply
if test "${reply}" != "yes"; then
    echo Script aborted.
    exit 0
fi

/usr/bin/sudo -p "The uninstaller requires root privileges. Please enter your password: " -v
if test $? -ne 0; then
    exit 1
fi

/bin/echo "Open ${APP} and open the Utilities tab af the ${APP} settings."
/bin/echo "Disable/uninstall fdautil, QuickLaunch and JobWatch."
/bin/echo -n "Enter \"done\" when ready: "
read -r reply
if test "${reply}" != "done"; then
    exit 0
fi

/bin/echo "Remove fdautil from the list of applications with Full Disk Access."
/bin/echo -n "Press enter to open the Full Disk Access System Settings: "
read -r reply
/usr/bin/open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"

/bin/echo -n "Enter \"done\" when Full Disk Access has been disabled: "
read -r reply
if test "${reply}" != "done"; then
    exit 0
fi

/usr/bin/dscl localonly -list /Local/Default/Users \
        | grep -v -e '^_' -e '^Guest$' -e '^daemon$' -e '^root$' -e '^nobody$' \
        | while read -r user; do
    processUser "${user}"
done

/bin/echo [1mProcessing global files[0m

if test -e "/usr/local/bin/fdautil"; then
    /bin/echo Removing /usr/local/bin/fdautil
    execute /usr/bin/sudo /bin/rm "/usr/local/bin/fdautil"
fi
removePathIfExists "fdautil config" "/Library/Preferences/com.soma-zone.LaunchControl.fdautil.plist" "root"
sudo -- find "/Library/Application Support/CrashReporter" -name 'LaunchControl_*' -delete

if (( remove_logs == 1 )); then
    globalLogs="/Library/Logs/${APP}"
    removePathIfExists "global logs" "${globalLogs}" "root"
fi

if (( remove_helper == 1 )); then
    removeJobIfExists "Privileged Helper" "/Library/LaunchDaemons/${BUNDLE_ID}.plist"
    removePathIfExists "Privileged Helper Tool" "/Library/PrivilegedHelperTools/${BUNDLE_ID}.Helper" "root"
fi

if (( remove_app == 1 )); then
    /bin/echo "Looking for ${APP} application bundles"
    IFS=$'\n'; for app in $(/usr/bin/mdfind "kMDItemCFBundleIdentifier == '${BUNDLE_ID}'"); do
        version=$(/usr/libexec/PlistBuddy -c 'Print CFBundleShortVersionString' "${app}/Contents/Info.plist")
        /bin/echo -n "Found ${app} (${version}); Do you want to delete it? (yes/NO): "
        read -r reply
        if test "${reply}" == "yes"; then
            /bin/echo [3m"${app}"[0m
            execute /usr/bin/sudo -- /bin/rm -rf "${app}"
        else
            /bin/echo Skipped
        fi
    done
fi

/bin/echo Uninstall completed.
