#!/bin/bash
#
# Interactive control for the PingPlotter macOS background service.
# Shows status and offers start / stop / restart / install / uninstall / wipe.
# With a verb argument, runs that one action without the menu or prompts:
#   service-command status|start|stop|restart|install|uninstall|wipe
#
# The TCP traceroute helper is a separate, app-installed daemon; only uninstall
# and wipe touch it (its plist is generated by the app, so this can't install it).

set -u

LABEL="com.pingman.pingplotter.mac"
PLIST="/Library/LaunchDaemons/com.pingman.pingplotter.mac_service.plist"
DATA_DIR="/Library/Application Support/PingPlotter"

TCP_LABEL="com.pingman.pingplotter.tcp-traceroute"
TCP_PLIST="/Library/LaunchDaemons/com.pingman.pingplotter.tcp-traceroute.plist"

APP="/Applications/PingPlotter.app"
APP_EXE="$APP/Contents/MacOS/PingPlotter"

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"

# Run elevated once up front so no action needs its own sudo prompt
if [ "$(id -u)" -ne 0 ]; then
    exec sudo "$0" "$@"
fi

is_quarantined() {
    xattr -p com.apple.quarantine "$1" >/dev/null 2>&1
}

quarantine_state() {
    if [ ! -e "$1" ]; then
        echo "n/a"
    elif is_quarantined "$1"; then
        echo "yes"
    else
        echo "no"
    fi
}

confirm() {
    local reply
    read -r -p "$1 [y/N] " reply </dev/tty
    [[ "$reply" == [yY]* ]]
}

print_status() {
    echo "=== PingPlotter service ==="

    if [ -f "$PLIST" ]; then
        echo "Installed:  yes"
    else
        echo "Installed:  no"
    fi

    local info
    if info="$(launchctl print "system/$LABEL" 2>/dev/null)"; then
        local pid
        pid="$(echo "$info" | awk -F'= ' '/^\t*pid = /{print $2; exit}')"
        if [ -n "$pid" ]; then
            echo "State:      running (pid $pid)"
        else
            echo "State:      loaded, not running"
        fi
    else
        echo "State:      not loaded"
    fi

    if launchctl print-disabled system 2>/dev/null | grep -q "\"$LABEL\" => \(disabled\|true\)"; then
        echo "Disabled:   yes (start will re-enable)"
    fi

    echo "Quarantine: app $(quarantine_state "$APP_EXE"), plist $(quarantine_state "$PLIST")"
    [ -f "$TCP_PLIST" ] && echo "TCP helper: installed"
    echo
}

do_start() {
    # launchd refuses a quarantined plist or program with a bare I/O error
    if is_quarantined "$PLIST"; then
        xattr -d com.apple.quarantine "$PLIST"
    fi
    if is_quarantined "$APP_EXE"; then
        xattr -d -r -s com.apple.quarantine "$APP" 2>/dev/null
        if is_quarantined "$APP_EXE"; then
            echo "Couldn't clear quarantine on PingPlotter.app (macOS App Management blocks Terminal). If the service won't start, use Restart Service from PingPlotter's menu, or allow Terminal under System Settings > Privacy & Security > App Management." >&2
        fi
    fi
    # enable clears a persisted "disabled" override (e.g. from a prior stop/uninstall)
    launchctl enable "system/$LABEL"
    launchctl bootstrap system "$PLIST"
}

do_stop() {
    launchctl bootout "system/$LABEL"
}

do_restart() {
    launchctl bootout "system/$LABEL" 2>/dev/null || true
    do_start
}

do_install() {
    local src="$SCRIPT_DIR/$(basename "$PLIST")"
    if [ ! -f "$src" ]; then
        echo "Cannot find the service plist next to this script ($src)." >&2
        return 1
    fi
    launchctl bootout "system/$LABEL" 2>/dev/null || true
    cp -f "$src" "$PLIST"
    chown root:wheel "$PLIST"
    chmod 644 "$PLIST"
    do_start && echo "Service installed."
}

do_uninstall() {
    launchctl bootout "system/$LABEL" 2>/dev/null || true
    rm -f "$PLIST"
    launchctl bootout "system/$TCP_LABEL" 2>/dev/null || true
    rm -f "$TCP_PLIST"
    echo "Service uninstalled. Data kept."
}

do_wipe() {
    do_uninstall
    rm -rf "$DATA_DIR"
    rm -rf /var/run/pingplotter /var/log/pingplotter
    echo "Service and all data removed."
}

if [ $# -gt 0 ]; then
    case "$1" in
        status) print_status ;;
        start|stop|restart|install|uninstall|wipe) "do_$1" ;;
        *)
            echo "Usage: $(basename "$0") [status|start|stop|restart|install|uninstall|wipe]" >&2
            exit 2
            ;;
    esac
    exit $?
fi

while true; do
    echo
    print_status
    echo "  1) Start"
    echo "  2) Stop"
    echo "  3) Restart"
    echo "  4) Install"
    echo "  5) Uninstall (keep data)"
    echo "  6) Remove all data (uninstall + wipe settings/data)"
    echo "  q) Quit"
    read -r -p "Choose: " choice </dev/tty

    case "$choice" in
        1) do_start ;;
        2) do_stop ;;
        3) do_restart ;;
        4) do_install ;;
        5) confirm "Uninstall the service (data kept)?" && do_uninstall ;;
        6) confirm "Remove the service AND all data/settings? This cannot be undone." && do_wipe ;;
        q|Q) exit 0 ;;
        *) echo "Not a valid choice." ;;
    esac
done
