#!/bin/bash

# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.

# Usage:
#     so-nsm-mount
#
# Options:
#     None - script automatically detects and configures NVMe devices
#
# Examples:
#     1. Configure and mount NVMe devices:
#         ```bash
#         sudo so-nsm-mount
#         ```
#
# Notes:
#     - Requires root privileges
#     - Automatically detects unmounted NVMe devices
#     - Handles multiple NVMe devices:
#         * Creates PV from each device
#         * Combines all devices into single volume group
#         * Creates single logical volume using total space
#     - Safely handles existing LVM configurations:
#         * Preserves proper existing configurations
#         * Provides cleanup instructions if conflicts found
#     - Creates or extends LVM configuration if no conflicts
#     - Uses XFS filesystem
#     - Configures persistent mount via /etc/fstab
#     - Safe to run multiple times
#
# Description:
#     This script automates the configuration and mounting of NVMe devices
#     as /nsm in Security Onion virtual machines. It performs these steps:
#
# Dependencies:
#     - dmidecode: Required for getting system UUID
#     - nvme-cli: Required for NVMe secure erase operations
#     - lvm2: Required for LVM operations
#     - xfsprogs: Required for XFS filesystem operations
#
#     1. Safety Checks:
#        - Verifies root privileges
#        - Checks if /nsm is already mounted
#        - Detects available unmounted NVMe devices
#
#     2. LVM Configuration Check:
#        - If device is part of "system" VG with "nsm" LV:
#          * Uses existing configuration
#          * Exits successfully
#        - If device is part of different LVM configuration:
#          * Logs current configuration details
#          * Provides specific cleanup instructions
#          * Exits with error to prevent data loss
#
#     3. New Configuration (if no conflicts):
#        - Creates physical volume on each NVMe device
#        - Combines all devices into single "system" volume group
#        - Creates single "nsm" logical volume using total space
#        - Creates XFS filesystem
#        - Updates /etc/fstab for persistence
#        - Mounts the filesystem as /nsm
#
# Exit Codes:
#     0: Success conditions:
#        - Devices configured and mounted
#        - Already properly mounted
#     1: Error conditions:
#        - Must be run as root
#        - No available NVMe devices found
#        - Device has conflicting LVM configuration
#        - Device preparation failed
#        - LVM operation failed
#        - Filesystem/mount operation failed
#
# Logging:
#     - All operations logged to both console and /opt/so/log/so-nsm-mount.log

set -e

LOG_FILE="/opt/so/log/so-nsm-mount-nvme"
VG_NAME=""
LV_NAME="nsm"
MOUNT_POINT="/nsm"

# Function to log messages
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "$LOG_FILE" >&2
}

# Function to log errors
log_error() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: $1" | tee -a "$LOG_FILE" >&2
}

# Function to log command output
log_cmd() {
    local cmd="$1"
    local desc="$2"
    local output
    local ret=0
    
    output=$(eval "$cmd" 2>&1) || ret=$?
    
    if [ -n "$output" ]; then
        log "$desc:"
        printf '%s\n' "$output" | sed 's/^/  /' | while IFS= read -r line; do
            log "$line"
        done
    fi
    
    [ $ret -eq 0 ] || log_error "Command failed with exit code $ret: $cmd"
    return $ret
}

# Get system UUID for unique VG naming
get_system_uuid() {
    local uuid
    
    if ! uuid=$(dmidecode -s system-uuid 2>/dev/null); then
        log_error "Failed to get system UUID"
        exit 1
    fi
    
    # Just convert hyphens to underscores
    echo "${uuid//-/_}"
}

# Convert VG name back to UUID format
vg_name_to_uuid() {
    local vg=$1
    # Just convert underscores back to hyphens
    echo "$vg" | tr '_' '-'
}

