#!/bin/bash
# mailgroups-helper — privileged helper for the Mail Groups Plesk extension.
# Runs as root via pm_ApiCli::callSbin(). The extension owns a dedicated Postfix
# alias map, /etc/postfix/mailgroups, and manages its wiring into
# virtual_alias_maps. The file is created on install and removed on uninstall.
set -eu

MAP_FILE="/etc/postfix/mailgroups"
POSTMAP="$(command -v postmap || echo /usr/sbin/postmap)"
POSTCONF="$(command -v postconf || echo /usr/sbin/postconf)"
BACKUP_KEEP=20

die() { echo "ERROR: $*" >&2; exit 1; }

reload_postfix() {
    if command -v systemctl >/dev/null 2>&1; then
        systemctl reload postfix >/dev/null 2>&1 || /usr/sbin/postfix reload >/dev/null 2>&1 || true
    else
        /usr/sbin/postfix reload >/dev/null 2>&1 || true
    fi
}

is_wired() {
    case "$("$POSTCONF" -h virtual_alias_maps 2>/dev/null || echo '')" in
        *"hash:$MAP_FILE"*) return 0 ;;
        *) return 1 ;;
    esac
}

ensure_wired() {
    is_wired && return 0
    local maps new
    maps="$("$POSTCONF" -h virtual_alias_maps 2>/dev/null || echo '')"
    if [ -z "$maps" ]; then new="hash:$MAP_FILE"; else new="$maps, hash:$MAP_FILE"; fi
    "$POSTCONF" -e "virtual_alias_maps=$new"
    reload_postfix
}

unwire() {
    is_wired || return 0
    local maps new
    maps="$("$POSTCONF" -h virtual_alias_maps 2>/dev/null || echo '')"
    new="$(printf '%s' "$maps" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' \
        | grep -vx "hash:$MAP_FILE" | paste -sd, - | sed 's/,/, /g')"
    "$POSTCONF" -e "virtual_alias_maps=$new"
    reload_postfix
}

cmd="${1:-}"

case "$cmd" in
  get)
    [ -f "$MAP_FILE" ] && cat "$MAP_FILE" || true
    ;;

  set)
    src="${2:-}"
    [ -n "$src" ] || die "no source path given"
    [ -f "$src" ] || die "source not found: $src"
    case "$src" in
      /usr/local/psa/var/modules/mailgroups/*|/opt/psa/var/modules/mailgroups/*) : ;;
      *) die "source path not allowed: $src" ;;
    esac

    bad="$(grep -vE '^[[:space:]]*(#|$)' "$src" | grep -vE '^[^[:space:]]+@[^[:space:]]+[[:space:]]+.+@.+' || true)"
    [ -z "$bad" ] || die "invalid line(s): $bad"

    tmp="$(mktemp "${MAP_FILE%/*}/.mailgroups.XXXXXX")" || die "mktemp failed"
    cp "$src" "$tmp"
    if ! "$POSTMAP" "$tmp" 2>/tmp/.mailgroups.err; then
      rm -f "$tmp" "$tmp.db"
      die "postmap validation failed: $(cat /tmp/.mailgroups.err 2>/dev/null)"
    fi
    rm -f "$tmp" "$tmp.db" /tmp/.mailgroups.err

    if [ -f "$MAP_FILE" ]; then
      cp -p "$MAP_FILE" "$MAP_FILE.mgbak-$(date +%Y%m%d-%H%M%S-%N)"
      ls -1t "$MAP_FILE".mgbak-* 2>/dev/null | tail -n +$((BACKUP_KEEP + 1)) | xargs -r rm -f
    fi
    install -m 0644 "$src" "$MAP_FILE"
    "$POSTMAP" "$MAP_FILE" || die "postmap failed on install"
    ensure_wired
    echo "OK"
    ;;

  check)
    [ -x "$POSTMAP" ] && echo "postmap=yes" || echo "postmap=no"
    is_wired && echo "wiring=yes" || echo "wiring=no"
    ;;

  install)
    [ -f "$MAP_FILE" ] || : > "$MAP_FILE"
    chmod 0644 "$MAP_FILE"
    "$POSTMAP" "$MAP_FILE" || die "postmap failed"
    ensure_wired
    echo "OK"
    ;;

  uninstall)
    unwire
    rm -f "$MAP_FILE" "$MAP_FILE.db" "$MAP_FILE".mgbak-*
    reload_postfix
    echo "OK"
    ;;

  *)
    die "unknown command: ${cmd:-<none>}"
    ;;
esac
