#!/bin/bash
# Ensure dependencies are installed
if ! command -v whiptail &>/dev/null; then
    echo "Installing whiptail..."
    apt-get update && apt-get install -y whiptail
fi

# ----------------------------
# Cleanup function
# ----------------------------
TEMP_FILE=""
OVA_EXTRACT_DIR="/tmp/ova_extract"

cleanup() {
    [[ -f "$TEMP_FILE" ]] && rm -f "$TEMP_FILE"
    [[ -d "$OVA_EXTRACT_DIR" ]] && rm -rf "$OVA_EXTRACT_DIR"
}
trap cleanup EXIT

# ----------------------------
# Get User Input via Whiptail
# ----------------------------
whiptail --title "Clavister Firewall VM" --yesno "This will create a new Clavister Firewall VM. Proceed?" 10 50 || exit 1
 
# Get login details
USERNAME=$(whiptail --title "https://my.clavister.com" --inputbox "Enter Clavister Username:" 10 50 "" 3>&1 1>&2 2>&3) || exit 1
PASSWORD=$(whiptail --title "https://my.clavister.com" --passwordbox "Enter Clavister Password:" 10 50 3>&1 1>&2 2>&3) || exit 1
 
# ----------------------------
# Deployment Mode: Single or HA
# ----------------------------
DEPLOY_MODE=$(whiptail --title "Deployment Mode" --menu "Choose deployment mode:" 15 50 2 \
"1" "Single" \
"2" "High Availability (HA)" 3>&1 1>&2 2>&3) || exit 1
 
if [[ "$DEPLOY_MODE" == "2" ]]; then
    VM_ID_MASTER=$(whiptail --inputbox "Enter Master VM ID (e.g., 9000):" 10 50 "9000" 3>&1 1>&2 2>&3) || exit 1
    VM_ID_SLAVE=$(whiptail --inputbox "Enter Slave VM ID (e.g., 9001):" 10 50 "9001" 3>&1 1>&2 2>&3) || exit 1
    if [[ "$VM_ID_MASTER" == "$VM_ID_SLAVE" ]]; then
        echo "❌ Master and Slave VM IDs must be different."
        exit 1
    fi
 
    VM_NAME_MASTER="clavister-firewall-master"
    VM_NAME_SLAVE="clavister-firewall-slave"
 
    # Minimum 2 interfaces for HA
    INTERFACE_COUNT=$(whiptail --inputbox "Enter Number of Network Interfaces (min 2 for HA):" 10 50 "2" 3>&1 1>&2 2>&3) || exit 1
    if [[ "$INTERFACE_COUNT" -lt 2 ]]; then
        echo "❌ HA requires at least 2 network interfaces."
        exit 1
    fi
 
    # Create sync bridge (with promiscuous mode)
    SYNC_BRIDGE="Sync${VM_ID_MASTER}${VM_ID_SLAVE}"
    echo "Creating sync bridge: $SYNC_BRIDGE..."
    if ! ip link show "$SYNC_BRIDGE" &>/dev/null; then
        ip link add name "$SYNC_BRIDGE" type bridge || { echo "❌ Failed to create sync bridge"; exit 1; }
        ip link set "$SYNC_BRIDGE" up
        ip link set "$SYNC_BRIDGE" promisc on  # Enable promiscuous mode
    fi
 
else
    VM_ID=$(whiptail --inputbox "Enter VM ID (e.g., 9000):" 10 50 "9000" 3>&1 1>&2 2>&3) || exit 1
    VM_NAME=$(whiptail --inputbox "Enter VM Name:" 10 50 "clavister-firewall" 3>&1 1>&2 2>&3) || exit 1
    INTERFACE_COUNT=$(whiptail --inputbox "Enter Number of Network Interfaces:" 10 50 "1" 3>&1 1>&2 2>&3) || exit 1
fi
 
# Get remaining VM details
STORAGE=$(whiptail --inputbox "Enter Storage Location:" 10 50 "local-lvm" 3>&1 1>&2 2>&3) || exit 1
BRIDGE=$(whiptail --inputbox "Enter Network Bridge:" 10 50 "vmbr0" 3>&1 1>&2 2>&3) || exit 1
RAM_SIZE=$(whiptail --inputbox "Enter RAM Size (MB):" 10 50 "4096" 3>&1 1>&2 2>&3) || exit 1
CPU_CORES=$(whiptail --inputbox "Enter Number of CPU Cores:" 10 50 "4" 3>&1 1>&2 2>&3) || exit 1
 