# Function to perform secure erase of NVMe device
secure_erase_nvme() {
    local device=$1
    local ret=0
    local retry=3
    
    log "Performing secure erase of NVMe device $device"
    
    if [[ ! "$device" =~ ^/dev/nvme[0-9]+n[0-9]+$ ]]; then
        log_error "Device $device is not an NVMe device"
        return 1
    fi
    
    # Check if device is mounted
    if mountpoint -q "$device" || findmnt -n | grep -q "$device"; then
        log_error "Device $device is mounted, cannot secure erase"
        return 1
    fi
    
    # Attempt secure erase with retries
    while [ $retry -gt 0 ]; do
        log "  Executing secure erase command (attempt $((4-retry))/3)"
        if nvme format "$device" --namespace-id 1 --ses 1 --lbaf 0 --force 2>nvme.err; then
            log "  Success: Secure erase completed"
            rm -f nvme.err
            return 0
        fi
        
        # Check error type
        if grep -q "Device or resource busy" nvme.err; then
            log "  Device busy, waiting before retry"
            sleep 3
        else
            log_error "Secure erase failed"
            log "  Details: $(cat nvme.err)"
            rm -f nvme.err
            return 1
        fi
        
        retry=$((retry - 1))
    done
    
    log_error "Failed to secure erase device after 3 attempts"
    return 1
}

# Function to check if running as root
check_root() {
    if [ "$EUID" -ne 0 ]; then
        log_error "Failed to execute - script must be run as root"
        exit 1
    fi
}

# Function to check LVM configuration of a device
check_lvm_config() {
    local device=$1
    local vg_name
    local lv_name
    
    log "Checking LVM configuration for $device"
    
    # Log device details
    log_cmd "lsblk -o NAME,SIZE,TYPE,MOUNTPOINT $device" "Device details"
    
    # Check if device is a PV
    if ! pvs "$device" &>/dev/null; then
        log "Device is not a physical volume"
        return 0
    fi
    
    # Log PV details
    log_cmd "pvs --noheadings -o pv_name,vg_name,pv_size,pv_used $device" "Physical volume details"
    
    # Get VG name if any
    vg_name=$(pvs --noheadings -o vg_name "$device" | tr -d ' ')
    if [ -z "$vg_name" ]; then
        log "Device is not part of any volume group"
        return 0
    fi
    
    # Safety check - never touch system VGs
    if is_system_vg "$vg_name"; then
        log_error "Device $device is part of system VG: $vg_name"
        log "Cannot modify system volume groups. Aborting."
        exit 1
    fi
    
    # Log VG details
    log_cmd "vgs --noheadings -o vg_name,vg_size,vg_free,pv_count $vg_name" "Volume group details"
    
    # If it's our expected configuration
    if [ "$vg_name" = "$VG_NAME" ]; then
        if lvs "$VG_NAME/$LV_NAME" &>/dev/null; then
            # Log LV details
            log_cmd "lvs --noheadings -o lv_name,lv_size,lv_path $VG_NAME/$LV_NAME" "Logical volume details"
            return 0
        fi
    fi
    
    # Get all LVs in the VG
    local lvs_in_vg=$(lvs --noheadings -o lv_name "$vg_name" 2>/dev/null | tr '\n' ',' | sed 's/,$//')
    
    log_error "Device $device is part of existing LVM configuration:"
    log "  Volume Group: $vg_name"
    log "  Logical Volumes: ${lvs_in_vg:-none}"
    log ""
    log "To preserve data safety, no changes will be made."
    log ""
    log "If you want to repurpose this device for /nsm, verify it's safe to proceed:"
    log "1. Check current usage: lsblk $device"
    log "2. Then run this command to clean up (CAUTION: THIS WILL DESTROY ALL DATA):"
    log "   umount $MOUNT_POINT 2>/dev/null; "
    for lv in $(echo "$lvs_in_vg" | tr ',' ' '); do
        log "   lvremove -f /dev/$vg_name/$lv; "
    done
    log "   vgreduce $vg_name $device && pvremove -ff -y $device && wipefs -a $device"
    
    exit 1
}

