#!/bin/bash
# postinstall — runs as root after pkgbuild installs payload.
# launchctl errors are tolerated so installs at the loginwindow (no console
# user) succeed; agents load on next login regardless.

set -euo pipefail

chmod 755 /usr/local/lib/runlayer/aiwatch/aiwatch

# Install-window stamp; see runlayer_cli/install_window.py.
mkdir -p /var/db/com.runlayer.aiwatch
chown root:wheel /var/db/com.runlayer.aiwatch
chmod 755 /var/db/com.runlayer.aiwatch
: > /var/db/com.runlayer.aiwatch/.install-time
chown root:wheel /var/db/com.runlayer.aiwatch/.install-time
chmod 644 /var/db/com.runlayer.aiwatch/.install-time

# On-device version record for MDM inventory — lets MDM read the installed
# version without exec'ing the aiwatch binary (no FDA / TCC prompt):
#   defaults read com.runlayer.aiwatch.version Version
# Dedicated com.runlayer.aiwatch.version domain, isolated from the MDM-owned
# com.runlayer.aiwatch config domain read by mdm_config.py. The absolute path
# form writes the global domain (/Library/Preferences), not root's ~/Library.
# __VERSION__ is templated in by build_pkg.sh; a same/upgrade reinstall re-runs
# postinstall and overwrites. Removed by uninstall.sh.
defaults write /Library/Preferences/com.runlayer.aiwatch.version Version "__VERSION__"
# cfprefsd flushes the plist to disk asynchronously, so the file may not exist
# yet here. Tolerate failure — under set -e a strict chown/chmod on a not-yet-
# flushed plist would abort the whole postinstall (failed install). defaults
# write as root already yields root:wheel, and MDM reads via `defaults read`
# (root) regardless of mode.
chown root:wheel /Library/Preferences/com.runlayer.aiwatch.version.plist 2>/dev/null || true
chmod 644 /Library/Preferences/com.runlayer.aiwatch.version.plist 2>/dev/null || true

AGENT_PLISTS=(
    /Library/LaunchAgents/com.runlayer.aiwatch.plist
    /Library/LaunchAgents/com.runlayer.aiwatch.enroll.plist
    /Library/LaunchAgents/com.runlayer.aiwatch.daemon.plist
)
AGENT_LABELS=(
    com.runlayer.aiwatch
    com.runlayer.aiwatch.enroll
    com.runlayer.aiwatch.daemon
)
DAEMON_PLISTS=(
    /Library/LaunchDaemons/com.runlayer.aiwatch.bootstrap.plist
)
DAEMON_LABELS=(
    com.runlayer.aiwatch.bootstrap
)
UPDATE_DAEMON_PLIST=/Library/LaunchDaemons/com.runlayer.aiwatch.update.plist

# launchd requires root:wheel ownership for plists in /Library/*.
for plist in "${AGENT_PLISTS[@]}" "${DAEMON_PLISTS[@]}" "$UPDATE_DAEMON_PLIST"; do
    chown root:wheel "$plist"
    chmod 644 "$plist"
done

# Bootstrap daemons into system domain (start now + every boot). Idempotent.
for i in "${!DAEMON_LABELS[@]}"; do
    launchctl bootout "system/${DAEMON_LABELS[$i]}" 2>/dev/null || true
    launchctl bootstrap system "${DAEMON_PLISTS[$i]}" 2>/dev/null || true
done

# Bootstrap the updater on first install, but never boot it out here. During a
# self-update this postinstall runs beneath that daemon; unloading it from its
# own package transaction can terminate the parent before installer completes.
# The updater's schedule is stable, so an already-loaded job can keep running.
launchctl bootstrap system "$UPDATE_DAEMON_PLIST" 2>/dev/null || true

# Bootstrap agents into the console user's GUI domain. No-op at loginwindow.
CONSOLE_UID=$(stat -f %u /dev/console 2>/dev/null || echo "")
if [ -n "$CONSOLE_UID" ] && [ "$CONSOLE_UID" != "0" ]; then
    for i in "${!AGENT_LABELS[@]}"; do
        launchctl bootout "gui/${CONSOLE_UID}/${AGENT_LABELS[$i]}" 2>/dev/null || true
        launchctl bootstrap "gui/${CONSOLE_UID}" "${AGENT_PLISTS[$i]}" 2>/dev/null || true
    done
fi

exit 0
