#!/bin/bash

#===============================================================================
# HDD Detection & Setup Script v1.0
# Detects unmounted HDDs, checks state, formats, mounts, creates folder structure
#
# This script safely prepares external/additional drives for Felhom homeserver:
#   - Detects unmounted block devices (HDDs and SSDs)
#   - Shows SMART health, partition tables, existing filesystems
#   - Formats with ext4 (only after explicit confirmation + safety checks)
#   - Mounts by UUID in /etc/fstab with proper options
#   - Creates standard Felhom media + storage folder structure
#
# Usage:
#   sudo ./hdd-setup.sh [OPTIONS]
#
# Options:
#   --scan              Scan and report only (no changes)
#   --mount-point PATH  Pre-set mount point (skip prompt)
#   --skip-smart        Skip SMART health check
#   --skip-folders      Skip folder structure creation
#   --dry-run           Show what would be done without making changes
#   --debug             Enable bash debug tracing (set -x)
#   -h, --help          Show this help message
#
# Safety:
#   - Never formats a drive with existing filesystems without triple confirmation
#   - Shows all existing data/partitions before any destructive action
#   - Writes fstab backup before modifications
#   - Uses nofail mount option to prevent boot failures
#   - All destructive operations require typing "YES" (not just y/n)
#
#===============================================================================

set -euo pipefail

#-------------------------------------------------------------------------------
# Configuration
#-------------------------------------------------------------------------------
SCRIPT_VERSION="1.0.1"

# Default values
SCAN_ONLY=false
PRESET_MOUNT_POINT=""
SKIP_SMART=false
SKIP_FOLDERS=false
DRY_RUN=false
DEBUG_MODE=false

# Folder structure owner (UID:GID for Docker containers, typically 1000:1000)
FOLDER_UID=1000
FOLDER_GID=1000

# Standard Felhom folder structure
declare -a MEDIA_DIRS=(
    "media/downloads/complete"
    "media/downloads/incomplete"
    "media/movies"
    "media/series"
    "media/music"
    "media/books"
)

declare -a STORAGE_DIRS=(
    "storage/immich"
    "storage/nextcloud"
    "storage/backups/local"
    "storage/backups/appdata"
)

declare -a USER_DIRS=(
    "Dokumentumok"
)

declare -a APPDATA_DIRS=(
    "appdata"
)

#-------------------------------------------------------------------------------
# Colors and logging (matching docker-setup.sh conventions)
#-------------------------------------------------------------------------------
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'

log_info()    { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn()    { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error()   { echo -e "${RED}[ERROR]${NC} $1"; }
log_step()    { echo -e "${BLUE}[STEP]${NC} $1"; }
log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
log_skip()    { echo -e "${CYAN}[SKIP]${NC} $1"; }
log_debug()   { if [[ "$DEBUG_MODE" == true ]]; then echo -e "${CYAN}[DEBUG]${NC} $1"; fi; }
log_danger()  { echo -e "${RED}${BOLD}[DANGER]${NC} $1"; }

#-------------------------------------------------------------------------------
# Error handling
#-------------------------------------------------------------------------------
on_error() {
    echo ""
    log_error "Script failed at line $1. Collecting diagnostics..."
    echo "--- Block Devices ---"
    lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT 2>/dev/null || true
    echo "--- /etc/fstab ---"
    cat /etc/fstab 2>/dev/null || true
    echo "--- Mount status ---"
    mount 2>/dev/null | grep -E "^/dev/" || true
}
trap 'on_error $LINENO' ERR

# Cleanup trap for temp files
TEMP_FILES=()
LOCK_FILE="/tmp/.hdd_setup.lock"
cleanup() {
    rm -f /tmp/.hdd_setup_part_dev 2>/dev/null || true
    rm -f "$LOCK_FILE" 2>/dev/null || true
    for f in "${TEMP_FILES[@]}"; do
        rm -f "$f" 2>/dev/null || true
    done
}
trap cleanup EXIT

#-------------------------------------------------------------------------------
# Helpers
#-------------------------------------------------------------------------------
print_banner() {
    echo ""
    echo -e "${BOLD}${BLUE}-==================================================================¬${NC}"
    echo -e "${BOLD}${BLUE}¦           HDD Detection & Setup Script v${SCRIPT_VERSION}                    ¦${NC}"
    echo -e "${BOLD}${BLUE}L==================================================================-${NC}"
    echo ""
}

print_help() {
    cat << 'EOF'
HDD Detection & Setup Script v1.0

Safely detects, formats, mounts, and prepares external drives for Felhom homeserver.

USAGE:
    sudo ./hdd-setup.sh [OPTIONS]

OPTIONS:
    --scan              Scan and report only (no changes made)
    --mount-point PATH  Pre-set mount point (e.g., /mnt/hdd_1)
    --skip-smart        Skip SMART health check
    --skip-folders      Skip folder structure creation
    --dry-run           Show what would be done without making changes
    --debug             Enable verbose debug output
    -h, --help          Show this help

WHAT THIS SCRIPT DOES:
    1. Detects unmounted block devices
    2. Shows disk info (size, partitions, SMART health)
    3. Lets you select a disk to set up
    4. Formats with ext4 (with safety confirmations)
    5. Mounts via UUID in /etc/fstab (with nofail)
    6. Creates Felhom folder structure

FOLDER STRUCTURE CREATED:
    <mount_point>/
    ├── Dokumentumok/
    ├── media/
    │   ├── downloads/complete/
    │   ├── downloads/incomplete/
    │   ├── movies/
    │   ├── series/
    │   ├── music/
    │   └── books/
    ├── storage/
    │   ├── immich/
    │   ├── nextcloud/
    │   └── backups/
    │       ├── local/
    │       └── appdata/
    └── appdata/

SAFETY:
    - Drives with existing data require typing "YES" to format
    - fstab is backed up before any modification
    - Uses 'nofail' mount option (system boots even if drive missing)
    - --scan mode for non-destructive inspection

EOF
    exit 0
}

parse_args() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            --scan)         SCAN_ONLY=true; shift ;;
            --mount-point)  PRESET_MOUNT_POINT="$2"; shift 2 ;;
            --skip-smart)   SKIP_SMART=true; shift ;;
            --skip-folders) SKIP_FOLDERS=true; shift ;;
            --dry-run)      DRY_RUN=true; shift ;;
            --debug)        DEBUG_MODE=true; shift ;;
            -h|--help)      print_help ;;
            *)              log_error "Unknown option: $1"; print_help ;;
        esac
    done
}

