#!/usr/bin/env bash
# policy: usr_prt — per-user printer auto-add via FreeIPA usr_prt_<printer> groups.
# Printer URI stored in IPA group description (ipps://... or similar).
# Logged-in members get the printer added to CUPS; leaving the group revokes access.

PRT_STATE_DIR="$STATE_DIR/printer-users"
PRT_DEFS_DIR="$STATE_DIR/printer-defs"
PRT_PROFILED="/etc/profile.d/ansipa-printers.sh"
PRT_SUDO_DROPIN="/etc/sudoers.d/ansipa-printers-trigger"
mkdir -p "$PRT_STATE_DIR" "$PRT_DEFS_DIR"

_prt_read_users() {
    local sf="$PRT_STATE_DIR/${1}.users"
    [[ -f "$sf" ]] && grep -v '^$' "$sf" | sort -u || true
}
_prt_write_users() {
    local printer="$1"; shift
    if [[ $# -gt 0 ]]; then
        printf '%s\n' "$@" | sort -u > "$PRT_STATE_DIR/${printer}.users"
    else
        > "$PRT_STATE_DIR/${printer}.users"
    fi
}
_prt_apply_acl() {
    local printer="$1"
    local -a users
    mapfile -t users < <(_prt_read_users "$printer")
    if [[ ${#users[@]} -gt 0 ]]; then
        local allow_list
        allow_list=$(IFS=','; echo "${users[*]}")
        lpadmin -p "$printer" -u "allow:${allow_list}" 2>/dev/null \
            || warn "lpadmin ACL update failed for printer $printer"
    else
        lpadmin -x "$printer" 2>/dev/null \
            && log "Removed printer $printer (no authorized users remaining)" \
            || warn "lpadmin -x failed for printer $printer"
        rm -f "$PRT_STATE_DIR/${printer}.users"
    fi
}
_prt_is_active() {
    local needle="$1"
    for _ap in "${ACTIVE_PRT_PRINTERS[@]+"${ACTIVE_PRT_PRINTERS[@]}"}"; do
        [[ "$_ap" == "$needle" ]] && return 0
    done
    return 1
}

if command -v lpadmin &>/dev/null; then
    for _i in "${!ACTIVE_PRT_PRINTERS[@]}"; do
        _PRT="${ACTIVE_PRT_PRINTERS[$_i]}"
        _GRP="${ACTIVE_PRT_GROUPS[$_i]}"

        _URI=$(ipa group-show "$_GRP" --all 2>/dev/null \
            | awk -F': ' '/Description:/{print $2; exit}' \
            | grep -E '^[a-z][a-z+.-]+://' || true)

        if [[ -z "$_URI" ]]; then
            warn "Group $_GRP has no printer URI in its description — set it with:"
            warn "  ipa group-mod $_GRP --desc='ipps://printserver/printers/$_PRT'"
            continue
        fi
        echo "$_URI" > "$PRT_DEFS_DIR/${_GRP}.uri"

        mapfile -t _CUR_USERS < <(_prt_read_users "$_PRT")
        _UPDATED=false

        while IFS= read -r _LUSER; do
            [[ -z "$_LUSER" ]] && continue
            id -Gn "$_LUSER" 2>/dev/null | tr ' ' '\n' | grep -qxF "$_GRP" || continue
            printf '%s\n' "${_CUR_USERS[@]+"${_CUR_USERS[@]}"}" | grep -qxF "$_LUSER" && continue

            if ! lpstat -p "$_PRT" &>/dev/null; then
                log "Adding printer $_PRT (URI: $_URI)"
                lpadmin -p "$_PRT" -v "$_URI" -m everywhere -E 2>/dev/null \
                    || lpadmin -p "$_PRT" -v "$_URI" -E 2>/dev/null \
                    || { warn "lpadmin failed to add printer $_PRT"; continue; }
            fi

            log "Granting printer $_PRT access to $_LUSER"
            _CUR_USERS+=("$_LUSER")
            _UPDATED=true
        done < <(who -u 2>/dev/null | awk '{print $1}' | sort -u)

        _VALID_USERS=()
        for _U in "${_CUR_USERS[@]+"${_CUR_USERS[@]}"}"; do
            if id -Gn "$_U" 2>/dev/null | tr ' ' '\n' | grep -qxF "$_GRP"; then
                _VALID_USERS+=("$_U")
            else
                log "Revoking printer $_PRT access for $_U (no longer in $_GRP)"
                _UPDATED=true
            fi
        done

        if [[ "$_UPDATED" == true ]]; then
            _prt_write_users "$_PRT" "${_VALID_USERS[@]+"${_VALID_USERS[@]}"}"
            _prt_apply_acl "$_PRT"
        fi
    done
    unset _i _PRT _GRP _URI _LUSER _U _CUR_USERS _VALID_USERS _UPDATED _ap

    # Remove printers whose IPA group was deleted.
    shopt -s nullglob
    for _sf in "$PRT_STATE_DIR"/*.users; do
        [[ -f "$_sf" ]] || continue
        _PRT=$(basename "$_sf" .users)
        _prt_is_active "$_PRT" && continue
        log "Removing printer $_PRT (IPA group usr_prt_$_PRT deleted)"
        lpadmin -x "$_PRT" 2>/dev/null || true
        rm -f "$_sf"
    done
    shopt -u nullglob
    unset _sf _PRT

    if [[ ${#ACTIVE_PRT_PRINTERS[@]} -gt 0 ]]; then
        if [[ ! -f "$PRT_SUDO_DROPIN" ]]; then
            log "Installing ansipa-printers sudo trigger rule"
            printf 'ALL ALL=(root) NOPASSWD: /usr/bin/systemctl start ansipa-enforce-policies.service\n' \
                > "$PRT_SUDO_DROPIN"
            chmod 440 "$PRT_SUDO_DROPIN"
        fi
        if [[ ! -f "$PRT_PROFILED" ]]; then
            log "Installing /etc/profile.d/ansipa-printers.sh"
            cat > "$PRT_PROFILED" <<'PROFILED'
# ansipa-printers: trigger policy enforcer at login to auto-add printers.
# Managed by ansipa-enforce-policies — do not edit manually.
sudo -n /usr/bin/systemctl start ansipa-enforce-policies.service 2>/dev/null &
disown 2>/dev/null || true
PROFILED
            chmod 644 "$PRT_PROFILED"
        fi
    else
        if [[ -f "$PRT_SUDO_DROPIN" ]]; then
            rm -f "$PRT_SUDO_DROPIN"
            log "Removed ansipa-printers sudo trigger (no active printer groups)"
        fi
        if [[ -f "$PRT_PROFILED" ]]; then
            rm -f "$PRT_PROFILED"
            log "Removed /etc/profile.d/ansipa-printers.sh (no active printer groups)"
        fi
    fi
else
    [[ ${#ACTIVE_PRT_PRINTERS[@]} -gt 0 ]] && \
        warn "lpadmin not found — install cups to enforce printer policies"
fi
unset _ap
