#!/bin/bash
# PrivacyFence.pkg postinstall — provisions privilege separation (#428 D2,
# Phase 4) at install time instead of leaving it to the daemon's own
# admin-password runtime prompt (privilege_separation.maybe_auto_enable_macos(),
# which a drag-installed DMG still depends on because a DMG has no root-context
# install step of its own to run this from). This script IS that root-context
# install step: Apple's installer already verified this package's signature
# before running it and always runs package scripts as root, so by the time
# this runs, "provision the _privacyfence account and hand it the daemon" is
# exactly as safe to do unconditionally as scripts/macos_privilege_separation.sh
# enable --auto already assumes its caller has confirmed.
#
# Must never fail the package install over this: a hiccup here is a reason to
# leave privilege separation opt-in (the daemon's own runtime prompt will offer
# it again once someone is logged in and starts the daemon), never a reason to
# roll back installing the app at all. Every exit path below is therefore
# explicit and this script always exits 0 -- no `set -e`, so one unexpected
# failure can't accidentally take the whole install down with it.
set -uo pipefail

APP_PATH="/Applications/PrivacyFenceApp.app"
SEPARATION_SCRIPT="${APP_PATH}/Contents/Resources/scripts/macos_privilege_separation.sh"

log() { printf 'PrivacyFence postinstall: %s\n' "$*" >&2; }

# Apple's installer runs this as root with no login session of its own --
# $SUDO_USER (what macos_privilege_separation.sh normally reads) is unset here,
# whether this ran from the Installer.app GUI or `sudo installer -pkg ...`.
# The actual human to provision this for is whoever is logged in at the
# console, the same thing `who`/Finder would show -- stat on /dev/console is
# the standard, dependency-free way any macOS installer script resolves that.
CONSOLE_USER="$(/usr/bin/stat -f '%Su' /dev/console 2>/dev/null || true)"

if [ -z "$CONSOLE_USER" ] || [ "$CONSOLE_USER" = "root" ] || [ "$CONSOLE_USER" = "loginwindow" ]; then
  # Nobody is actually logged in at install time (a remote/unattended install,
  # or a package run at the login window) -- there is no human account yet to
  # add to the service group. That used to end this script, leaving the whole
  # install unseparated; ADR 0003 decision 3 splits `enable` so it no longer
  # has to. The machine half below runs regardless and fully separates the
  # install, and the one step that genuinely needs a human -- the group
  # membership -- is recorded as pending, which the companion app closes by
  # itself at the first real login session.
  log "no logged-in console user detected (got '${CONSOLE_USER:-<empty>}') -- provisioning the machine half and leaving the group membership pending."
  CONSOLE_USER=""
fi

if [ ! -x "$SEPARATION_SCRIPT" ]; then
  # Should not happen from a package this script itself ships inside of, but
  # this postinstall's only job is a convenience layered on the opt-in path --
  # never worth failing the install over.
  log "${SEPARATION_SCRIPT} not found or not executable -- leaving privilege separation opt-in."
  exit 0
fi

log "provisioning privilege separation for ${CONSOLE_USER:-this machine} (#428 D2, ADR 0003 decision 3)…"
ENABLE_STATUS=0
if [ -n "$CONSOLE_USER" ]; then
  "$SEPARATION_SCRIPT" enable --auto --user "$CONSOLE_USER" --app "$APP_PATH" || ENABLE_STATUS=$?
else
  "$SEPARATION_SCRIPT" enable --auto --app "$APP_PATH" || ENABLE_STATUS=$?
fi
if [ "$ENABLE_STATUS" -eq 0 ]; then
  if [ -n "$CONSOLE_USER" ]; then
    log "privilege separation enabled -- ${CONSOLE_USER} still needs to log out and back in once before the companion app and MCP client can reach the daemon (macOS only evaluates group membership at login; see 'sudo ${SEPARATION_SCRIPT} status')."
  else
    log "privilege separation enabled -- nobody is in the service group yet; the companion app adds the first account to log in, or run 'sudo ${SEPARATION_SCRIPT} enable --for-user <name>'."
  fi
else
  # enable --auto itself never exits non-zero (it logs and returns 0 on every
  # failure path -- see that script's own --auto handling), so reaching this
  # branch at all means the script couldn't even run to completion. Still not
  # a reason to fail the package install.
  log "automatic privilege-separation enable did not complete -- install continues; run 'sudo ${SEPARATION_SCRIPT} enable' by hand later, or check Console.app / /var/log/install.log for details."
fi

# #428 Phase 2: `enable`'s own internal call to `daemon ensure-running`
# (scripts/macos_privilege_separation.sh's cmd_enable) is what is *supposed*
# to catch a daemon that came up stopped -- the privacyfence/privacyfence#598
# upgrade gap this phase exists to close -- but that call is itself wrapped
# in a subshell precisely so a hiccup in it cannot take the rest of `enable`
# down, which also means its own failure is easy to miss in a log this long.
# Running `daemon ensure-running` a second time here, directly, costs
# nothing when the first call already succeeded (it is a no-op against an
# already-running daemon) and catches the case where it did not -- whether
# `enable --auto` above reported success or not: ENABLE_STATUS above is
# about `enable` completing, not about the daemon specifically ending up
# running, and #598 was exactly a case where the two came apart.
ENSURE_RUNNING_OUTPUT="$("$SEPARATION_SCRIPT" daemon ensure-running 2>&1)"
ENSURE_RUNNING_STATUS=$?
if [ "$ENSURE_RUNNING_STATUS" -eq 0 ]; then
  log "confirmed the daemon is running after install."
else
  # Still not a reason to fail the package install -- see this script's own
  # header. The companion app's tray menu (#428 Phase 2 §2.5) now surfaces a
  # stopped daemon with a Start button, so a failed start here is no longer
  # silent the way it used to be before this phase.
  log "could not confirm the daemon is running after install: ${ENSURE_RUNNING_OUTPUT}"
fi

exit 0