check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "This script must be run as root (use sudo)"
        exit 1
    fi
}

install_dependencies() {
    local missing=()

    # smartmontools for SMART data
    if ! command -v smartctl &> /dev/null && [[ "$SKIP_SMART" == false ]]; then
        missing+=("smartmontools")
    fi

    # parted for partition inspection
    if ! command -v parted &> /dev/null; then
        missing+=("parted")
    fi

    # util-linux should be present, but check for blkid/lsblk
    if ! command -v blkid &> /dev/null; then
        missing+=("util-linux")
    fi

    if [[ ${#missing[@]} -gt 0 ]]; then
        log_info "Installing missing dependencies: ${missing[*]}"
        if [[ "$DRY_RUN" == true ]]; then
            log_info "[DRY RUN] Would install: ${missing[*]}"
            return
        fi
        apt-get update -qq
        apt-get install -qq -y "${missing[@]}" > /dev/null 2>&1
        log_success "Dependencies installed"
    fi
}

#-------------------------------------------------------------------------------
# Disk detection
#-------------------------------------------------------------------------------

# Get the device name of the root filesystem (e.g., "sda")
get_root_disk() {
    local root_dev
    root_dev=$(findmnt -n -o SOURCE / 2>/dev/null | head -1)

    # Handle LVM: /dev/mapper/vg-root -> find underlying PV
    if [[ "$root_dev" == /dev/mapper/* ]]; then
        if command -v pvs &> /dev/null; then
            root_dev=$(pvs --noheadings -o pv_name 2>/dev/null | head -1 | tr -d ' ')
        fi
    fi

    # Handle partitions: /dev/sda2 -> sda, /dev/nvme0n1p2 -> nvme0n1
    local disk_name
    disk_name=$(lsblk -no PKNAME "$root_dev" 2>/dev/null | head -1)

    if [[ -z "$disk_name" ]]; then
        # Fallback: strip partition number
        disk_name=$(echo "$root_dev" | sed 's|/dev/||' | sed 's/[0-9]*$//' | sed 's/p$//')
    fi

    echo "$disk_name"
}

# Get list of disks that are NOT the system disk and NOT mounted
get_candidate_disks() {
    local root_disk
    root_disk=$(get_root_disk)
    log_debug "Root disk detected as: $root_disk"

    local candidates=()

    # Iterate over whole-disk block devices (not partitions)
    while IFS= read -r line; do
        local name size type
        name=$(echo "$line" | awk '{print $1}')
        size=$(echo "$line" | awk '{print $2}')
        type=$(echo "$line" | awk '{print $3}')

        # Skip if this IS the root disk
        if [[ "$name" == "$root_disk" ]]; then
            log_debug "Skipping $name (root disk)"
            continue
        fi

        # Skip if type is not "disk"
        if [[ "$type" != "disk" ]]; then
            log_debug "Skipping $name (type: $type)"
            continue
        fi

        # Skip very small devices (<1GB) - likely USB sticks with boot media, etc.
        local size_bytes
        size_bytes=$(lsblk -bno SIZE "/dev/$name" 2>/dev/null | head -1)
        if [[ -n "$size_bytes" ]] && [[ "$size_bytes" -lt 1073741824 ]]; then
            log_debug "Skipping $name (too small: $size)"
            continue
        fi

        # Skip loop, ram, zram devices
        if [[ "$name" =~ ^(loop|ram|zram) ]]; then
            log_debug "Skipping $name (virtual device)"
            continue
        fi

        # Check if ANY partition of this disk is mounted
        local any_mounted=false
        while IFS= read -r part_line; do
            local part_name part_mount
            part_name=$(echo "$part_line" | awk '{print $1}')
            part_mount=$(echo "$part_line" | awk '{print $7}')
            if [[ -n "$part_mount" ]]; then
                any_mounted=true
                log_debug "Skipping $name (partition $part_name mounted at $part_mount)"
                break
            fi
        done < <(lsblk -lno NAME,MAJ:MIN,RM,SIZE,RO,TYPE,MOUNTPOINT "/dev/$name" 2>/dev/null | tail -n +2)

        # Also check if the disk itself is mounted (whole-disk filesystem)
        local disk_mount
        disk_mount=$(lsblk -lno MOUNTPOINT "/dev/$name" 2>/dev/null | head -1)
        if [[ -n "$disk_mount" ]]; then
            any_mounted=true
            log_debug "Skipping $name (disk mounted at $disk_mount)"
        fi

        if [[ "$any_mounted" == true ]]; then
            continue
        fi

        candidates+=("$name")

    done < <(lsblk -lno NAME,SIZE,TYPE 2>/dev/null | grep ' disk$')

    echo "${candidates[@]}"
}

#-------------------------------------------------------------------------------
# Disk inspection
#-------------------------------------------------------------------------------

print_disk_info() {
    local disk="$1"
    local dev="/dev/$disk"

    echo ""
    echo -e "${BOLD}${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${BOLD} Disk: /dev/$disk${NC}"
    echo -e "${BOLD}${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"

    # Basic info
    local size model serial rotational transport
    size=$(lsblk -dno SIZE "$dev" 2>/dev/null | tr -d ' ')
    model=$(lsblk -dno MODEL "$dev" 2>/dev/null | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')
    serial=$(lsblk -dno SERIAL "$dev" 2>/dev/null | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')
    rotational=$(cat /sys/block/"$disk"/queue/rotational 2>/dev/null || echo "?")
    transport=$(lsblk -dno TRAN "$dev" 2>/dev/null | tr -d ' ')

    local disk_type="Unknown"
    if [[ "$rotational" == "1" ]]; then
        disk_type="HDD (rotational)"
    elif [[ "$rotational" == "0" ]]; then
        disk_type="SSD (non-rotational)"
    fi

    echo -e "  ${BOLD}Size:${NC}      $size"
    echo -e "  ${BOLD}Model:${NC}     ${model:-Unknown}"
    echo -e "  ${BOLD}Serial:${NC}    ${serial:-Unknown}"
    echo -e "  ${BOLD}Type:${NC}      $disk_type"
    echo -e "  ${BOLD}Transport:${NC} ${transport:-Unknown}"

    # Partition table
    echo ""
    echo -e "  ${BOLD}Partition layout:${NC}"
    local part_output
    part_output=$(lsblk -o NAME,SIZE,TYPE,FSTYPE,LABEL,MOUNTPOINT "$dev" 2>/dev/null)
    echo "$part_output" | sed 's/^/    /'

    # Check for existing filesystems on whole disk and partitions
    echo ""
    echo -e "  ${BOLD}Filesystem detection:${NC}"
    local has_data=false

    # Check whole disk
    local whole_fs
    whole_fs=$(blkid -o value -s TYPE "$dev" 2>/dev/null || echo "")
    if [[ -n "$whole_fs" ]]; then
        local whole_label
        whole_label=$(blkid -o value -s LABEL "$dev" 2>/dev/null || echo "")
        echo -e "    ${YELLOW}$dev: filesystem=$whole_fs label=${whole_label:-<none>}${NC}"
        has_data=true
    fi

    # Check each partition
    while IFS= read -r part; do
        [[ -z "$part" ]] && continue
        local part_dev="/dev/$part"
        local part_fs part_label part_uuid
        part_fs=$(blkid -o value -s TYPE "$part_dev" 2>/dev/null || echo "")
        part_label=$(blkid -o value -s LABEL "$part_dev" 2>/dev/null || echo "")
        part_uuid=$(blkid -o value -s UUID "$part_dev" 2>/dev/null || echo "")
        if [[ -n "$part_fs" ]]; then
            echo -e "    ${YELLOW}$part_dev: filesystem=$part_fs label=${part_label:-<none>} uuid=${part_uuid:-<none>}${NC}"
            has_data=true
        else
            echo -e "    $part_dev: ${GREEN}no filesystem detected${NC}"
        fi
    done < <(lsblk -lno NAME "$dev" 2>/dev/null | tail -n +2)

    if [[ "$has_data" == false ]]; then
        echo -e "    ${GREEN}No filesystems detected (clean disk)${NC}"
    fi

    # SMART health
    if [[ "$SKIP_SMART" == false ]] && command -v smartctl &> /dev/null; then
        echo ""
        echo -e "  ${BOLD}SMART Health:${NC}"
        local smart_output
        smart_output=$(smartctl -H "$dev" 2>/dev/null || echo "SMART not available")

        if echo "$smart_output" | grep -q "PASSED"; then
            echo -e "    ${GREEN}SMART overall: PASSED${NC}"
        elif echo "$smart_output" | grep -q "FAILED"; then
            echo -e "    ${RED}${BOLD}SMART overall: FAILED - DO NOT USE THIS DISK${NC}"
        else
            echo -e "    ${YELLOW}SMART: Not available (USB enclosures often don't support SMART)${NC}"
        fi

        # Show key SMART attributes if available
        local reallocated power_on temp
        reallocated=$(smartctl -A "$dev" 2>/dev/null | grep -i "Reallocated_Sector" | awk '{print $NF}' || echo "")
        power_on=$(smartctl -A "$dev" 2>/dev/null | grep -i "Power_On_Hours" | awk '{print $NF}' || echo "")
        temp=$(smartctl -A "$dev" 2>/dev/null | grep -i "Temperature_Celsius" | awk '{print $NF}' || echo "")

        if [[ -n "$reallocated" ]]; then
            if [[ "$reallocated" -gt 0 ]] 2>/dev/null; then
                echo -e "    ${YELLOW}Reallocated sectors: $reallocated (some wear detected)${NC}"
            else
                echo -e "    Reallocated sectors: $reallocated"
            fi
        fi
        [[ -n "$power_on" ]] && echo "    Power-on hours: $power_on"
        [[ -n "$temp" ]] && echo "    Temperature: ${temp}°C"
    fi

    # Return whether disk has data (for caller to use)
    if [[ "$has_data" == true ]]; then
        return 1
    else
        return 0
    fi
}

#-------------------------------------------------------------------------------
# Disk formatting
#-------------------------------------------------------------------------------

# Check if a disk has any filesystem signatures anywhere
disk_has_data() {
    local disk="$1"
    local dev="/dev/$disk"

    # Check whole disk
    if blkid "$dev" &>/dev/null; then
        return 0  # has data
    fi

    # Check all partitions
    while IFS= read -r part; do
        [[ -z "$part" ]] && continue
        if blkid "/dev/$part" &>/dev/null; then
            return 0  # has data
        fi
    done < <(lsblk -lno NAME "$dev" 2>/dev/null | tail -n +2)

    return 1  # no data
}

# Check if disk is referenced anywhere in fstab
disk_in_fstab() {
    local disk="$1"
    local dev="/dev/$disk"

    # Check by device path
    if grep -q "$dev" /etc/fstab 2>/dev/null; then
        return 0
    fi

    # Check by UUID of any partition
    while IFS= read -r part; do
        [[ -z "$part" ]] && continue
        local part_uuid
        part_uuid=$(blkid -o value -s UUID "/dev/$part" 2>/dev/null || echo "")
        if [[ -n "$part_uuid" ]] && grep -q "$part_uuid" /etc/fstab 2>/dev/null; then
            return 0
        fi
    done < <(lsblk -lno NAME "$dev" 2>/dev/null | tail -n +2)

    # Check whole disk UUID
    local disk_uuid
    disk_uuid=$(blkid -o value -s UUID "$dev" 2>/dev/null || echo "")
    if [[ -n "$disk_uuid" ]] && grep -q "$disk_uuid" /etc/fstab 2>/dev/null; then
        return 0
    fi

    return 1
}

format_disk() {
    local disk="$1"
    local dev="/dev/$disk"

    echo ""
    log_step "Preparing to format /dev/$disk"

    # Safety check: Is the disk part of a RAID array?
    if command -v mdadm &>/dev/null; then
        if mdadm --examine "$dev" &>/dev/null || mdadm --examine "${dev}"* &>/dev/null 2>&1; then
            log_error "Disk /dev/$disk appears to be part of a RAID array!"
            log_error "Remove it from the array first with: mdadm --zero-superblock $dev"
            return 1
        fi
    fi
    # Check for RAID signatures via blkid
    if blkid "$dev" 2>/dev/null | grep -qi "linux_raid_member"; then
        log_error "Disk /dev/$disk has a RAID superblock! Cannot format."
        return 1
    fi

    # Safety check: Is the disk used by LVM?
    if command -v pvs &>/dev/null; then
        if pvs "$dev" &>/dev/null 2>&1 || pvs "${dev}"* &>/dev/null 2>&1; then
            log_error "Disk /dev/$disk is an LVM physical volume!"
            log_error "Remove it first with: pvremove $dev"
            return 1
        fi
    fi

    # Safety check: Is the disk or any partition currently in use?
    if lsof "$dev"* 2>/dev/null | grep -q .; then
        log_error "Disk /dev/$disk has open file handles! Cannot proceed."
        log_error "Another process is using this disk."
        return 1
    fi

    # Safety check: Is it in fstab?
    if disk_in_fstab "$disk"; then
        log_warn "This disk is referenced in /etc/fstab!"
        grep -E "(${dev}|$(blkid -o value -s UUID "$dev" 2>/dev/null || echo 'NOUUID'))" /etc/fstab 2>/dev/null | sed 's/^/    /'
        echo ""
        log_warn "Proceeding will remove the old fstab entry."
    fi

    local has_existing_data=false
    if disk_has_data "$disk"; then
        has_existing_data=true
    fi

    if [[ "$has_existing_data" == true ]]; then
        echo ""
        log_danger "═══════════════════════════════════════════════════════════════"
        log_danger "  THIS DISK CONTAINS DATA! Formatting will DESTROY everything."
        log_danger "═══════════════════════════════════════════════════════════════"
        echo ""
        echo -e "  Disk: ${BOLD}/dev/$disk${NC}"
        echo -e "  Existing filesystems:"
        blkid "$dev"* 2>/dev/null | sed 's/^/    /' || true
        echo ""

        # First confirmation
        echo -e "${RED}${BOLD}Type the disk name (e.g., sdb) to confirm you want to DESTROY ALL DATA:${NC}"
        read -r confirm_name
        if [[ "$confirm_name" != "$disk" ]]; then
            log_info "Disk name did not match. Aborting format."
            return 1
        fi

        # Second confirmation
        echo -e "${RED}${BOLD}Type YES (uppercase) to confirm formatting /dev/$disk:${NC}"
        read -r confirm_yes
        if [[ "$confirm_yes" != "YES" ]]; then
            log_info "Confirmation not received. Aborting format."
            return 1
        fi
    else
        echo ""
        echo "This disk appears empty (no filesystems detected)."
        read -p "Format /dev/$disk with ext4? [y/N] " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            log_info "Skipping format."
            return 1
        fi
    fi

    if [[ "$DRY_RUN" == true ]]; then
        log_info "[DRY RUN] Would format /dev/$disk with ext4"
        return 0
    fi

    log_info "Wiping existing partition table on /dev/$disk..."
    wipefs -a "$dev" 2>/dev/null || true

    log_info "Creating GPT partition table..."
    parted -s "$dev" mklabel gpt

    log_info "Creating single ext4 partition spanning entire disk..."
    parted -s "$dev" mkpart primary ext4 0% 100%

    # Wait for kernel to pick up partition
    sleep 2
    partprobe "$dev" 2>/dev/null || true
    sleep 1

    # Determine partition device name (sdb1 or nvme0n1p1)
    local part_dev=""
    # Try common naming patterns
    if [[ -b "${dev}1" ]]; then
        part_dev="${dev}1"
    elif [[ -b "${dev}p1" ]]; then
        part_dev="${dev}p1"
    else
        # Wait a bit more and retry
        sleep 3
        partprobe "$dev" 2>/dev/null || true
        if [[ -b "${dev}1" ]]; then
            part_dev="${dev}1"
        elif [[ -b "${dev}p1" ]]; then
            part_dev="${dev}p1"
        else
            log_error "Could not find partition device after partitioning!"
            log_error "Expected ${dev}1 or ${dev}p1"
            lsblk "$dev"
            return 1
        fi
    fi

    log_info "Formatting ${part_dev} as ext4..."
    mkfs.ext4 -F -L "felhom_data" "$part_dev"

    log_success "Disk formatted successfully"
    echo "  Partition: $part_dev"
    echo "  Filesystem: ext4"
    echo "  Label: felhom_data"

    # Return the partition device for mounting
    echo "$part_dev" > /tmp/.hdd_setup_part_dev
    return 0
}

#-------------------------------------------------------------------------------
# Mount point selection and mounting
#-------------------------------------------------------------------------------

suggest_mount_point() {
    # Find next available /mnt/hdd_N
    local n=1
    while [[ -d "/mnt/hdd_${n}" ]] && mountpoint -q "/mnt/hdd_${n}" 2>/dev/null; do
        ((n++))
    done

    # If dir exists but not mounted, it might be a leftover — still suggest it
    if [[ -d "/mnt/hdd_${n}" ]] && [[ -z "$(ls -A /mnt/hdd_${n} 2>/dev/null)" ]]; then
        echo "/mnt/hdd_${n}"
    elif [[ ! -d "/mnt/hdd_${n}" ]]; then
        echo "/mnt/hdd_${n}"
    else
        # Directory exists and has content, try next
        ((n++))
        echo "/mnt/hdd_${n}"
    fi
}

select_mount_point() {
    local mount_point=""

    if [[ -n "$PRESET_MOUNT_POINT" ]]; then
        mount_point="$PRESET_MOUNT_POINT"
        log_info "Using pre-set mount point: $mount_point" >&2
    else
        local suggested
        suggested=$(suggest_mount_point)

        echo "" >&2
        log_step "Select mount point" >&2
        echo "" >&2
        echo "  Suggested: $suggested" >&2
        echo "" >&2
        read -rp "  Enter mount point [${suggested}]: " user_mount
        mount_point="${user_mount:-$suggested}"
    fi

    # Validate mount point
    if [[ ! "$mount_point" =~ ^/ ]]; then
        log_error "Mount point must be an absolute path (start with /)" >&2
        return 1
    fi

    # Check if something is already mounted there
    if mountpoint -q "$mount_point" 2>/dev/null; then
        log_error "$mount_point is already a mount point!" >&2
        mount | grep "$mount_point" >&2
        return 1
    fi

    # Check if directory exists and has content
    if [[ -d "$mount_point" ]] && [[ -n "$(ls -A "$mount_point" 2>/dev/null)" ]]; then
        log_warn "$mount_point exists and is not empty!" >&2
        ls -la "$mount_point" >&2
        echo "" >&2
        log_warn "Mounting here will HIDE existing content (it won't be deleted, but inaccessible while mounted)." >&2
        read -p "Continue with this mount point? [y/N] " -n 1 -r
        echo >&2
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            return 1
        fi
    fi

    echo "$mount_point"
}

mount_disk() {
    local part_dev="$1"
    local mount_point="$2"

    echo ""
    log_step "Mounting $part_dev at $mount_point"

    # Get UUID
    local uuid
    uuid=$(blkid -o value -s UUID "$part_dev" 2>/dev/null)
    if [[ -z "$uuid" ]]; then
        log_error "Could not determine UUID for $part_dev"
        return 1
    fi

    log_info "Partition UUID: $uuid"

    if [[ "$DRY_RUN" == true ]]; then
        log_info "[DRY RUN] Would create $mount_point"
        log_info "[DRY RUN] Would add to /etc/fstab: UUID=$uuid $mount_point ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 2"
        log_info "[DRY RUN] Would mount $part_dev at $mount_point"
        return 0
    fi

    # Create mount point
    mkdir -p "$mount_point"

    # Backup fstab
    local fstab_backup
    fstab_backup="/etc/fstab.backup.$(date +%Y%m%d_%H%M%S)"
    cp /etc/fstab "$fstab_backup"
    log_info "fstab backed up to: $fstab_backup"

    # Remove any existing entry for this UUID (in case of re-setup)
    if grep -q "$uuid" /etc/fstab 2>/dev/null; then
        log_warn "Removing existing fstab entry for UUID=$uuid"
        sed -i "\|$uuid|d" /etc/fstab
    fi

    # Add fstab entry
    # nofail: system boots even if drive is missing
    # x-systemd.device-timeout=10: don't wait forever during boot
    # noatime: skip updating access timestamps (better performance)
    local fstab_entry="UUID=$uuid  $mount_point  ext4  defaults,noatime,nofail,x-systemd.device-timeout=10  0  2"

    {
        echo ""
        echo "# Felhom data drive - added by hdd-setup.sh on $(date '+%Y-%m-%d %H:%M:%S')"
        echo "$fstab_entry"
    } >> /etc/fstab

    log_info "Added to /etc/fstab:"
    echo "  $fstab_entry"

    # Verify fstab syntax (multiple methods - findmnt segfaults on some Debian 13 builds)
    local fstab_ok=false
    
    # Method 1: findmnt --verify (preferred, but may segfault on trixie)
    local verify_exit=0
    findmnt --verify --tab-file /etc/fstab &>/dev/null || verify_exit=$?
    if [[ $verify_exit -eq 0 ]]; then
        fstab_ok=true
        log_debug "fstab verified via findmnt"
    elif [[ $verify_exit -eq 139 ]] || [[ $verify_exit -gt 128 ]]; then
        log_debug "findmnt segfaulted (exit $verify_exit), falling back to mount --fake"
    fi
    
    # Method 2: mount --fake -a (dry-run mount test)
    if [[ "$fstab_ok" == false ]]; then
        if mount --fake -a &>/dev/null; then
            fstab_ok=true
            log_debug "fstab verified via mount --fake"
        fi
    fi
    
    # Method 3: Basic sanity check on the entry we just wrote
    if [[ "$fstab_ok" == false ]]; then
        # Verify our entry has all required fields (UUID, mountpoint, fstype, options, dump, pass)
        local field_count
        field_count=$(echo "$fstab_entry" | awk '{print NF}')
        if [[ "$field_count" -eq 6 ]] && [[ "$fstab_entry" == UUID=* ]]; then
            fstab_ok=true
            log_debug "fstab verified via field count sanity check"
        fi
    fi
    
    if [[ "$fstab_ok" == false ]]; then
        log_error "fstab verification failed! Restoring backup..."
        cp "$fstab_backup" /etc/fstab
        log_info "fstab restored from backup"
        return 1
    fi
    log_success "fstab syntax verified"

    # Mount
    mount "$mount_point"

    if mountpoint -q "$mount_point"; then
        log_success "Disk mounted at $mount_point"

        # Show mounted disk info
        df -h "$mount_point" | sed 's/^/  /'
    else
        log_error "Mount failed! Check dmesg for errors."
        dmesg | tail -5
        return 1
    fi
}

#-------------------------------------------------------------------------------
# Folder structure creation
#-------------------------------------------------------------------------------

create_folder_structure() {
    local mount_point="$1"

    echo ""
    log_step "Creating Felhom folder structure at $mount_point"
    echo ""
    echo -e "  ${BOLD}Planned structure:${NC}"
    echo "  $mount_point/"

    for dir in "${USER_DIRS[@]}"; do
        echo "  ├── $dir/"
    done
    for dir in "${MEDIA_DIRS[@]}"; do
        echo "  ├── $dir/"
    done
    for dir in "${STORAGE_DIRS[@]}"; do
        echo "  ├── $dir/"
    done
    for dir in "${APPDATA_DIRS[@]}"; do
        echo "  └── $dir/"
    done

    echo ""
    echo "  Owner: ${FOLDER_UID}:${FOLDER_GID} (standard Docker user)"
    echo ""

    if [[ "$DRY_RUN" == true ]]; then
        log_info "[DRY RUN] Would create the above folder structure"
        return 0
    fi

    read -p "Create this folder structure? [Y/n] " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Nn]$ ]]; then
        log_skip "Folder structure creation skipped"
        return 0
    fi

    for dir in "${USER_DIRS[@]}" "${MEDIA_DIRS[@]}" "${STORAGE_DIRS[@]}" "${APPDATA_DIRS[@]}"; do
        mkdir -p "${mount_point}/${dir}"
        log_debug "Created: ${mount_point}/${dir}"
    done

    # Set ownership recursively
    chown -R "${FOLDER_UID}:${FOLDER_GID}" "$mount_point"

    # Set permissions: owner rwx, group rwx, others r-x
    # This allows Docker containers running as 1000:1000 to read/write
    chmod -R 775 "$mount_point"

    # Verify
    local created_count
    created_count=$(find "$mount_point" -type d | wc -l)
    log_success "Folder structure created ($created_count directories)"

    echo ""
    echo -e "  ${BOLD}Result:${NC}"
    # Use find to show the tree structure (works without 'tree' command)
    (cd "$mount_point" && find . -type d -maxdepth 3 | sort | sed 's|^\.||' | sed 's|/|  |g' | sed 's/^/    /')
}

#-------------------------------------------------------------------------------
# Existing partition handling
#-------------------------------------------------------------------------------

# Handle a disk that already has a usable ext4 partition
handle_existing_partition() {
    local disk="$1"
    local dev="/dev/$disk"

    echo ""
    log_step "Checking for usable existing partitions on /dev/$disk"

    local usable_parts=()
    local part_info=()

    # Check whole disk for ext4
    local whole_fs
    whole_fs=$(blkid -o value -s TYPE "$dev" 2>/dev/null || echo "")
    if [[ "$whole_fs" == "ext4" ]]; then
        usable_parts+=("$dev")
        local whole_label whole_uuid
        whole_label=$(blkid -o value -s LABEL "$dev" 2>/dev/null || echo "<none>")
        whole_uuid=$(blkid -o value -s UUID "$dev" 2>/dev/null || echo "")
        part_info+=("$dev  fs=ext4  label=$whole_label  uuid=$whole_uuid")
    fi

    # Check partitions
    while IFS= read -r part; do
        [[ -z "$part" ]] && continue
        local part_dev="/dev/$part"
        local part_fs
        part_fs=$(blkid -o value -s TYPE "$part_dev" 2>/dev/null || echo "")
        if [[ "$part_fs" == "ext4" ]]; then
            usable_parts+=("$part_dev")
            local p_label p_uuid
            p_label=$(blkid -o value -s LABEL "$part_dev" 2>/dev/null || echo "<none>")
            p_uuid=$(blkid -o value -s UUID "$part_dev" 2>/dev/null || echo "")
            part_info+=("$part_dev  fs=ext4  label=$p_label  uuid=$p_uuid")
        fi
    done < <(lsblk -lno NAME "$dev" 2>/dev/null | tail -n +2)

    if [[ ${#usable_parts[@]} -eq 0 ]]; then
        return 1  # No usable ext4 partitions
    fi

    echo ""
    echo -e "  ${GREEN}Found usable ext4 partition(s):${NC}"
    for info in "${part_info[@]}"; do
        echo "    $info"
    done
    echo ""

    echo "Options:"
    echo "  1) Use existing ext4 partition (no format, no data loss)"
    echo "  2) Wipe and reformat the entire disk"
    echo "  3) Cancel"
    echo ""
    read -rp "Choose [1/2/3]: " choice

    case "$choice" in
        1)
            # Use the first (or only) usable ext4 partition
            local selected_part="${usable_parts[0]}"
            if [[ ${#usable_parts[@]} -gt 1 ]]; then
                echo ""
                echo "Multiple ext4 partitions found. Select one:"
                for i in "${!usable_parts[@]}"; do
                    echo "  $((i+1))) ${part_info[$i]}"
                done
                read -rp "Choose [1-${#usable_parts[@]}]: " part_choice
                local idx=$((part_choice - 1))
                if [[ $idx -ge 0 && $idx -lt ${#usable_parts[@]} ]]; then
                    selected_part="${usable_parts[$idx]}"
                else
                    log_error "Invalid selection"
                    return 1
                fi
            fi

            log_info "Using existing partition: $selected_part"

            # Run fsck before mounting
            log_info "Running filesystem check on $selected_part..."
            if ! fsck.ext4 -n "$selected_part" 2>/dev/null; then
                log_warn "Filesystem has issues. Run 'fsck.ext4 -y $selected_part' manually to fix."
                read -p "Try auto-fix now? [y/N] " -n 1 -r
                echo
                if [[ $REPLY =~ ^[Yy]$ ]]; then
                    fsck.ext4 -y "$selected_part" || true
                fi
            else
                log_success "Filesystem check passed"
            fi

            echo "$selected_part" > /tmp/.hdd_setup_part_dev
            return 0
            ;;
        2)
            # Will proceed to format
            return 1
            ;;
        3)
            log_info "Cancelled."
            exit 0
            ;;
        *)
            log_error "Invalid choice"
            return 1
            ;;
    esac
}

#-------------------------------------------------------------------------------
# Main flow
#-------------------------------------------------------------------------------

main() {
    parse_args "$@"
    check_root

    # Logging
    LOG_FILE="/var/log/hdd-setup.log"
    mkdir -p /var/log 2>/dev/null || true
    exec > >(tee -a "$LOG_FILE") 2>&1

    if [[ "$DEBUG_MODE" == true ]]; then
        set -x
    fi

    print_banner

    # Prevent concurrent runs
    if [[ -f "$LOCK_FILE" ]]; then
        local lock_pid
        lock_pid=$(cat "$LOCK_FILE" 2>/dev/null || echo "")
        if [[ -n "$lock_pid" ]] && kill -0 "$lock_pid" 2>/dev/null; then
            log_error "Another instance is already running (PID: $lock_pid)"
            log_error "If this is incorrect, remove $LOCK_FILE"
            exit 1
        fi
    fi
    echo $$ > "$LOCK_FILE"

    if [[ "$DRY_RUN" == true ]]; then
        echo -e "${YELLOW}DRY RUN MODE - no changes will be made${NC}"
        echo ""
    fi

    install_dependencies

    #---------------------------------------------------------------------------
    # Phase 1: Detect candidate disks
    #---------------------------------------------------------------------------
    log_step "Phase 1: Scanning for unmounted disks..."

    local root_disk
    root_disk=$(get_root_disk)
    log_info "System disk: /dev/$root_disk (will be excluded)"

    local candidates_str
    candidates_str=$(get_candidate_disks)

    if [[ -z "$candidates_str" ]]; then
        echo ""
        log_warn "No unmounted disks found!"
        echo ""
        echo "  All detected disks:"
        lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT | sed 's/^/    /'
        echo ""
        echo "  Possible reasons:"
        echo "  - All disks are already mounted"
        echo "  - External drive not connected/detected"
        echo "  - Drive may need a different driver"
        echo ""
        echo "  Troubleshooting:"
        echo "    dmesg | tail -20    # Check kernel messages"
        echo "    lsusb               # Check USB devices"
        echo "    lsblk               # Full block device list"
        exit 0
    fi

    # Convert to array
    read -ra candidates <<< "$candidates_str"

    echo ""
    log_info "Found ${#candidates[@]} unmounted disk(s)"

    #---------------------------------------------------------------------------
    # Phase 2: Show disk information
    #---------------------------------------------------------------------------
    log_step "Phase 2: Inspecting disks..."

    local disk_has_data_map=()
    for disk in "${candidates[@]}"; do
        local has_data=false
        print_disk_info "$disk" || has_data=true
        disk_has_data_map+=("$has_data")
    done

    if [[ "$SCAN_ONLY" == true ]]; then
        echo ""
        echo -e "${BOLD}${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo -e "${BOLD} Scan complete. Use without --scan to set up a disk.${NC}"
        echo -e "${BOLD}${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        exit 0
    fi

    #---------------------------------------------------------------------------
    # Phase 3: Select disk
    #---------------------------------------------------------------------------
    echo ""
    log_step "Phase 3: Select a disk to set up"
    echo ""

    if [[ ${#candidates[@]} -eq 1 ]]; then
        echo "  Only one unmounted disk found: /dev/${candidates[0]}"
        read -p "  Set up this disk? [Y/n] " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Nn]$ ]]; then
            log_info "Cancelled."
            exit 0
        fi
        selected_disk="${candidates[0]}"
    else
        echo "  Available disks:"
        for i in "${!candidates[@]}"; do
            local d="${candidates[$i]}"
            local s
            s=$(lsblk -dno SIZE "/dev/$d" 2>/dev/null | tr -d ' ')
            local m
            m=$(lsblk -dno MODEL "/dev/$d" 2>/dev/null | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')
            echo "    $((i+1))) /dev/$d  ($s, ${m:-Unknown})"
        done
        echo ""
        read -rp "  Select disk [1-${#candidates[@]}]: " disk_choice
        local idx=$((disk_choice - 1))
        if [[ $idx -lt 0 || $idx -ge ${#candidates[@]} ]]; then
            log_error "Invalid selection"
            exit 1
        fi
        selected_disk="${candidates[$idx]}"
    fi

    log_info "Selected: /dev/$selected_disk"

    #---------------------------------------------------------------------------
    # Phase 4: Format or use existing
    #---------------------------------------------------------------------------
    log_step "Phase 4: Prepare filesystem"

    local part_dev=""

    # Check if disk already has a usable ext4 partition
    if handle_existing_partition "$selected_disk"; then
        # User chose to use existing partition
        part_dev=$(cat /tmp/.hdd_setup_part_dev 2>/dev/null)
        rm -f /tmp/.hdd_setup_part_dev
    else
        # Need to format
        if format_disk "$selected_disk"; then
            part_dev=$(cat /tmp/.hdd_setup_part_dev 2>/dev/null)
            rm -f /tmp/.hdd_setup_part_dev
        else
            log_error "Format failed or was cancelled."
            exit 1
        fi
    fi

    if [[ -z "$part_dev" ]] && [[ "$DRY_RUN" == false ]]; then
        log_error "No partition device determined. Cannot proceed."
        exit 1
    fi

    # For dry run, simulate a partition device
    if [[ "$DRY_RUN" == true ]] && [[ -z "$part_dev" ]]; then
        part_dev="/dev/${selected_disk}1"
    fi

    #---------------------------------------------------------------------------
    # Phase 5: Mount
    #---------------------------------------------------------------------------
    log_step "Phase 5: Mount disk"

    local mount_point
    mount_point=$(select_mount_point)
    if [[ -z "$mount_point" ]]; then
        log_error "No mount point selected. Aborting."
        exit 1
    fi

    mount_disk "$part_dev" "$mount_point"

    #---------------------------------------------------------------------------
    # Phase 6: Create folder structure
    #---------------------------------------------------------------------------
    if [[ "$SKIP_FOLDERS" == false ]]; then
        log_step "Phase 6: Create folder structure"
        create_folder_structure "$mount_point"
    fi

    #---------------------------------------------------------------------------
    # Summary
    #---------------------------------------------------------------------------
    echo ""
    echo -e "${BOLD}${GREEN}-==================================================================¬${NC}"
    echo -e "${BOLD}${GREEN}¦                    HDD Setup Complete!                            ¦${NC}"
    echo -e "${BOLD}${GREEN}L==================================================================-${NC}"
    echo ""
    echo -e "  ${BOLD}Disk:${NC}        /dev/$selected_disk"
    echo -e "  ${BOLD}Partition:${NC}   $part_dev"
    if [[ "$DRY_RUN" == false ]]; then
        local final_uuid
        final_uuid=$(blkid -o value -s UUID "$part_dev" 2>/dev/null || echo "N/A")
        echo -e "  ${BOLD}UUID:${NC}        $final_uuid"
    fi
    echo -e "  ${BOLD}Mount point:${NC} $mount_point"
    echo -e "  ${BOLD}Filesystem:${NC}  ext4"
    echo -e "  ${BOLD}fstab:${NC}       Configured (nofail)"
    echo ""

    if [[ "$DRY_RUN" == false ]]; then
        echo -e "  ${BOLD}Disk usage:${NC}"
        df -h "$mount_point" | sed 's/^/    /'
        echo ""
    fi

    echo -e "  ${BOLD}Docker volume mount examples:${NC}"
    echo "    # Media stack (Sonarr/Radarr/Plex)"
    echo "    volumes:"
    echo "      - ${mount_point}/media:/data/media"
    echo ""
    echo "    # Immich photo storage"
    echo "    volumes:"
    echo "      - ${mount_point}/storage/immich:/usr/src/app/upload"
    echo ""
    echo "    # Nextcloud data"
    echo "    volumes:"
    echo "      - ${mount_point}/storage/nextcloud:/var/www/html/data"
    echo ""
    echo -e "  ${BOLD}Verify mount survives reboot:${NC}"
    echo "    sudo mount -a       # Test fstab now"
    echo "    sudo reboot         # Full test (when convenient)"
    echo ""
    echo -e "  ${BOLD}Quick check commands:${NC}"
    echo "    lsblk               # See all block devices"
    echo "    df -h ${mount_point}  # Disk usage"
    echo "    ls -la ${mount_point} # Folder structure"
    echo ""
}

main "$@"