#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

SRC_ROOT="$HOME/Documents/2026/projects"
DST_ROOT="$HOME/projects"
SUBDIR="doc"
FSTAB="/etc/fstab"

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

is_mounted() { findmnt -n "$1" >/dev/null 2>&1; }

bind_source_of() {
    awk -v t="$1" '$5 == t {print $4; exit}' /proc/self/mountinfo
}

abort_busy() {
    local target="$1"
    echo "Fehler: '$target' ist belegt — kann nicht ausgehängt werden." >&2
    echo "Folgende Prozesse halten das Verzeichnis offen:" >&2
    lsof +D "$target" 2>/dev/null | head -20 >&2 || true
    exit 1
}

safe_umount() {
    local target="$1"
    is_mounted "$target" || return 0
    sudo umount "$target" 2>/dev/null || abort_busy "$target"
}

remove_fstab_targets() {
    (( $# > 0 )) || return 0
    local tmp list
    tmp=$(mktemp)
    list=$(printf '%s\n' "$@")
    awk -v targets="$list" '
        BEGIN { n = split(targets, arr, "\n"); for (i in arr) if (arr[i] != "") skip[arr[i]] = 1 }
        !($2 in skip) { print }
    ' "$FSTAB" > "$tmp"
    sudo install -m 644 -o root -g root "$tmp" "$FSTAB"
    rm -f "$tmp"
}

append_fstab() {
    echo "$1 $2 none bind,nofail 0 0" | sudo tee -a "$FSTAB" > /dev/null
}

fstab_bind_targets_under() {
    local prefix="$1"
    awk -v p="$prefix/" '
        $3 == "none" && $4 ~ /(^|,)bind(,|$)/ && index($2, p) == 1 { print $1 "\t" $2 }
    ' "$FSTAB"
}

mode_remove() {
    local entries=()
    mapfile -t entries < <(fstab_bind_targets_under "$DST_ROOT")
    if (( ${#entries[@]} == 0 )); then
        echo "Keine ma-sync Mounts in fstab gefunden."
        return 0
    fi

    local targets=() removed=0 src target entry
    for entry in "${entries[@]}"; do
        IFS=$'\t' read -r src target <<< "$entry"
        echo "→ Entferne: $target  (Source: $src)"
        safe_umount "$target"
        if [[ -d "$src" ]]; then
            cp -a "$src/." "$target/"
        else
            echo "  Warnung: Source '$src' existiert nicht mehr — Target bleibt leer." >&2
        fi
        targets+=("$target")
        removed=$((removed + 1))
    done

    remove_fstab_targets "${targets[@]}"
    sudo systemctl daemon-reload
    echo "✓ $removed Mount(s) entfernt, Inhalte kopiert, fstab bereinigt."
}

mode_mount() {
    [[ -d "$SRC_ROOT" ]] || die "Source-Root '$SRC_ROOT' existiert nicht."

    local mounted=0 skipped=0 remounted=0

    shopt -s nullglob
    local src name target
    for src in "$SRC_ROOT"/*/; do
        src="${src%/}"
        name=$(basename "$src")
        target="$DST_ROOT/$name/$SUBDIR"

        # Sicherheitschecks
        [[ -z "$name" || "$name" == "/" ]] && continue
        [[ "$src" == "$HOME" ]] && continue
        [[ "$src" == "$target" ]] && continue
        case "$target/" in "$src"/*) continue;; esac
        case "$src/" in "$target"/*) continue;; esac

        # Nur mounten, wenn das Target-Parent-Verzeichnis (mit gleichem Namen) bereits existiert
        if [[ ! -d "$DST_ROOT/$name" ]]; then
            echo "↷ kein Target-Container: $DST_ROOT/$name fehlt → übersprungen"
            skipped=$((skipped + 1))
            continue
        fi

        if is_mounted "$target"; then
            local cur
            cur=$(bind_source_of "$target")
            if [[ "$cur" == "$src" ]]; then
                echo "↻ skip (bereits korrekt): $target"
                skipped=$((skipped + 1))
                continue
            fi
            echo "↺ Re-mount: $target  (war: $cur, neu: $src)"
            safe_umount "$target"
            remounted=$((remounted + 1))
        fi

        mkdir -p "$target"
        if [[ -n "$(ls -A "$target" 2>/dev/null)" ]]; then
            echo "  Target '$target' nicht leer — wird geleert." >&2
            find "$target" -mindepth 1 -delete
        fi

        remove_fstab_targets "$target"
        sudo mount --bind "$src" "$target"
        append_fstab "$src" "$target"
        echo "✓ gemountet: $src → $target"
        mounted=$((mounted + 1))
    done
    shopt -u nullglob

    sudo systemctl daemon-reload

    echo ""
    echo "Zusammenfassung: $mounted gemountet (davon $remounted Re-mount), $skipped übersprungen."
}

case "${1:-}" in
    --remove) mode_remove ;;
    "")       mode_mount ;;
    *)        die "Unbekanntes Argument: '$1' (erwartet: --remove oder leer)" ;;
esac
