#!/bin/bash
set -e  # Exit immediately if a command exits with a non-zero status

# ===================== Configuration Section (Modify as per environment) =====================
# Log output level (No need to modify)
LOG_LEVEL="INFO"
# qemu.conf configuration file path
QEMU_CONF="/etc/libvirt/qemu.conf"
# VM XML configuration file path (XML to be modified)
VM_XML_PATH="/etc/vmdeploy/Windows_11.xml"
# VM name (Must match the name defined in XML)
VM_NAME="Windows_11"
# =========================================================================

# Log function (with timestamp)
log() {
    local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
    echo "[$timestamp] [$LOG_LEVEL] $1"
}

# ===================== Parameter Validation =====================
# Check if qcow2 path parameter is provided
if [ $# -ne 1 ]; then
    log "Error: Must pass exactly 1 parameter (absolute path of qcow2 image file)"
    echo "Usage: $0 /path/to/xxx.qcow2"
    exit 1
fi
# Define the passed qcow2 path variable
VM_QCOW2_PATH="$1"
# Check if qcow2 file exists
if [ ! -f "$VM_QCOW2_PATH" ]; then
    log "Error: Specified qcow2 file does not exist (Path: $VM_QCOW2_PATH)"
    echo "Error: Image file missing, script terminated"
    exit 1
fi
# Check if file suffix is qcow2
if [[ "$VM_QCOW2_PATH" != *.qcow2 ]]; then
    log "Warning: Specified file suffix is not .qcow2 (Path: $VM_QCOW2_PATH)"
    echo ">> Warning: File suffix is not .qcow2, continuing to set permissions..."
fi

# Start main logic
log "===== Start executing VM environment configuration & definition script ====="
log "QCOW2 image path to configure: $VM_QCOW2_PATH"

# 1. Check and start libvirtd service
log "Checking libvirtd service status"
if systemctl is-active --quiet libvirtd; then
    log "libvirtd is running"
else
    log "libvirtd is not running, starting now..."
    systemctl start libvirtd
    log "libvirtd started successfully"
fi
echo ">> libvirtd service is ready"

# 2. Set permissions for the specified qcow2 image file
log "Starting to set qcow2 file permissions (Path: $VM_QCOW2_PATH)"
chmod 666 "$VM_QCOW2_PATH"
log "Image permission set completed: $VM_QCOW2_PATH (Permission: 666)"
echo ">> Image permission set completed"

# 3. Configure qemu.conf (Add root user/group)
log "Configuring qemu.conf"
if [ ! -f "$QEMU_CONF" ]; then
    log "Error: qemu.conf does not exist (Path: $QEMU_CONF)"
    echo "Error: Configuration file missing, script terminated"
    exit 1
fi
# Check and add user = root
if ! grep -q '^user\s*=\s*"root"' "$QEMU_CONF"; then
    echo 'user = "root"' >> "$QEMU_CONF"
    log "Added configuration: user = root to $QEMU_CONF"
fi
# Check and add group = root
if ! grep -q '^group\s*=\s*"root"' "$QEMU_CONF"; then
    echo 'group = "root"' >> "$QEMU_CONF"
    log "Added configuration: group = root to $QEMU_CONF"
fi

# 4. Restart libvirtd to make configuration take effect
log "Restarting libvirtd service"
systemctl restart libvirtd &> /dev/null
log "libvirtd restarted successfully"
echo ">> libvirtd service has been restarted"

# 5. Modify <source file> path in XML to the passed qcow2 path (Core new logic)
log "Checking XML configuration file (Path: $VM_XML_PATH)"
if [ ! -f "$VM_XML_PATH" ]; then
    log "Error: XML file $VM_XML_PATH does not exist"
    echo "Error: XML configuration missing, cannot define VM"
    exit 1
fi
# Backup original XML (Avoid errors from modification)
XML_BACKUP_PATH="${VM_XML_PATH}.bak_$(date +%Y%m%d_%H%M%S)"
cp "$VM_XML_PATH" "$XML_BACKUP_PATH"
log "Backed up original XML file to: $XML_BACKUP_PATH"

# Precisely replace the disk source file path in XML (Compatible with paths containing /)
log "Modifying <source file> path in XML to: $VM_QCOW2_PATH"
# sed uses | as delimiter (Avoid conflict with / in path), match disk source file line and replace
sed -i "s|<source file='[^']*'/>|<source file='$VM_QCOW2_PATH'/>|g" "$VM_XML_PATH"
if [ $? -eq 0 ]; then
    log "QCOW2 path modification in XML completed"
    echo ">> XML image path updated to: $VM_QCOW2_PATH"
else
    log "Error: Failed to modify XML path"
    echo "Error: Restoring original XML file ($XML_BACKUP_PATH)"
    cp "$XML_BACKUP_PATH" "$VM_XML_PATH"
    exit 1
fi

# 6. Define VM (Check if already defined)
log "Checking if VM $VM_NAME is already defined"
if virsh list --all | grep -q "\s${VM_NAME}$"; then
    log "VM $VM_NAME is already defined, executing virsh undefine then redefining (Ensure configuration takes effect)"
    virsh undefine "$VM_NAME" &> /dev/null  # Delete old definition first
    log "Old VM definition cleared"
fi
log "Executing virsh define to import latest configuration"
virsh define "$VM_XML_PATH"
if [ $? -eq 0 ]; then
    log "VM $VM_NAME defined successfully"
    echo ">> VM configuration imported successfully (New qcow2 path applied)"
else
    log "Error: virsh define execution failed"
    echo "Error: Configuration import failed, restoring original XML file ($XML_BACKUP_PATH)"
    cp "$XML_BACKUP_PATH" "$VM_XML_PATH"
    exit 1
fi

# Execution completed
log "===== VM environment configuration & definition script execution completed ====="
echo ">> All configurations completed, VM $VM_NAME is ready"
echo ">> Image file path: $VM_QCOW2_PATH (Synced to XML)"
echo ">> You can execute: virsh start $VM_NAME to start the VM"
exit 0