#!/bin/bash
# verify-guest-agent.sh
# Verify guest agent status on all VMs via Proxmox API

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"

# Load environment
if [ -f "${PROJECT_ROOT}/.env" ]; then
    set -a
    source "${PROJECT_ROOT}/.env"
    set +a
fi

# Try API tokens first, fall back to password
PROXMOX_1_TOKEN="${PROXMOX_TOKEN_ML110_01:-}"
PROXMOX_2_TOKEN="${PROXMOX_TOKEN_R630_01:-}"
PROXMOX_PASS="${PROXMOX_ROOT_PASS:-L@kers2010}"
PROXMOX_1_URL="https://192.168.11.10:8006"
PROXMOX_2_URL="https://192.168.11.11:8006"

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

log() {
    echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $*"
}

log_success() {
    echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] ✅${NC} $*"
}

log_error() {
    echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ❌${NC} $*"
}

log_warning() {
    echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] ⚠️${NC} $*"
}

# Get auth - try API token first, fall back to password
get_auth() {
    local api_url=$1
    local api_token=$2
    local response
    
    # Try API token authentication first
    if [ -n "${api_token}" ]; then
        response=$(curl -k -s -X GET \
            -H "Authorization: PVEAuthCookie=${api_token}" \
            "${api_url}/api2/json/version" 2>/dev/null)
        
        if echo "${response}" | grep -q "data\|version"; then
            echo "${api_token}|TOKEN"
            return 0
        fi
    fi
    
    # Fall back to password authentication
    response=$(curl -k -s -X POST \
        -d "username=root@pam&password=${PROXMOX_PASS}" \
        "${api_url}/api2/json/access/ticket" 2>/dev/null)
    
    if echo "${response}" | grep -q "authentication failure"; then
        echo ""
        return 1
    fi
    
    local ticket csrf
    if command -v jq &> /dev/null; then
        ticket=$(echo "${response}" | jq -r '.data.ticket // empty' 2>/dev/null)
        csrf=$(echo "${response}" | jq -r '.data.CSRFPreventionToken // empty' 2>/dev/null)
    else
        ticket=$(echo "${response}" | grep -o '"ticket":"[^"]*' | head -1 | cut -d'"' -f4)
        csrf=$(echo "${response}" | grep -o '"CSRFPreventionToken":"[^"]*' | head -1 | cut -d'"' -f4)
    fi
    
    if [ -z "${ticket}" ] || [ -z "${csrf}" ]; then
        echo ""
        return 1
    fi
    
    echo "${ticket}|${csrf}"
}

# List all nodes in the cluster
list_nodes() {
    local api_url=$1
    local auth_token=$2
    local auth_type=$3
    
    local response
    
    if [ "${auth_type}" = "TOKEN" ]; then
        response=$(curl -k -s -X GET \
            -H "Authorization: PVEAuthCookie=${auth_token}" \
            "${api_url}/api2/json/nodes" 2>/dev/null)
    else
        local ticket csrf
        IFS='|' read -r ticket csrf <<< "${auth_token}"
        response=$(curl -k -s -X GET \
            -H "CSRFPreventionToken: ${csrf}" \
            -b "PVEAuthCookie=${ticket}" \
            "${api_url}/api2/json/nodes" 2>/dev/null)
    fi
    
    if command -v jq &> /dev/null; then
        echo "${response}" | jq -r '.data[]?.node // empty' 2>/dev/null | grep -v '^$' | sort
    else
        echo "${response}" | grep -o '"node":"[^"]*' | cut -d'"' -f4 | sort | uniq
    fi
}

# List all VMs on a node
list_vms() {
    local api_url=$1
    local node=$2
    local auth_token=$3
    local auth_type=$4
    
    local response
    
    if [ "${auth_type}" = "TOKEN" ]; then
        response=$(curl -k -s -X GET \
            -H "Authorization: PVEAuthCookie=${auth_token}" \
            "${api_url}/api2/json/nodes/${node}/qemu" 2>/dev/null)
    else
        local ticket csrf
        IFS='|' read -r ticket csrf <<< "${auth_token}"
        response=$(curl -k -s -X GET \
            -H "CSRFPreventionToken: ${csrf}" \
            -b "PVEAuthCookie=${ticket}" \
            "${api_url}/api2/json/nodes/${node}/qemu" 2>/dev/null)
    fi
    
    if command -v jq &> /dev/null; then
        echo "${response}" | jq -r '.data[]?.vmid // empty' 2>/dev/null | grep -v '^$' | sort -n
    else
        echo "${response}" | grep -o '"vmid":[0-9]*' | grep -o '[0-9]*' | sort -n | uniq
    fi
}

