#!/bin/bash

set -euo pipefail

# PackageKit overlays payloads without removing paths that disappeared between
# versions. Replace only this product's onedir so stale modules and
# runlayer-<old>.dist-info cannot survive an upgrade or rollback.
TARGET_VOLUME="${3:?missing installer target volume}"
AIWATCH_BUNDLE="${TARGET_VOLUME%/}/usr/local/lib/runlayer/aiwatch"

rm -rf "$AIWATCH_BUNDLE"

# Retire the script-based Detect rollout that predates this package: a per-user
# com.runlayer.scan LaunchAgent plus an ad-hoc signed wrapper. Both scan paths
# left in place means every scheduled scan runs twice. Walk every home so this
# also works at the loginwindow and on shared Macs. Every step is best-effort:
# launchctl failures are expected (no GUI session, agent not loaded), and an
# undeletable plist or wrapper (immutable flag, read-only network home) must
# not abort the install under set -e once the old bundle is already gone. The
# uv-installed CLI, its shim, and the stored org key are left for the
# documented cleanup script: a uv-installed runlayer may be the user's own.
retire_legacy_detect_agent() {
    local volume="${TARGET_VOLUME%/}"
    local plist home_dir uid
    for plist in "$volume"/Users/*/Library/LaunchAgents/com.runlayer.scan.plist; do
        [ -e "$plist" ] || continue
        home_dir="${plist%/Library/LaunchAgents/com.runlayer.scan.plist}"
        uid=$(stat -f %u "$home_dir" 2>/dev/null || true)
        case "$uid" in
            ""|0|*[!0-9]*) ;;
            *) launchctl bootout "gui/${uid}/com.runlayer.scan" 2>/dev/null || true ;;
        esac
        rm -f "$plist" 2>/dev/null || true
    done
}

# Bound the sweep. The glob stats into every home, and a home on an
# unreachable network mount can block that stat in the kernel; the installer
# has no timeout of its own, so an unbounded sweep could wedge an install or
# a self-update. Run it detached with stdio closed (a lingering child must
# not hold the installer's pipes open), poll for about ten seconds, then
# move on. The aiwatch_uninstall child timeout exists for the same reason.
# The wrapper is on the local volume and cannot hang, and removing it alone
# stops the legacy agent from scanning, so it goes first and in the foreground:
# a Mac whose home walk is cut short below still loses the wrapper.
rm -f "${TARGET_VOLUME%/}/usr/local/bin/runlayer-scan" 2>/dev/null || true
retire_legacy_detect_agent </dev/null >/dev/null 2>&1 &
SWEEP_PID=$!
SWEEP_TICKS=0
while [ "$SWEEP_TICKS" -lt 100 ] && kill -0 "$SWEEP_PID" 2>/dev/null; do
    sleep 0.1
    SWEEP_TICKS=$((SWEEP_TICKS + 1))
done
if kill -0 "$SWEEP_PID" 2>/dev/null; then
    kill "$SWEEP_PID" 2>/dev/null || true
else
    wait "$SWEEP_PID" 2>/dev/null || true
fi