# Function to check if VG is system critical
is_system_vg() {
    local vg=$1
    local root_dev
    local root_vg
    local mp
    local dev
    
    # First check if it's the current root VG
    root_dev=$(findmnt -n -o SOURCE /)
    if [ -n "$root_dev" ]; then
        # Get VG name from root device
        if lvs --noheadings -o vg_name "$root_dev" 2>/dev/null | grep -q "^$vg$"; then
            return 0  # true
        fi
    fi
    
    # Check all mounted LVM devices
    while read -r mp; do
        # Skip our NSM mount
        [ "$mp" = "$MOUNT_POINT" ] && continue
        
        # Check if mount uses this VG
        if lvs --noheadings -o vg_name "$mp" 2>/dev/null | grep -q "^$vg$"; then
            return 0  # true
        fi
    done < <(findmnt -n -o SOURCE -t ext4,xfs,btrfs,swap | grep "/dev/mapper/")
    
    # Check if VG contains any mounted devices
    while read -r dev; do
        if [ -n "$dev" ] && findmnt -n | grep -q "$dev"; then
            return 0  # true
        fi
    done < <(lvs "/dev/$vg" --noheadings -o lv_path 2>/dev/null)
    
    # Check if VG contains critical LV names
    if lvs "/dev/$vg" &>/dev/null; then
        if lvs --noheadings -o lv_name "/dev/$vg" 2>/dev/null | grep -qE '^(root|swap|home|var|usr|tmp|opt|srv|boot)$'; then
            return 0  # true
        fi
    fi
    
    # Check if VG has common system names
    if [[ "$vg" =~ ^(vg_main|system|root|os|rhel|centos|ubuntu|debian|fedora)$ ]]; then
        return 0  # true
    fi
    
    return 1  # false
}

# Function to deactivate LVM on device
deactivate_lvm() {
    local device=$1
    local vg=$2
    
    # Safety check - never touch system VGs
    if is_system_vg "$vg"; then
        log_error "Refusing to deactivate system VG: $vg"
        return 1
    fi
    
    log "  Deactivating LVM on device $device (VG: $vg)"
    
    # Get list of LVs that specifically use this device
    local lvs_to_deactivate
    lvs_to_deactivate=$(pvs --noheadings -o vg_name,lv_name "$device" 2>/dev/null | awk '{print $1"/"$2}')
    
    # Deactivate only LVs that use this device
    if [ -n "$lvs_to_deactivate" ]; then
        log "    Deactivating logical volumes on device"
        while read -r lv; do
            if [ -n "$lv" ]; then
                log "      Deactivating: $lv"
                if ! lvchange -an "/dev/$lv" 2>/dev/null; then
                    log "      WARNING: Failed to deactivate $lv"
                fi
            fi
        done <<< "$lvs_to_deactivate"
    fi
    
    # No need to attempt VG removal - secure erase will handle it
    return 0
}

# Function to cleanup device
cleanup_device() {
    local device=$1
    local ret=0
    
    log "Cleaning up device $device"
    
    # Check if device belongs to current system
    if pvs "$device" &>/dev/null; then
        local vg=$(pvs --noheadings -o vg_name "$device" | tr -d ' ')
        local current_vg=$(get_system_uuid)
        local vg_uuid=""
        local current_uuid=""
        
        if [[ -n "$vg" ]]; then
            # Convert VG names to UUIDs for comparison
            vg_uuid=$(vg_name_to_uuid "$vg")
            current_uuid=$(vg_name_to_uuid "$current_vg")
            
            if [[ "$vg_uuid" == "$current_uuid" ]]; then
                log "  Device belongs to current system, skipping secure erase"
            else
                log "  Device belongs to different system (VG: $vg)"
                
                # First deactivate LVM
                if ! deactivate_lvm "$device" "$vg"; then
                    log_error "Failed to fully deactivate LVM"
                    ret=1
                fi
                
                # Attempt secure erase even if LVM cleanup had issues
                log "  Performing secure erase"
                if ! secure_erase_nvme "$device"; then
                    log_error "Failed to secure erase device"
                    ret=1
                fi
            fi
        fi
    else
        # No LVM configuration found, perform secure erase
        log "  No LVM configuration found, performing secure erase"
        if ! secure_erase_nvme "$device"; then
            log_error "Failed to secure erase device"
            ret=1
        fi
    fi
    
    # Always attempt to remove partitions and signatures
    log "  Removing partitions and signatures"
    if ! wipefs -a "$device" 2>/dev/null; then
        log_error "Failed to remove signatures"
        ret=1
    fi
    
    if [ $ret -eq 0 ]; then
        log "  Device cleanup successful"
    else
        log_error "Device cleanup had some issues"
    fi
    return $ret
}

