#!/usr/bin/env bash
# policy: usr_policystore — auto-mount the ansipa policy store for admins.
# When the IPA user group usr_smb_adm_policystore exists, members who are
# logged in get the ansipa-policystore SMB share mounted at ~/policystore (rw).
# The mount is tracked in state and removed when the group is deleted or the
# user is no longer a member.
# Credential: cifs://<host>:smb-policystore:<pass> in the IPA group description,
# written by ansipa-smb-setup.sh.

PS_MOUNT_STATE="$STATE_DIR/policystore-mounts"
PS_CREDS_DIR="$STATE_DIR/smb-creds"
PS_CREDS_FILE="$PS_CREDS_DIR/policystore.creds"
[[ -f "$PS_MOUNT_STATE" ]] || touch "$PS_MOUNT_STATE"
mkdir -p "$PS_CREDS_DIR"
chmod 700 "$PS_CREDS_DIR"

_ps_grp_exists=false
grep -qxF "usr_smb_adm_policystore" <<< "$_ALL_USER_GROUPS" && _ps_grp_exists=true

_ps_member() { id -nG "$1" 2>/dev/null | tr ' ' '\n' | grep -qxF "usr_smb_adm_policystore"; }

if [[ "$_ps_grp_exists" == true ]] && command -v mount.cifs &>/dev/null; then
    _PS_CRED=$(_smb_parse_cred "usr_smb_adm_policystore")
    if [[ -z "$_PS_CRED" ]]; then
        warn "usr_smb_adm_policystore: no cifs:// credential in IPA group description"
        warn "  — run ansipa-smb.service on the FreeIPA container first"
    else
        read -r _PS_HOST _PS_SUSER _PS_SPASS <<< "$_PS_CRED"
        printf 'username=%s\npassword=%s\ndomain=WORKGROUP\n' "$_PS_SUSER" "$_PS_SPASS" \
            > "$PS_CREDS_FILE"
        chmod 600 "$PS_CREDS_FILE"

        # Collect logged-in users.
        declare -A _PS_SESS
        _ps_add_sess() {
            local _u
            [[ "$2" == "loginctl" ]] && _u=$(awk '{print $3}' <<< "$1") \
                                     || _u=$(awk '{print $1}' <<< "$1")
            [[ -z "$_u" || "$_u" == "root" || "$_u" == "USER" ]] && return 0
            local _h; _h=$(getent passwd "$_u" | cut -d: -f6 2>/dev/null) || return 0
            [[ -d "$_h" ]] && _PS_SESS["$_u"]="$_h"
        }
        if loginctl list-sessions --no-legend &>/dev/null; then
            while IFS= read -r _L; do _ps_add_sess "$_L" "loginctl"
            done < <(loginctl list-sessions --no-legend 2>/dev/null)
        else
            while IFS= read -r _L; do _ps_add_sess "$_L" "who"
            done < <(who 2>/dev/null)
        fi
        unset _L

        # Mount for logged-in members.
        for _PS_U in "${!_PS_SESS[@]}"; do
            _ps_member "$_PS_U" || continue
            _PS_H="${_PS_SESS[$_PS_U]}"
            _PS_MP="$_PS_H/policystore"

            if mountpoint -q "$_PS_MP" 2>/dev/null; then
                grep -qxF "$_PS_U" "$PS_MOUNT_STATE" 2>/dev/null || \
                    echo "$_PS_U" >> "$PS_MOUNT_STATE"
                continue
            fi

            mkdir -p "$_PS_MP"
            chown "$_PS_U" "$_PS_MP" 2>/dev/null || true

            if mount -t cifs "//${_PS_HOST}/ansipa-policystore" "$_PS_MP" \
                -o "credentials=${PS_CREDS_FILE},uid=${_PS_U},gid=${_PS_U},file_mode=0664,dir_mode=02775,nounix,noserverino" \
                2>/dev/null; then
                log "Mounted //${_PS_HOST}/ansipa-policystore → $_PS_MP for $_PS_U"
                grep -qxF "$_PS_U" "$PS_MOUNT_STATE" 2>/dev/null || \
                    echo "$_PS_U" >> "$PS_MOUNT_STATE"
            else
                warn "Failed to mount policystore for $_PS_U"
                rmdir "$_PS_MP" 2>/dev/null || true
            fi
        done
        unset _PS_U _PS_H _PS_MP

        # Revert: unmount for users no longer in the group or group deleted.
        _NEW_PS_MOUNTS=()
        while IFS= read -r _OLD_PS_U; do
            [[ -z "$_OLD_PS_U" ]] && continue
            _OLD_PS_HOME=$(getent passwd "$_OLD_PS_U" | cut -d: -f6 2>/dev/null) || continue
            _OLD_PS_MP="$_OLD_PS_HOME/policystore"
            if _ps_member "$_OLD_PS_U"; then
                _NEW_PS_MOUNTS+=("$_OLD_PS_U")
            else
                umount -l "$_OLD_PS_MP" 2>/dev/null || true
                rmdir "$_OLD_PS_MP" 2>/dev/null || true
                log "Unmounted policystore for $_OLD_PS_U (no longer in usr_smb_adm_policystore)"
            fi
        done < "$PS_MOUNT_STATE"
        unset _OLD_PS_U _OLD_PS_HOME _OLD_PS_MP

        if [[ ${#_NEW_PS_MOUNTS[@]} -gt 0 ]]; then
            printf '%s\n' "${_NEW_PS_MOUNTS[@]}" | sort -u > "$PS_MOUNT_STATE"
        else
            > "$PS_MOUNT_STATE"
        fi
        unset _NEW_PS_MOUNTS _PS_SESS _PS_HOST _PS_SUSER _PS_SPASS _PS_CRED

        rm -f "$PS_CREDS_FILE" 2>/dev/null || true
    fi
else
    # Group deleted — unmount for any previously-tracked users.
    if [[ -s "$PS_MOUNT_STATE" ]]; then
        while IFS= read -r _OLD_PS_U; do
            [[ -z "$_OLD_PS_U" ]] && continue
            _OLD_PS_HOME=$(getent passwd "$_OLD_PS_U" | cut -d: -f6 2>/dev/null) || continue
            umount -l "$_OLD_PS_HOME/policystore" 2>/dev/null || true
            rmdir "$_OLD_PS_HOME/policystore" 2>/dev/null || true
            log "Unmounted policystore for $_OLD_PS_U (usr_smb_adm_policystore group deleted)"
        done < "$PS_MOUNT_STATE"
        > "$PS_MOUNT_STATE"
        unset _OLD_PS_U _OLD_PS_HOME
    fi
fi
unset _ps_grp_exists