# Get VM name
get_vm_name() {
    local api_url=$1
    local node=$2
    local vmid=$3
    local auth_token=$4
    local auth_type=$5
    
    local response
    
    if [ "${auth_type}" = "TOKEN" ]; then
        response=$(curl -k -s -X GET \
            -H "Authorization: PVEAuthCookie=${auth_token}" \
            "${api_url}/api2/json/nodes/${node}/qemu/${vmid}/config" 2>/dev/null)
    else
        local ticket csrf
        IFS='|' read -r ticket csrf <<< "${auth_token}"
        response=$(curl -k -s -X GET \
            -H "CSRFPreventionToken: ${csrf}" \
            -b "PVEAuthCookie=${ticket}" \
            "${api_url}/api2/json/nodes/${node}/qemu/${vmid}/config" 2>/dev/null)
    fi
    
    if command -v jq &> /dev/null; then
        echo "${response}" | jq -r '.data.name // "unnamed"' 2>/dev/null
    else
        echo "${response}" | grep -o '"name":"[^"]*' | head -1 | cut -d'"' -f4 || echo "unnamed"
    fi
}

# Check guest agent status
check_guest_agent() {
    local api_url=$1
    local node=$2
    local vmid=$3
    local auth_token=$4
    local auth_type=$5
    
    local response
    
    if [ "${auth_type}" = "TOKEN" ]; then
        response=$(curl -k -s -X GET \
            -H "Authorization: PVEAuthCookie=${auth_token}" \
            "${api_url}/api2/json/nodes/${node}/qemu/${vmid}/config" 2>/dev/null)
    else
        local ticket csrf
        IFS='|' read -r ticket csrf <<< "${auth_token}"
        response=$(curl -k -s -X GET \
            -H "CSRFPreventionToken: ${csrf}" \
            -b "PVEAuthCookie=${ticket}" \
            "${api_url}/api2/json/nodes/${node}/qemu/${vmid}/config" 2>/dev/null)
    fi
    
    # Check if agent is enabled
    if echo "${response}" | grep -q '"agent"[[:space:]]*:[[:space:]]*"1"'; then
        return 0  # Enabled
    fi
    return 1  # Not enabled
}

verify_node() {
    local api_url=$1
    local node=$2
    local auth_token=$3
    local auth_type=$4
    
    log "Verifying node: ${node}"
    
    local vmids
    vmids=$(list_vms "${api_url}" "${node}" "${auth_token}" "${auth_type}")
    
    if [ -z "${vmids}" ]; then
        log_warning "  No VMs found on ${node}"
        return 0
    fi
    
    local enabled_count=0
    local disabled_count=0
    
    printf "  %-8s %-30s %-10s\n" "VMID" "Name" "Status"
    printf "  %-8s %-30s %-10s\n" "----" "----" "------"
    
    while IFS= read -r vmid; do
        [ -z "${vmid}" ] && continue
        
        local vm_name
        vm_name=$(get_vm_name "${api_url}" "${node}" "${vmid}" "${auth_token}" "${auth_type}")
        
        if check_guest_agent "${api_url}" "${node}" "${vmid}" "${auth_token}" "${auth_type}"; then
            printf "  %-8s %-30s ${GREEN}%-10s${NC}\n" "${vmid}" "${vm_name}" "ENABLED"
            enabled_count=$((enabled_count + 1))
        else
            printf "  %-8s %-30s ${RED}%-10s${NC}\n" "${vmid}" "${vm_name}" "DISABLED"
            disabled_count=$((disabled_count + 1))
        fi
    done <<< "${vmids}"
    
    log ""
    log "  Summary: ${enabled_count} enabled, ${disabled_count} disabled"
    log ""
}

verify_site() {
    local api_url=$1
    local site_name=$2
    local auth_token=$3
    local auth_type=$4
    
    log "=========================================="
    log "Site: ${site_name}"
    log "=========================================="
    
    local nodes
    nodes=$(list_nodes "${api_url}" "${auth_token}" "${auth_type}")
    
    if [ -z "${nodes}" ]; then
        log_error "Failed to discover nodes on ${site_name}"
        return 1
    fi
    
    log_success "Discovered nodes: $(echo "${nodes}" | tr '\n' ' ')"
    log ""
    
    while IFS= read -r node; do
        [ -z "${node}" ] && continue
        verify_node "${api_url}" "${node}" "${auth_token}" "${auth_type}"
    done <<< "${nodes}"
}

main() {
    log "=========================================="
    log "Verify Guest Agent Status on All VMs"
    log "=========================================="
    log ""
    
    # Site 1
    local auth1
    auth1=$(get_auth "${PROXMOX_1_URL}" "${PROXMOX_1_TOKEN}")
    
    if [ -z "${auth1}" ]; then
        log_error "Failed to authenticate to Site 1"
    else
        IFS='|' read -r auth_token1 auth_type1 <<< "${auth1}"
        log_success "Authenticated to Site 1"
        log ""
        verify_site "${PROXMOX_1_URL}" "Site 1" "${auth_token1}" "${auth_type1}"
    fi
    
    # Site 2
    local auth2
    auth2=$(get_auth "${PROXMOX_2_URL}" "${PROXMOX_2_TOKEN}")
    
    if [ -z "${auth2}" ]; then
        log_error "Failed to authenticate to Site 2"
    else
        IFS='|' read -r auth_token2 auth_type2 <<< "${auth2}"
        log_success "Authenticated to Site 2"
        log ""
        verify_site "${PROXMOX_2_URL}" "Site 2" "${auth_token2}" "${auth_type2}"
    fi
    
    log "=========================================="
    log_success "Verification complete!"
    log "=========================================="
}

main "$@"

