#!/usr/bin/env bash
# Autostart unit installation for the DPF installer.
# Source this file; do not execute directly.
#
# Writes a launch script that the platform-native autostart mechanism
# invokes:
#   - macOS:  ~/Library/LaunchAgents/local.dpf-autostart.plist  (LaunchAgent)
#   - Linux:  ~/.config/systemd/user/dpf.service                (user unit)
#
# Both unprivileged; both run-at-login (or run-on-boot with
# loginctl enable-linger). Per the deployment doctrine's Contract 3
# (lifecycle).
#
# Bash 3.2 baseline.

if [ "${DPF_LIB_AUTOSTART_LOADED:-}" = "1" ]; then
  return 0
fi
DPF_LIB_AUTOSTART_LOADED=1

if [ -z "${DPF_LIB_LOGGING_LOADED:-}" ]; then
  # shellcheck source=logging.sh
  . "$(dirname "${BASH_SOURCE[0]}")/logging.sh"
fi
if [ -z "${DPF_LIB_PLATFORM_LOADED:-}" ]; then
  # shellcheck source=platform.sh
  . "$(dirname "${BASH_SOURCE[0]}")/platform.sh"
fi
if [ -z "${DPF_LIB_STATE_LOADED:-}" ]; then
  # shellcheck source=state.sh
  . "$(dirname "${BASH_SOURCE[0]}")/state.sh"
fi

DPF_AUTOSTART_LABEL="local.dpf-autostart"
DPF_AUTOSTART_SYSTEMD_UNIT="dpf.service"

# Generate the launch script that the autostart unit invokes. The
# script lives at $stateDir/dpf-autostart.sh and embeds the compose
# chain that was active at install time, so subsequent docker compose
# upgrades or overlay changes don't silently break autostart.
#
# Args:
#   $1 = install path (repo root)
#   $2 = compose -f chain as a single space-separated string
_dpf_autostart_write_launch_script() {
  local install_path="$1"
  local compose_chain="$2"
  local state_dir; state_dir="$(dpf_state_dir)"
  local launch="$state_dir/dpf-autostart.sh"

  mkdir -p "$state_dir/logs"

  cat > "$launch" <<EOF
#!/usr/bin/env bash
# Auto-generated by install-dpf.sh on $(date -u +%Y-%m-%dT%H:%M:%SZ).
# Invoked by the platform-native autostart unit. Don't edit by hand;
# re-run install-dpf.sh to regenerate.
set -euo pipefail
cd "$install_path"
exec docker compose $compose_chain up -d
EOF
  chmod 0755 "$launch"
  echo "$launch"
}

# Render a template by substituting @@PLACEHOLDER@@ tokens.
# Args:
#   $1 = template path
#   $2 = launch script path
#   $3 = log dir
#   stdout: rendered template
_dpf_autostart_render_template() {
  local template="$1"
  local launch="$2"
  local log_dir="$3"
  sed -e "s|@@DPF_LAUNCH_SCRIPT@@|$launch|g" \
      -e "s|@@DPF_LOG_DIR@@|$log_dir|g" \
      "$template"
}

# Install the LaunchAgent (macOS) and load it via launchctl.
_dpf_autostart_install_darwin() {
  local install_path="$1"
  local compose_chain="$2"
  local template_dir="$3"
  local state_dir; state_dir="$(dpf_state_dir)"
  local log_dir="$state_dir/logs"
  local plist_path="$HOME/Library/LaunchAgents/${DPF_AUTOSTART_LABEL}.plist"
  local template="$template_dir/macos-launchagent.plist.tmpl"

  local launch; launch="$(_dpf_autostart_write_launch_script "$install_path" "$compose_chain")"

  mkdir -p "$HOME/Library/LaunchAgents"
  _dpf_autostart_render_template "$template" "$launch" "$log_dir" > "$plist_path"
  chmod 0644 "$plist_path"

  # Strip the quarantine xattr if present (downloaded plists can get
  # tagged in some workflows; harmless on plain installs).
  xattr -d com.apple.quarantine "$plist_path" 2>/dev/null || true

  # Bootstrap into the current user's GUI domain. If already loaded,
  # bootout-then-bootstrap to refresh.
  launchctl bootout "gui/$UID/${DPF_AUTOSTART_LABEL}" 2>/dev/null || true
  if launchctl bootstrap "gui/$UID" "$plist_path" 2>/dev/null; then
    ok "LaunchAgent loaded ($plist_path)"
  else
    warn "launchctl bootstrap failed; falling back to launchctl load."
    launchctl load -w "$plist_path" 2>/dev/null || warn "  launchctl load also failed; check $plist_path manually"
  fi

  dpf_state_write_json autostart "{\"enabled\":true,\"kind\":\"launchagent\"}" 2>/dev/null || true
}

