#!/bin/bash
# ==============================================================================
# ESXi 8 Installation via Hetzner Rescue System
# Method: Extract ISO to FAT32 EFI partition (UEFI-compatible)
#
# Usage:
#   wget http://YOUR_SERVER/esxi-install-rescue.sh -O /tmp/install.sh
#   bash /tmp/install.sh
#
# What it does:
#   1. Shows all disks — you pick which one
#   2. Downloads ESXi ISO from your web server
#   3. Creates GPT + FAT32 EFI partition on selected disk
#   4. Extracts ISO contents to the partition
#   5. Fixes boot.cfg paths for disk boot
#
# After reboot: pass through installation screens via KVM manually.
# ==============================================================================

set -euo pipefail

# ========================= CONFIG =========================
ISO_URL="http://ai-1-files.uni-renter.ru/VMware-ESXi-8.0U3g-24859861-x86_64.iso"
ISO_PATH="/tmp/esxi.iso"
# ==========================================================

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

echo ""
echo -e "${GREEN}=== ESXi 8 Rescue Installer (FAT32 method) ===${NC}"
echo ""

# --- Step 1: Show disks ---
echo -e "${GREEN}Step 1: Available disks${NC}"
echo ""
lsblk -d -o NAME,SIZE,MODEL,TRAN | grep -v "loop\|ram"
echo ""

mapfile -t DISKS < <(lsblk -d -n -o NAME | grep -v "loop\|ram")