# Function to validate device state
validate_device_state() {
    local device=$1
    
    if [[ ! -b "$device" ]]; then
        log_error "$device is not a valid block device"
        return 1
    fi
    
    # Check if device is already properly configured
    if pvs "$device" &>/dev/null; then
        local vg=$(pvs --noheadings -o vg_name "$device" | tr -d ' ')
        
        # Safety check - never touch system VGs
        if is_system_vg "$vg"; then
            log_error "Device $device is part of system VG: $vg"
            log "Cannot modify system volume groups. Aborting."
            return 1
        fi
        
        # Convert VG names to UUIDs for comparison
        local vg_uuid=$(vg_name_to_uuid "$vg")
        local current_uuid=$(vg_name_to_uuid "$VG_NAME")
        
        if [[ "$vg_uuid" == "$current_uuid" ]]; then
            if lvs "$vg/$LV_NAME" &>/dev/null; then
                log "Device $device is already properly configured in VG $vg"
                return 0
            fi
        fi
    fi
    
    # Check for existing partitions or LVM
    if pvs "$device" &>/dev/null || lsblk -no TYPE "$device" | grep -q "part"; then
        # Check if device is mounted as root filesystem
        if mountpoint -q / && findmnt -n -o SOURCE / | grep -q "$device"; then
            log_error "Device $device contains root filesystem. Aborting."
            return 1
        fi
        
        log "Device $device has existing configuration"
        if ! cleanup_device "$device"; then
            log "Failed to cleanup device $device"
            return 1
        fi
    fi
    
    return 0
}

# Function to log device details
log_device_details() {
    local device=$1
    local size mount fs_type vg_name
    
    size=$(lsblk -dbn -o SIZE "$device" 2>/dev/null | numfmt --to=iec)
    mount=$(lsblk -no MOUNTPOINT "$device" 2>/dev/null)
    fs_type=$(lsblk -no FSTYPE "$device" 2>/dev/null)
    
    log "Device details for $device:"
    log "  Size: $size"
    log "  Filesystem: ${fs_type:-none}"
    log "  Mountpoint: ${mount:-none}"
    
    if pvs "$device" &>/dev/null; then
        vg_name=$(pvs --noheadings -o vg_name "$device" | tr -d ' ')
        log "  LVM status: Physical volume in VG ${vg_name:-none}"
    else
        log "  LVM status: Not a physical volume"
    fi
}