# ----------------------------
# File Type and Download
# ----------------------------
FIREWALL_TYPE=$(whiptail --title "Select Firewall Type" --menu "Choose an option:" 15 50 2 \
"1" "OVA" \
"2" "QCOW2" 3>&1 1>&2 2>&3) || exit 1
 
if [ "$FIREWALL_TYPE" == "1" ]; then
    FILE_URL="https://my.clavister.com/api/downloads/v1.0/file/68a0f353-31f4-ef11-a436-005056bdfeb0"
    FILE_NAME="clavister.ova"
else
    FILE_URL="https://my.clavister.com/api/downloads/v1.0/file/35fda95c-31f4-ef11-a436-005056bdfeb0"
    FILE_NAME="clavister.qcow2"
fi
 
# ----------------------------
# OAuth Token
# ----------------------------
response=$(wget --quiet --method POST --header 'Content-Type: application/x-www-form-urlencoded' \
--body-data "username=$USERNAME&password=$PASSWORD&grant_type=password" -O - \
'https://my.clavister.com/api/oauth/v1.0/token')
 
bearer_token=$(echo "$response" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
 
if [ -z "$bearer_token" ]; then
    echo "❌ Failed to retrieve Bearer token."
    exit 1
fi
 
# ----------------------------
# Download file once for HA
# ----------------------------
TEMP_FILE="/tmp/clavister_${FILE_NAME}"
if [[ ! -f "$TEMP_FILE" ]]; then
    echo "Downloading $FILE_URL..."
    wget --header "Authorization: Bearer $bearer_token" -O "$TEMP_FILE" "$FILE_URL" || exit 1
fi
 
# ----------------------------
# Extract and Convert OVA to QCOW2
# ----------------------------
convert_ova() {
    local vm_id=$1
    echo "Extracting OVA..."
    mkdir -p "/tmp/ova_extract"
    tar -xvf "$TEMP_FILE" -C "/tmp/ova_extract"
    VMDK_FILE=$(find /tmp/ova_extract -name '*.vmdk' | head -n 1)
    if [ -z "$VMDK_FILE" ]; then
        echo "❌ No VMDK file found in OVA."
        exit 1
    fi
    echo "Converting VMDK to QCOW2..."
    qm importdisk $vm_id "$VMDK_FILE" "$STORAGE" --format qcow2 || exit 1
}
 
# ----------------------------
# Create VM Function
# ----------------------------
create_vm() {
    local vm_id=$1
    local vm_name=$2
    echo "Creating VM $vm_name with ID $vm_id..."
    qm create $vm_id --name "$vm_name" --memory $RAM_SIZE --cores $CPU_CORES --net0 virtio,bridge=$BRIDGE
    for i in $(seq 1 $((INTERFACE_COUNT - 1))); do
        if [[ "$DEPLOY_MODE" == "2" && "$i" == "1" ]]; then
            qm set "$vm_id" --net$i virtio,bridge="$SYNC_BRIDGE"
        else
            qm set "$vm_id" --net$i virtio,bridge="$BRIDGE"
        fi
    done

    
    if [ "$FIREWALL_TYPE" == "1" ]; then
        convert_ova "$vm_id"
    else
        qm importdisk $vm_id "$TEMP_FILE" "$STORAGE" --format qcow2 || exit 1
    fi
 
    qm set $vm_id --virtio0 "$STORAGE:vm-$vm_id-disk-0"
    qm resize $vm_id virtio0 4G
    qm set $vm_id --bios seabios
    qm set $vm_id --cpu host
    qm set $vm_id --boot order=virtio0
    qm set $vm_id --serial0 socket
}
 
if [[ "$DEPLOY_MODE" == "2" ]]; then
    create_vm "$VM_ID_MASTER" "$VM_NAME_MASTER"
    create_vm "$VM_ID_SLAVE" "$VM_NAME_SLAVE"
else
    create_vm "$VM_ID" "$VM_NAME"
fi
 
echo "✅ Clavister VM(s) successfully created"

# ----------------------------
# Start VM(s)
# ----------------------------
if [[ "$DEPLOY_MODE" == "2" ]]; then
    qm start "$VM_ID_MASTER"
    qm start "$VM_ID_SLAVE"
    echo "✅ Clavister VMs successfully started."
else
    qm start "$VM_ID"
    echo "✅ Clavister VM successfully started."
fi