if [ ${#DISKS[@]} -eq 0 ]; then
    echo -e "${RED}ERROR: No disks found!${NC}"
    exit 1
fi

echo "Detected disks:"
for i in "${!DISKS[@]}"; do
    SIZE=$(lsblk -d -n -o SIZE "/dev/${DISKS[$i]}" 2>/dev/null)
    MODEL=$(lsblk -d -n -o MODEL "/dev/${DISKS[$i]}" 2>/dev/null)
    echo "  [$i] /dev/${DISKS[$i]}  ${SIZE}  ${MODEL}"
done
echo ""

read -p "Select disk number for ESXi installation [0]: " DISK_NUM
DISK_NUM=${DISK_NUM:-0}

if [ "$DISK_NUM" -ge "${#DISKS[@]}" ] 2>/dev/null; then
    echo -e "${RED}ERROR: Invalid disk number${NC}"
    exit 1
fi

TARGET="/dev/${DISKS[$DISK_NUM]}"
TARGET_SIZE=$(lsblk -d -n -o SIZE "$TARGET" 2>/dev/null)
TARGET_MODEL=$(lsblk -d -n -o MODEL "$TARGET" 2>/dev/null)

echo ""
echo -e "${YELLOW}Selected: ${TARGET}  ${TARGET_SIZE}  ${TARGET_MODEL}${NC}"
echo ""

# --- Step 2: Download ISO ---
echo -e "${GREEN}Step 2: Downloading ESXi ISO${NC}"
echo "URL: ${ISO_URL}"
echo ""

if [ -f "$ISO_PATH" ]; then
    EXISTING_SIZE=$(stat -c%s "$ISO_PATH" 2>/dev/null || echo 0)
    echo -e "${YELLOW}ISO already exists at ${ISO_PATH} ($(( EXISTING_SIZE / 1024 / 1024 )) MB)${NC}"
    read -p "Re-download? (y/N): " redownload
    if [[ "$redownload" =~ ^[Yy]$ ]]; then
        wget -O "$ISO_PATH" "$ISO_URL"
    fi
else
    wget -O "$ISO_PATH" "$ISO_URL"
fi

if [ ! -f "$ISO_PATH" ]; then
    echo -e "${RED}ERROR: ISO download failed!${NC}"
    exit 1
fi

ISO_SIZE=$(stat -c%s "$ISO_PATH")
ISO_SIZE_MB=$(( ISO_SIZE / 1024 / 1024 ))
echo ""
echo -e "${GREEN}ISO downloaded: ${ISO_SIZE_MB} MB${NC}"

if [ "$ISO_SIZE_MB" -lt 400 ]; then
    echo -e "${RED}WARNING: ISO is smaller than expected (< 400 MB). Might be corrupted.${NC}"
    read -p "Continue anyway? (y/N): " confirm
    [[ "$confirm" =~ ^[Yy]$ ]] || exit 1
fi

# --- Step 3: Confirm ---
echo ""
echo -e "${RED}============================================${NC}"
echo -e "${RED}  WARNING: ALL DATA ON ${TARGET} WILL BE DESTROYED${NC}"
echo -e "${RED}============================================${NC}"
echo ""
echo "  Disk:  ${TARGET}  ${TARGET_SIZE}  ${TARGET_MODEL}"
echo "  ISO:   ${ISO_PATH}  ${ISO_SIZE_MB} MB"
echo "  Method: GPT + FAT32 EFI partition + extract ISO"
echo ""
read -p "Type 'yes' to proceed: " confirm

if [ "$confirm" != "yes" ]; then
    echo "Aborted."
    exit 0
fi

# --- Step 4: Create GPT + FAT32 partition ---
echo ""
echo -e "${GREEN}Step 3: Creating GPT + FAT32 EFI partition on ${TARGET}${NC}"

# Wipe old partition table
wipefs -af "$TARGET"
sleep 1

# Create GPT label
parted -s "$TARGET" mklabel gpt

# Create 1GB FAT32 EFI partition
parted -s "$TARGET" mkpart primary fat32 1MiB 1GiB
parted -s "$TARGET" set 1 boot on
sleep 1

# Determine partition name (sda1 or nvme0n1p1)
if [[ "$TARGET" == *nvme* ]]; then
    PART="${TARGET}p1"
else
    PART="${TARGET}1"
fi

echo -e "${GREEN}Formatting ${PART} as FAT32...${NC}"
mkfs.vfat -F32 "${PART}"

# --- Step 5: Mount and extract ---
echo ""
echo -e "${GREEN}Step 4: Extracting ISO to ${PART}${NC}"

mkdir -p /mnt/iso /mnt/esxi
mount -o loop "$ISO_PATH" /mnt/iso
mount "${PART}" /mnt/esxi

echo "Copying files..."
cp -r /mnt/iso/* /mnt/esxi/
cp -r /mnt/iso/.* /mnt/esxi/ 2>/dev/null || true

# --- Step 6: Fix boot.cfg paths ---
echo ""
echo -e "${GREEN}Step 5: Fixing boot.cfg paths for disk boot${NC}"

# Remove leading "/" from module paths in boot.cfg
# Original: kernel=/b.b00  modules=/jumpstrt.gz --- /useropts.gz
# Fixed:    kernel=b.b00   modules=jumpstrt.gz --- useropts.gz
for cfg in /mnt/esxi/efi/boot/boot.cfg /mnt/esxi/boot.cfg; do
    if [ -f "$cfg" ]; then
        sed -i 's|=/|=|g; s|--- /|--- |g' "$cfg"
        echo "  Fixed: $cfg"
    fi
done

# --- Step 7: Verify ---
echo ""
echo -e "${GREEN}Step 6: Verification${NC}"

FILE_COUNT=$(find /mnt/esxi -type f | wc -l)
echo "  Files extracted: ${FILE_COUNT}"

if [ -f /mnt/esxi/efi/boot/boot.cfg ]; then
    echo "  efi/boot/boot.cfg: exists"
    # Show first few module lines
    grep -E "^(kernel|modules)" /mnt/esxi/efi/boot/boot.cfg | head -2
else
    echo -e "${RED}  WARNING: efi/boot/boot.cfg not found!${NC}"
fi

# Unmount
umount /mnt/iso
umount /mnt/esxi
sync

echo ""
echo -e "${GREEN}=== Done! ===${NC}"
echo ""
echo "ESXi installer extracted to ${PART} (FAT32 EFI)."
echo ""
echo "Next steps:"
echo "  1. Type 'reboot' to restart the server"
echo "  2. Connect via KVM to see ESXi installer"
echo "  3. Walk through installation screens manually"
echo "  4. After install: configure network in DCUI, enable SSH"
echo ""
echo "When ready, type 'reboot' manually."
echo ""
