#!/bin/bash
#================================================================================================
# fnnas-install (Pro-Lockdown Edition)
# 修正点：禁用后台挂载干扰、强制卸载循环、严格挂载校验、消除路径警告。
#================================================================================================

model_conf="/etc/model_database.conf"
ophub_release_file="/etc/ophub-release"
tmp_path="/ddbr"
DIR_INSTALL="${tmp_path}/install"

STEPS="[\033[95m STEPS \033[0m]"; INFO="[\033[94m INFO \033[0m]"; SUCCESS="[\033[92m SUCCESS \033[0m]"; OPTIONS="[\033[93m OPTIONS \033[0m]"; ERROR="[\033[91m ERROR \033[0m]"

error_msg() { echo -e "${ERROR} ${1}"; exit 1; }

# 1. 检查依赖
check_depends() {
    echo -e "${STEPS} 正在检查必要依赖..."
    apt-get update && apt-get install -y tar bsdextrautils dosfstools btrfs-progs parted util-linux uuid-runtime psmisc udev
}

# 2. 交互选择
init_selection() {
    root_devname="$(df / | tail -n1 | awk '{print $1}' | grep -oE 'mmcblk[0-9]|sd[a-z]|nvme[0-9]n[0-9]')"
    mapfile -t disk_lines < <(lsblk -dn -o NAME,SIZE,MODEL,TYPE | grep "disk" | grep -vE "${root_devname}|zram")
    [[ ${#disk_lines[@]} -eq 0 ]] && error_msg "未找到可用磁盘！"
    
    echo -e "${INFO} 请选择目标磁盘:"
    for ((i=0; i<${#disk_lines[@]}; i++)); do
        printf "[%d] /dev/%s\n" "$((i+1))" "${disk_lines[$i]}"
    done
    read -p "请输入编号: " disk_idx < /dev/tty
    DEV_TARGET="/dev/$(echo "${disk_lines[$((disk_idx-1))]}" | awk '{print $1}')"
    [[ "${DEV_TARGET}" == *mmcblk* || "${DEV_TARGET}" == *nvme* ]] && P_SUFFIX="p" || P_SUFFIX=""

    source "${ophub_release_file}"
    model_database="$(cat ${model_conf} | sed -e 's/NA//g' -e 's/NULL//g' -e 's/[ ][ ]*//g' | grep -E "^[0-9]{1,3}:.*:$(basename ${FAMILY}):.*")"
    
    echo -e "${INFO} 请选择设备 ID:"
    echo "${model_database}" | awk -F':' '{print $1,$3,$2,$4}' | while read -r line; do printf "%-5s %-10s %-45s %-50s\n" $(echo "${line}"); done
    read -p "请输入 ID: " boxid < /dev/tty
    
    ret="$(echo "${model_database}" | grep -E "^${boxid}:" | head -n 1)"
    FDTFILE="$(echo "${ret}" | awk -F ':' '{print $4}')"
    MAINLINE_UBOOT="$(echo "${ret}" | awk -F ':' '{print $6}')"
}

# 3. 深度清理逻辑
force_clean_disk() {
    local dev=$1
    echo -e "${STEPS} 正在深度锁定并清理 ${dev}..."
    
    # 尝试停止 udisks 服务以防自动挂载
    systemctl stop udisks2 2>/dev/null

    # 循环卸载所有分区，直到彻底干净
    local count=0
    while grep -q "${dev}" /proc/mounts && [ $count -lt 5 ]; do
        grep "${dev}" /proc/mounts | awk '{print $2}' | xargs -r umount -l 2>/dev/null
        ((count++))
        sleep 1
    done

    # 抹除特征
    wipefs -af "${dev}"
    dd if=/dev/zero of="${dev}" bs=1M count=10 conv=fsync 2>/dev/null
}

# 4. 执行分区
create_partition() {
    force_clean_disk "${DEV_TARGET}"
    
    echo -e "${STEPS} 正在分区 ${DEV_TARGET}..."
    parted -s "${DEV_TARGET}" mklabel msdos
    
    BLANK1="117"; BOOT="512"
    read -p "请输入根分区大小 (GB, 默认全选): " root_size_gb < /dev/tty
    
    parted -s "${DEV_TARGET}" mkpart primary fat32 $((BLANK1))MiB $((BLANK1 + BOOT - 1))MiB
    [[ -z "${root_size_gb}" ]] && root_end="100%" || root_end="$((BLANK1 + BOOT + root_size_gb * 1024))MiB"
    parted -s "${DEV_TARGET}" mkpart primary btrfs $((BLANK1 + BOOT))MiB "${root_end}"
    
    # 强制等待内核更新
    udevadm settle
    sleep 2
}

# 5. 格式化与挂载校验
copy_and_fix_boot() {
    echo -e "${STEPS} 正在格式化并修正引导..."
    PART_BOOT="${DEV_TARGET}${P_SUFFIX}1"
    PART_ROOT="${DEV_TARGET}${P_SUFFIX}2"
    
    # 格式化前再次确保没被挂载
    umount -l "${PART_BOOT}" "${PART_ROOT}" 2>/dev/null
    
    # 格式化
    mkfs.vfat -F 32 -n "BOOT_EMMC" "${PART_BOOT}" || error_msg "无法格式化 ${PART_BOOT}"
    mkfs.btrfs -f -L "ROOTFS_EMMC" "${PART_ROOT}" || error_msg "无法格式化 ${PART_ROOT}"
    
    TARGET_UUID=$(blkid -s UUID -o value "${PART_ROOT}")
    
    # 挂载校验：这是防止写错位置的关键
    mkdir -p ${DIR_INSTALL}
    mount "${PART_BOOT}" "${DIR_INSTALL}" || error_msg "挂载 SSD BOOT 分区失败！"
    
    # 确认挂载点确实是 SSD
    if ! mountpoint -q "${DIR_INSTALL}"; then error_msg "挂载校验失败，请检查 SSD 状态！"; fi

    cp -rf /boot/* "${DIR_INSTALL}/"
    
    # 修正引导文件
    local ROOT_CMD="root=UUID=${TARGET_UUID} rootflags=compress=zstd:6 rootfstype=btrfs rw rootwait"
    for cfg in uEnv.txt armbianEnv.txt extlinux/extlinux.conf boot.ini; do
        if [[ -f "${DIR_INSTALL}/${cfg}" ]]; then
            sed -i "s|root=[^ ]*|${ROOT_CMD}|g" "${DIR_INSTALL}/${cfg}"
            sed -i "s|meson.*\.dtb|${FDTFILE}|g" "${DIR_INSTALL}/${cfg}"
        fi
    done
    [[ -f "${DIR_INSTALL}/boot-emmc.scr" ]] && mv -f "${DIR_INSTALL}/boot-emmc.scr" "${DIR_INSTALL}/boot.scr"
    
    sync && umount -l "${DIR_INSTALL}"

    # 修正 eMMC 原始引导
    EMMC_BOOT="/dev/mmcblk1p1"
    if [[ -b "${EMMC_BOOT}" ]]; then
        mkdir -p /mnt/emmc_boot
        mount "${EMMC_BOOT}" /mnt/emmc_boot && {
            sed -i "s|root=[^ ]*|${ROOT_CMD}|g" /mnt/emmc_boot/uEnv.txt 2>/dev/null
            sync && umount -l /mnt/emmc_boot
        }
    fi
}

# 6. 系统搬迁
copy_rootfs() {
    echo -e "${STEPS} 正在同步文件到 SSD..."
    mount -t btrfs -o compress=zstd:6 "${DEV_TARGET}${P_SUFFIX}2" "${DIR_INSTALL}" || error_msg "挂载 SSD ROOTFS 失败！"
    
    if ! mountpoint -q "${DIR_INSTALL}"; then error_msg "ROOTFS 挂载校验失败！"; fi

    mkdir -p "${DIR_INSTALL}"/{boot,dev,media,mnt,proc,run,sys,tmp}
    chmod 1777 "${DIR_INSTALL}/tmp"
    
    for src in etc home opt root srv usr var; do
        if [[ -d "/${src}" ]]; then
            echo -e "${INFO} 同步: /${src}"
            tar -C / -cf - "${src}" | tar -C "${DIR_INSTALL}" -xpf -
        fi
    done

    cat >"${DIR_INSTALL}/etc/fstab" <<EOF
UUID=${TARGET_UUID}    /        btrfs    defaults,noatime,compress=zstd:6      0 1
LABEL=BOOT_EMMC        /boot    vfat     defaults                              0 2
tmpfs                  /tmp     tmpfs    defaults,nosuid                       0 0
EOF

    sync && umount -l "${DIR_INSTALL}"
    # 恢复服务
    systemctl start udisks2 2>/dev/null
}

# 执行
[[ "$(id -u)" == "0" ]] || error_msg "请使用 sudo"
check_depends
init_selection
create_partition
copy_and_fix_boot
copy_rootfs

echo -e "${SUCCESS} 安装圆满成功！请运行 poweroff 重启。"