# Function to detect NVMe devices
detect_nvme_devices() {
    local -a devices=()
    local -a available_devices=()
    local -a configured_devices=()
    
    {
        log "----------------------------------------"
        log "Starting NVMe device detection"
        log "----------------------------------------"
        
        # First get a clean list of devices
        while read -r dev; do
            if [[ -b "$dev" ]]; then
                devices+=("$dev")
            fi
        done < <(find /dev -name 'nvme*n1' 2>/dev/null)
        
        if [ ${#devices[@]} -eq 0 ]; then
            log_error "No NVMe devices found"
            log "----------------------------------------"
            exit 1
        fi
        
        log "Found ${#devices[@]} NVMe device(s)"
        
        # Process and validate each device
        for dev in "${devices[@]}"; do
            log_device_details "$dev"
            
            if validate_device_state "$dev"; then
                if pvs "$dev" &>/dev/null; then
                    local vg=$(pvs --noheadings -o vg_name "$dev" | tr -d ' ')
                    local vg_uuid=$(vg_name_to_uuid "$vg")
                    local current_uuid=$(vg_name_to_uuid "$VG_NAME")
                    
                    if [[ "$vg_uuid" == "$current_uuid" ]]; then
                        configured_devices+=("$dev")
                        log "Status: Already configured in VG $vg"
                    else
                        available_devices+=("$dev")
                        log "Status: Available for use"
                    fi
                else
                    available_devices+=("$dev")
                    log "Status: Available for use"
                fi
            else
                log "Status: Not available (see previous messages)"
            fi
            log "----------------------------------------"
        done
        
        if [ ${#configured_devices[@]} -gt 0 ]; then
            log "Found ${#configured_devices[@]} device(s) already configured:"
            for dev in "${configured_devices[@]}"; do
                local size=$(lsblk -dbn -o SIZE "$dev" 2>/dev/null | numfmt --to=iec)
                log "  - $dev ($size)"
            done
            log "Proceeding with mount setup"
            return 0
        fi
        
        if [ ${#available_devices[@]} -eq 0 ]; then
            log_error "No available NVMe devices found"
            log "----------------------------------------"
            exit 1
        fi
        
        log "Summary: ${#available_devices[@]} device(s) available for use"
        for dev in "${available_devices[@]}"; do
            local size=$(lsblk -dbn -o SIZE "$dev" 2>/dev/null | numfmt --to=iec)
            log "  - $dev ($size)"
        done
        log "----------------------------------------"
    } >&2
    
    # Return array elements one per line
    printf '%s\n' "${available_devices[@]}"
}

# Function to prepare devices for LVM
prepare_devices() {
    local -a devices=("$@")
    local -a prepared_devices=()
    
    {
        log "----------------------------------------"
        log "Starting device preparation"
        log "----------------------------------------"
        
        for device in "${devices[@]}"; do
            if [[ ! -b "$device" ]]; then
                log_error "Invalid device path: $device"
                continue
            fi
            
            log "Processing device: $device"
            log_device_details "$device"
            
            # Check if device needs preparation
            if ! validate_device_state "$device"; then
                log "Skipping device $device - invalid state"
                continue
            fi
            
            log "Preparing device for LVM use:"
            
            # Clean existing signatures
            log "  Step 1: Cleaning existing signatures"
            if ! wipefs -a "$device" 2>wipefs.err; then
                log_error "Failed to clean signatures"
                log "  Details: $(cat wipefs.err)"
                rm -f wipefs.err
                continue
            fi
            rm -f wipefs.err
            log "  Success: Signatures cleaned"

            # Create physical volume
            log "  Step 2: Creating physical volume"
            if ! pvcreate -ff -y "$device" 2>pv.err; then
                log_error "Physical volume creation failed"
                log "  Details: $(cat pv.err)"
                rm -f pv.err
                continue
            fi
            rm -f pv.err
            
            # Log success and add to prepared devices
            size=$(lsblk -dbn -o SIZE "$device" | numfmt --to=iec)
            log "  Success: Created physical volume"
            log "    Device: $device"
            log "    Size: $size"
            log_cmd "pvs --noheadings -o pv_name,vg_name,pv_size,pv_used $device" "Physical volume details"
            
            prepared_devices+=("$device")
            log "----------------------------------------"
        done
        
        if [ ${#prepared_devices[@]} -eq 0 ]; then
            log_error "No devices were successfully prepared"
            exit 1
        fi
    } >&2
    
    printf '%s\n' "${prepared_devices[@]}"
}

# Function to wait for device
wait_for_device() {
    local device="$1"
    local timeout=10
    local count=0
    
    log "Waiting for device $device to be available"
    while [ ! -e "$device" ] && [ $count -lt $timeout ]; do
        sleep 1
        count=$((count + 1))
        log "  Attempt $count/$timeout"
    done
    
    if [ ! -e "$device" ]; then
        log_error "Device $device did not appear after $timeout seconds"
        return 1
    fi
    
    # Run udevadm trigger to ensure device nodes are created
    log "  Running udevadm trigger"
    if ! udevadm trigger "$device" 2>/dev/null; then
        log "  WARNING: udevadm trigger failed, continuing anyway"
    fi
    
    # Give udev a moment to create device nodes
    sleep 1
    
    # Run udevadm settle to wait for udev to finish processing
    log "  Waiting for udev to settle"
    if ! udevadm settle 2>/dev/null; then
        log "  WARNING: udevadm settle failed, continuing anyway"
    fi
    
    # Run vgscan to ensure LVM sees the device
    log "  Running vgscan"
    if ! vgscan --mknodes 2>/dev/null; then
        log "  WARNING: vgscan failed, continuing anyway"
    fi
    
    log "  Device $device is now available"
    return 0
}

# Function to setup LVM
setup_lvm() {
    local -a devices=("$@")
    
    log "----------------------------------------"
    log "Starting LVM configuration"
    log "----------------------------------------"
    
    # Log initial LVM state
    log "Initial LVM state:"
    log_cmd "pvs" "Physical volumes"
    log_cmd "vgs" "Volume groups"
    log_cmd "lvs" "Logical volumes"
    
    # Create or extend volume group
    if vgs "$VG_NAME" &>/dev/null; then
        log "Step 1: Extending existing volume group"
        log "  Target VG: $VG_NAME"
        log "  Devices to add: ${devices[*]}"
        
        # Extend existing VG
        if ! vgextend "$VG_NAME" "${devices[@]}" 2>vg.err; then
            log_error "Volume group extension failed"
            log "  Details: $(cat vg.err)"
            rm -f vg.err
            exit 1
        fi
        rm -f vg.err
        
        size=$(vgs --noheadings -o vg_size --units h "$VG_NAME" | tr -d ' ')
        log "  Success: Extended volume group"
        log "    Name: $VG_NAME"
        log "    Total size: $size"
    else
        log "Step 1: Creating new volume group"
        log "  Name: $VG_NAME"
        log "  Devices: ${devices[*]}"
        
        # Create new VG
        if ! vgcreate "$VG_NAME" "${devices[@]}" 2>vg.err; then
            log_error "Volume group creation failed"
            log "  Details: $(cat vg.err)"
            rm -f vg.err
            exit 1
        fi
        rm -f vg.err
        
        size=$(vgs --noheadings -o vg_size --units h "$VG_NAME" | tr -d ' ')
        log "  Success: Created volume group"
        log "    Name: $VG_NAME"
        log "    Size: $size"
    fi

    log_cmd "vgs $VG_NAME" "Volume group details"

    # Create logical volume using all available space
    if ! lvs "$VG_NAME/$LV_NAME" &>/dev/null; then
        log "Step 2: Creating logical volume"
        log "  Name: $LV_NAME"
        log "  Size: 100% of free space"
        
        # Create LV with yes flag
        if ! lvcreate -l 100%FREE -n "$LV_NAME" "$VG_NAME" -y 2>lv.err; then
            log_error "Logical volume creation failed"
            log "  Details: $(cat lv.err)"
            rm -f lv.err
            exit 1
        fi
        rm -f lv.err
        
        size=$(lvs --noheadings -o lv_size --units h "$VG_NAME/$LV_NAME" | tr -d ' ')
        log "  Success: Created logical volume"
        log "    Name: $LV_NAME"
        log "    Size: $size"
        log_cmd "lvs $VG_NAME/$LV_NAME" "Logical volume details"
    else
        log "Step 2: Logical volume already exists"
        log_cmd "lvs $VG_NAME/$LV_NAME" "Existing logical volume details"
    fi
    
    log "----------------------------------------"
}

# Function to create and mount filesystem
setup_filesystem() {
    local device="/dev/$VG_NAME/$LV_NAME"
    
    log "----------------------------------------"
    log "Starting filesystem setup"
    log "----------------------------------------"
    
    log "Step 1: Checking device status"
    log "  Device path: $device"
    
    # Wait for device to be available
    if ! wait_for_device "$device"; then
        exit 1
    fi
    
    # Check for existing /nsm directory
    if [[ -d "$MOUNT_POINT" ]]; then
        log "WARNING: $MOUNT_POINT directory already exists"
        if [[ -n "$(ls -A "$MOUNT_POINT")" ]]; then
            log "WARNING: $MOUNT_POINT is not empty"
            log "Contents will be hidden when mounted"
        fi
    fi
    
    # Check filesystem type - don't fail if blkid fails
    local fs_type
    fs_type=$(blkid -o value -s TYPE "$device" 2>/dev/null || echo "none")
    log "  Current filesystem type: ${fs_type:-none}"
    
        # Create XFS filesystem if needed
    log "Step 2: Filesystem preparation"
    if [[ "$fs_type" != "xfs" ]]; then
        log "  Creating new XFS filesystem:"
        log "    Device: $device"
        log "    Options: -f (force)"
        
        # Clean any existing signatures first
        wipefs -a "$device" 2>/dev/null || true
        
        # Create filesystem with force flag
        if ! mkfs.xfs -f "$device" -K -q 2>mkfs.err; then
            log_error "XFS filesystem creation failed"
            log "  Details: $(cat mkfs.err)"
            rm -f mkfs.err
            exit 1
        fi
        rm -f mkfs.err
        
        size=$(lvs --noheadings -o lv_size --units h "$VG_NAME/$LV_NAME" | tr -d ' ')
        log "  Success: Created XFS filesystem"
        log "    Device: $device"
        log "    Size: $size"
        
        # Verify filesystem was created
        fs_type=$(blkid -o value -s TYPE "$device")
        if [[ "$fs_type" != "xfs" ]]; then
            log_error "Failed to verify XFS filesystem creation"
            exit 1
        fi
        log "  Verified XFS filesystem"
    else
        log "  XFS filesystem already exists"
    fi

    # Create mount point
    log "Step 3: Mount point preparation"
    if [[ ! -d "$MOUNT_POINT" ]]; then
        log "  Creating mount point directory: $MOUNT_POINT"
        mkdir -p "$MOUNT_POINT"
        log "  Success: Directory created"
    else
        log "  Mount point already exists: $MOUNT_POINT"
    fi

    # Update fstab if needed
    log "Step 4: Configuring persistent mount"
    log "  Checking current fstab entries:"
    # Temporarily disable exit on error for fstab operations
    set +e
    
    # Check fstab entries without failing on no match
    if ! grep -P "^/dev/$VG_NAME/$LV_NAME\\s" /etc/fstab >/dev/null 2>&1; then
        log "  No existing fstab entry found"
    else
        log_cmd "grep -P '^/dev/$VG_NAME/$LV_NAME\\s' /etc/fstab" "Current configuration"
    fi
    
    # Check if we need to add fstab entry
    if ! grep -q "^$device.*$MOUNT_POINT" /etc/fstab >/dev/null 2>&1; then
        # Re-enable exit on error for critical operations
        set -e
        log "  Adding new fstab entry"
        local mount_options="rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota"
        echo "$device $MOUNT_POINT xfs $mount_options 0 0" >> /etc/fstab
        log "  Success: Added entry"
        log "    Device: $device"
        log "    Mount point: $MOUNT_POINT"
        log "    Options: $mount_options"
        log_cmd "grep -P \"^/dev/$VG_NAME/$LV_NAME\\s\" /etc/fstab" "New configuration"
        
        # Reload systemd to recognize new fstab entry
        log "  Reloading systemd to recognize new fstab entry"
        if ! systemctl daemon-reload; then
            log "  WARNING: Failed to reload systemd, continuing anyway"
        fi
    else
        log "  Existing fstab entry found"
        # Re-enable exit on error
        set -e
    fi

    # Mount the filesystem
    log "Step 5: Mounting filesystem"
    if ! mountpoint -q "$MOUNT_POINT"; then
        log "  Mounting $device to $MOUNT_POINT"
        if ! mount "$MOUNT_POINT" 2>mount.err; then
            log_error "Mount operation failed"
            log "  Details: $(cat mount.err)"
            rm -f mount.err
            exit 1
        fi
        rm -f mount.err
        
        size=$(df -h "$MOUNT_POINT" | awk 'NR==2 {print $2}')
        log "  Success: Filesystem mounted"
        log "    Device: $device"
        log "    Mount point: $MOUNT_POINT"
        log "    Size: $size"
        log_cmd "df -h $MOUNT_POINT" "Mount details"
    else
        log "  Filesystem already mounted"
        log_cmd "df -h $MOUNT_POINT" "Current mount details"
    fi
    
    log "----------------------------------------"
}

# Main function
main() {
    check_root
    
    # Set VG_NAME based on system UUID
    VG_NAME=$(get_system_uuid)

    # Check if already mounted
    if mountpoint -q "$MOUNT_POINT"; then
        size=$(df -h "$MOUNT_POINT" | awk 'NR==2 {print $2}')
        log "$MOUNT_POINT already mounted (size: $size)"
        log_cmd "df -h $MOUNT_POINT" "Current mount details"
        exit 0
    fi

    # Log initial system state with context
    log "----------------------------------------"
    log "Checking initial system state"
    log "NOTE: If any drives were previously used in another system, you may see"
    log "      warnings about missing devices or volume groups below. These warnings"
    log "      are normal and expected when reusing drives. They indicate the drive"
    log "      was part of a previous system's configuration and will be automatically"
    log "      cleaned up in the following steps."
    log "----------------------------------------"
    
    log_cmd "lsblk" "Block devices"
    log_cmd "pvs" "Physical volumes"
    log_cmd "vgs" "Volume groups"
    log_cmd "lvs" "Logical volumes"
    
    log "----------------------------------------"
    log "Proceeding with cleanup of any previous configurations and setup for /nsm"
    log "----------------------------------------"

    # Check if LVM is already configured
    if vgs "$VG_NAME" &>/dev/null && lvs "$VG_NAME/$LV_NAME" &>/dev/null; then
        log "Found existing LVM configuration"
        log "Proceeding with filesystem setup"
    else
        # Detect NVMe devices
        local -a devices=()
        mapfile -t devices < <(detect_nvme_devices)
        
        if [ ${#devices[@]} -eq 0 ]; then
            log_error "No NVMe devices found"
            exit 1
        fi

        # Prepare devices and get list of successfully prepared ones
        local -a prepared_devices=()
        mapfile -t prepared_devices < <(prepare_devices "${devices[@]}")
        
        if [ ${#prepared_devices[@]} -eq 0 ]; then
            if vgs "$VG_NAME" &>/dev/null && lvs "$VG_NAME/$LV_NAME" &>/dev/null; then
                log "Devices already configured, proceeding with filesystem setup"
            else
                log_error "No devices were successfully prepared and no existing configuration found"
                exit 1
            fi
        else
            # Setup LVM with prepared devices
            setup_lvm "${prepared_devices[@]}"
        fi
    fi
    
    # Create and mount filesystem
    setup_filesystem

    # Log final system state
    log "Final system state:"
    log_cmd "lsblk" "Block devices"
    log_cmd "pvs" "Physical volumes"
    log_cmd "vgs" "Volume groups"
    log_cmd "lvs" "Logical volumes"
    log_cmd "df -h $MOUNT_POINT" "Mount details"
}

# Run main function
main "$@"
