#!/bin/bash
# ==============================================================================
# karch module: bootloader
# Phase 2 (chroot) — Install microcode, run mkinitcpio, install & configure GRUB
# ==============================================================================

run_bootloader() {
    source_env

    local boot_mode="${BOOT_MODE:-bios}"

    # --- Install GRUB packages -----------------------------------------------
    msg_info "Installing bootloader packages..."

    local grub_packages=(grub)

    if [[ "$boot_mode" == "uefi" ]]; then
        grub_packages+=(efibootmgr)
    fi

    if ! pacman -S --noconfirm "${grub_packages[@]}"; then
        msg_error "Failed to install GRUB packages!"
        return 1
    fi

    # --- Ensure vconsole.conf exists (prevents mkinitcpio warning) -----------
    if [[ ! -f /etc/vconsole.conf ]]; then
        msg_warn "/etc/vconsole.conf not found — creating default"
        echo "FONT=ter-120b" > /etc/vconsole.conf
    fi

    # --- Rebuild initramfs (after ucode is already installed in base.sh) -----
    msg_info "Rebuilding initramfs..."
    mkinitcpio -P

    # --- Ensure efivarfs is mounted (needed for efibootmgr in chroot) --------
    if [[ "$boot_mode" == "uefi" ]]; then
        if [[ -d /sys/firmware/efi/efivars ]] && ! mountpoint -q /sys/firmware/efi/efivars; then
            msg_info "Mounting efivarfs..."
            mount -t efivarfs efivarfs /sys/firmware/efi/efivars 2>/dev/null || true
        fi
    fi

    # --- Install GRUB --------------------------------------------------------
    if [[ "$boot_mode" == "uefi" ]]; then
        _install_grub_uefi || return 1
    else
        _install_grub_bios || return 1
    fi

    # --- Generate GRUB config ------------------------------------------------
    msg_info "Generating GRUB configuration..."
    grub-mkconfig -o /boot/grub/grub.cfg

    msg_ok "Bootloader installed and configured."

    dialog_msgbox "Bootloader" \
        "GRUB has been installed and configured.\n\nBoot mode: ${boot_mode^^}\nConfig: /boot/grub/grub.cfg"

    return 0
}

# --- UEFI installation -------------------------------------------------------

_install_grub_uefi() {
    msg_info "Installing GRUB for UEFI..."

    # Verify EFI partition is mounted at /boot
    if ! mountpoint -q /boot; then
        msg_error "/boot is not a mountpoint — EFI partition may not be mounted!"
        msg_error "Check that the EFI partition was mounted during the disk module."
        return 1
    fi

    # Install to the removable/fallback path FIRST (EFI/BOOT/BOOTX64.EFI).
    # This is the universal path that ALL UEFI firmware checks, regardless
    # of NVRAM boot entries. This is the most reliable method.
    msg_info "Installing GRUB to fallback UEFI path (EFI/BOOT/BOOTX64.EFI)..."
    if ! grub-install \
        --target=x86_64-efi \
        --efi-directory=/boot \
        --removable; then
        msg_error "GRUB UEFI removable installation failed!"
        return 1
    fi

    # Also try to create a named NVRAM entry (nice-to-have, not essential)
    msg_info "Creating NVRAM boot entry (GRUB)..."
    grub-install \
        --target=x86_64-efi \
        --efi-directory=/boot \
        --bootloader-id=GRUB 2>/dev/null || msg_warn "NVRAM boot entry creation failed (non-fatal — fallback path is installed)"

    # Verify the EFI binaries exist
    if [[ -f /boot/EFI/BOOT/BOOTX64.EFI ]]; then
        msg_ok "Verified: /boot/EFI/BOOT/BOOTX64.EFI exists"
    else
        msg_error "EFI binary not found at /boot/EFI/BOOT/BOOTX64.EFI!"
        ls -laR /boot/EFI/ 2>/dev/null || msg_error "/boot/EFI/ directory not found"
        return 1
    fi

    msg_ok "GRUB installed (UEFI, EFI directory: /boot)"
}

# --- BIOS installation -------------------------------------------------------

_install_grub_bios() {
    msg_info "Installing GRUB for BIOS/Legacy..."

    source_env
    local target_disk="${DISK:-}"

    # Prefer the disk saved during the disk module; fall back to manual selection
    if [[ -z "$target_disk" ]]; then
        local disk_list=()
        while IFS= read -r line; do
            local dname dsize
            dname="$(echo "$line" | awk '{print $1}')"
            dsize="$(echo "$line" | awk '{print $2}')"
            disk_list+=("$dname" "${dsize}")
        done < <(lsblk -d -n -p -o NAME,SIZE,TYPE | awk '$3 == "disk" {print $1, $2}')

        if [[ ${#disk_list[@]} -eq 0 ]]; then
            dialog_msgbox "Error" "No disks found for GRUB installation!"
            return 1
        fi

        target_disk=$(dialog_menu "GRUB Target Disk" \
            "Select the disk to install GRUB to (BIOS/MBR):" \
            "${disk_list[@]}") || return 1
    else
        msg_info "Using installation disk from earlier: $target_disk"
    fi

    if ! grub-install --target=i386-pc "$target_disk"; then
        msg_error "GRUB BIOS installation failed!"
        return 1
    fi

    msg_ok "GRUB installed (BIOS, target: ${target_disk})"
}
