#!/usr/bin/env bash
#
# Mount health checker with Telegram notifications
#
set -euo pipefail

# ─────────────── Configuration ───────────────
TIMEOUT=3
HOST_FSTYPES="cifs,fuse.bindfs"
APPRISE_CFG="tgram://5862752875:AAHo7tPSIhUIAtGhHLqRmsokpPMQ__K4clU/-1001730456573"
EXCLUDE_DOCKER_CONTAINERS=("dozzle_agent" "db")
EXCLUDE_LXC_HOSTNAMES=("lxc-test" "monitor-node")
# ──────────────────────────────────────────

problems=()

warn() {
    printf '\e[31mWARNING\e[0m: %s\n' "$*" >&2
    problems+=("$*")
}

# Test if mount is responsive AND has content
test_mount() {
    local mp="$1"
    local ns_pid="${2:-}"  # optional: PID for namespace
    
    local cmd='
        # Try to stat the mount point itself (detects hung mounts)
        stat "'"$mp"'" >/dev/null 2>&1 || exit 1
        
        # Try to list directory (detects permissions/access issues)
        ls -A "'"$mp"'" >/dev/null 2>&1 || exit 1
        
        # Check if directory has content
        shopt -s nullglob dotglob
        files=("'"$mp"'"/*)
        (( ${#files[@]} > 0 ))
    '
    
    if [[ -n "$ns_pid" ]]; then
        # Test inside container namespace
        timeout "${TIMEOUT}s" nsenter -t "$ns_pid" -m bash -c "$cmd" &>/dev/null
    else
        # Test from host
        timeout "${TIMEOUT}s" bash -c "$cmd" &>/dev/null
    fi
}

#############################################################################
# 1. LXC Container Mode
#############################################################################
if [[ $(systemd-detect-virt 2>/dev/null || echo "none") == "lxc" ]]; then
    hostname_lxc=$(hostname -s)
    if [[ " ${EXCLUDE_LXC_HOSTNAMES[*]:-} " =~ " $hostname_lxc " ]]; then
        exit 0
    fi

    mapfile -t binds < <(
        findmnt -rn -o TARGET,OPTIONS \
        | awk '$2 ~ /(^|,)bind(,|$)/ {print $1}' \
        | grep -Ev '^/(dev|proc|sys|run)(/|$)'
    )
    
    for mp in "${binds[@]}"; do
        test_mount "$mp" || warn "LXC: bind mount \"$mp\" empty or hung"
    done

else
#############################################################################
# 2. Host / VM Mode
#############################################################################
    # Check host CIFS & bindfs mounts
    mapfile -t host_tab < <(findmnt -rn -t "$HOST_FSTYPES" -o TARGET,FSTYPE 2>/dev/null || true)
    for entry in "${host_tab[@]}"; do
        mp=${entry%% *}
        fstype=${entry##* }
        
        case $fstype in
            cifs)
                # CIFS: test with stat -f (filesystem stat, catches network issues)
                if ! timeout "${TIMEOUT}s" stat -f "$mp" &>/dev/null; then
                    warn "Host CIFS \"$mp\" unreachable"
                fi
                ;;
            fuse.bindfs)
                test_mount "$mp" || warn "Host bindfs \"$mp\" empty or hung"
                ;;
        esac
    done

    # Check Docker containers
    if command -v docker &>/dev/null && docker ps -q 2>/dev/null | grep -q .; then
        while IFS= read -r line; do
            cid=${line%% *}
            cname=${line#* }
            
            # Skip excluded containers
            if [[ " ${EXCLUDE_DOCKER_CONTAINERS[*]:-} " =~ " $cid " ]] || \
               [[ " ${EXCLUDE_DOCKER_CONTAINERS[*]:-} " =~ " $cname " ]]; then
                continue
            fi

            # Get container PID
            pid=$(docker inspect -f '{{.State.Pid}}' "$cid" 2>/dev/null)
            if [[ -z "$pid" || "$pid" == "0" ]]; then
                continue
            fi

            # Find fuse.mapfs mounts in container
            mapfile -t ctr_mps < <(
                nsenter -t "$pid" -m cat /proc/self/mounts 2>/dev/null \
                | awk '$3 == "fuse.mapfs" {print $2}'
            )
            
            for mp in "${ctr_mps[@]}"; do
                test_mount "$mp" "$pid" || warn "Container \"$cname\": mapfs \"$mp\" empty or hung"
            done
        done < <(docker ps --format '{{.ID}} {{.Names}}')
    fi
fi

#############################################################################
# 3. Report & Exit
#############################################################################
if ((${#problems[@]})); then
    body=$(printf "🚨 Mount-check alert on %s:\n\n" "$(hostname -s)")
    body+=$(printf '• %s\n' "${problems[@]}")

    if command -v apprise &>/dev/null && [[ -n "${APPRISE_CFG:-}" ]]; then
        apprise "$APPRISE_CFG" -b "$body" || echo "⚠️  Apprise failed" >&2
    else
        echo "⚠️  Cannot send notification (apprise missing or unconfigured)" >&2
    fi
    
    exit 1
fi

exit 0