# Install the systemd user unit (Linux) and enable it.
_dpf_autostart_install_linux() {
  local install_path="$1"
  local compose_chain="$2"
  local template_dir="$3"
  local state_dir; state_dir="$(dpf_state_dir)"
  local log_dir="$state_dir/logs"
  local unit_dir="$HOME/.config/systemd/user"
  local unit_path="$unit_dir/$DPF_AUTOSTART_SYSTEMD_UNIT"
  local template="$template_dir/linux-systemd.service.tmpl"

  if ! command -v systemctl >/dev/null 2>&1; then
    warn "systemctl not found; skipping autostart unit install."
    dpf_state_write_json autostart "{\"enabled\":false,\"kind\":\"none\"}" 2>/dev/null || true
    return 0
  fi

  local launch; launch="$(_dpf_autostart_write_launch_script "$install_path" "$compose_chain")"

  mkdir -p "$unit_dir"
  _dpf_autostart_render_template "$template" "$launch" "$log_dir" > "$unit_path"
  chmod 0644 "$unit_path"

  # Enable lingering so the user unit runs across logout / boot.
  if command -v loginctl >/dev/null 2>&1; then
    sudo loginctl enable-linger "$(id -un)" 2>/dev/null || \
      warn "loginctl enable-linger failed; autostart will run only when a user session is active."
  fi

  systemctl --user daemon-reload 2>/dev/null || true
  if systemctl --user enable --now "$DPF_AUTOSTART_SYSTEMD_UNIT" 2>/dev/null; then
    ok "systemd user unit enabled ($unit_path)"
  else
    warn "systemctl --user enable --now $DPF_AUTOSTART_SYSTEMD_UNIT failed."
    info "  Verify with: systemctl --user status $DPF_AUTOSTART_SYSTEMD_UNIT"
  fi

  dpf_state_write_json autostart "{\"enabled\":true,\"kind\":\"systemd-user\"}" 2>/dev/null || true
}

# Public entry point. Installs autostart for the current platform.
#
# Args:
#   $1 = install path (repo root)
#   $2 = compose -f chain as a single space-separated string
#   $3 = template dir (absolute path; typically scripts/installer)
dpf_autostart_install() {
  local install_path="$1"
  local compose_chain="$2"
  local template_dir="$3"

  dpf_platform

  case "$DPF_PLATFORM" in
    darwin)  _dpf_autostart_install_darwin "$install_path" "$compose_chain" "$template_dir" ;;
    linux)   _dpf_autostart_install_linux  "$install_path" "$compose_chain" "$template_dir" ;;
    *)
      warn "Autostart not implemented for platform: $DPF_PLATFORM"
      dpf_state_write_json autostart "{\"enabled\":false,\"kind\":\"none\"}" 2>/dev/null || true
      return 1
      ;;
  esac
}

# Public entry point for uninstall (used by uninstall-dpf.sh in Phase 7d).
dpf_autostart_uninstall() {
  dpf_platform
  case "$DPF_PLATFORM" in
    darwin)
      local plist="$HOME/Library/LaunchAgents/${DPF_AUTOSTART_LABEL}.plist"
      if [ -f "$plist" ]; then
        launchctl bootout "gui/$UID/${DPF_AUTOSTART_LABEL}" 2>/dev/null || true
        launchctl unload "$plist" 2>/dev/null || true
        rm -f "$plist"
        ok "LaunchAgent uninstalled"
      fi
      ;;
    linux)
      if command -v systemctl >/dev/null 2>&1; then
        systemctl --user disable --now "$DPF_AUTOSTART_SYSTEMD_UNIT" 2>/dev/null || true
      fi
      rm -f "$HOME/.config/systemd/user/$DPF_AUTOSTART_SYSTEMD_UNIT"
      ok "systemd user unit removed"
      ;;
  esac
  dpf_state_write_json autostart "{\"enabled\":false,\"kind\":\"none\"}" 2>/dev/null || true
}
