#!/bin/bash
# create-proxmox-cluster.sh
# Creates a Proxmox cluster between two instances

set -euo pipefail

# Load environment variables
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -f "${SCRIPT_DIR}/../.env" ]; then
    set -a
    source <(grep -v '^#' "${SCRIPT_DIR}/../.env" | grep -v '^$' | sed 's/^/export /')
    set +a
fi

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

# Configuration
CLUSTER_NAME="${CLUSTER_NAME:-sankofa-cluster}"
NODE1_IP="192.168.11.10"
NODE1_NAME="ML110-01"
NODE1_TOKEN="${PROXMOX_TOKEN_ML110_01:-}"
NODE2_IP="192.168.11.11"
NODE2_NAME="R630-01"
NODE2_TOKEN="${PROXMOX_TOKEN_R630_01:-}"

log() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

error() {
    echo -e "${RED}[ERROR]${NC} $1" >&2
    exit 1
}

warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

check_prerequisites() {
    if [ -z "$NODE1_TOKEN" ] || [ -z "$NODE2_TOKEN" ]; then
        error "Proxmox API tokens not found in .env file"
    fi
    
    log "Prerequisites check passed"
}

check_cluster_status() {
    log "Checking current cluster status..."
    
    local node1_cluster=$(curl -k -s -H "Authorization: PVEAPIToken ${NODE1_TOKEN}" \
        "https://${NODE1_IP}:8006/api2/json/cluster/config/nodes" 2>/dev/null | jq -r '.data // null')
    
    local node2_cluster=$(curl -k -s -H "Authorization: PVEAPIToken ${NODE2_TOKEN}" \
        "https://${NODE2_IP}:8006/api2/json/cluster/config/nodes" 2>/dev/null | jq -r '.data // null')
    
    if [ "$node1_cluster" != "null" ] && [ -n "$node1_cluster" ]; then
        warn "Node 1 is already in a cluster"
        echo "$node1_cluster" | jq '.'
        return 1
    fi
    
    if [ "$node2_cluster" != "null" ] && [ -n "$node2_cluster" ]; then
        warn "Node 2 is already in a cluster"
        echo "$node2_cluster" | jq '.'
        return 1
    fi
    
    log "Both nodes are standalone - ready for clustering"
    return 0
}

create_cluster_on_node1() {
    log "Creating cluster '${CLUSTER_NAME}' on ${NODE1_NAME}..."
    
    # Create cluster via API
    local response=$(curl -k -s -X POST \
        -H "Authorization: PVEAPIToken ${NODE1_TOKEN}" \
        -H "Content-Type: application/json" \
        "https://${NODE1_IP}:8006/api2/json/cluster/config" \
        -d "{\"clustername\":\"${CLUSTER_NAME}\",\"link0\":\"${NODE1_IP}\"}" 2>/dev/null)
    
    local success=$(echo "$response" | jq -r '.data // null')
    
    if [ "$success" != "null" ] && [ -n "$success" ]; then
        log "✓ Cluster created on ${NODE1_NAME}"
        return 0
    else
        local error_msg=$(echo "$response" | jq -r '.errors[0].message // "Unknown error"')
        error "Failed to create cluster: ${error_msg}"
    fi
}

get_cluster_fingerprint() {
    log "Getting cluster fingerprint from ${NODE1_NAME}..."
    
    local fingerprint=$(curl -k -s -H "Authorization: PVEAPIToken ${NODE1_TOKEN}" \
        "https://${NODE1_IP}:8006/api2/json/cluster/config/totem" 2>/dev/null | \
        jq -r '.data.fingerprint // empty')
    
    if [ -n "$fingerprint" ]; then
        echo "$fingerprint"
        return 0
    else
        warn "Could not get cluster fingerprint"
        return 1
    fi
}

add_node2_to_cluster() {
    log "Adding ${NODE2_NAME} to cluster..."
    
    # Get cluster fingerprint
    local fingerprint=$(get_cluster_fingerprint)
    
    if [ -z "$fingerprint" ]; then
        warn "Fingerprint not available, trying without it"
    fi
    
    # Add node to cluster
    local response=$(curl -k -s -X POST \
        -H "Authorization: PVEAPIToken ${NODE2_TOKEN}" \
        -H "Content-Type: application/json" \
        "https://${NODE2_IP}:8006/api2/json/cluster/config/nodes" \
        -d "{\"hostname\":\"${NODE1_NAME}\",\"nodeid\":1,\"votes\":1,\"link0\":\"${NODE1_IP}\"}" 2>/dev/null)
    
    local success=$(echo "$response" | jq -r '.data // null')
    
    if [ "$success" != "null" ] && [ -n "$success" ]; then
        log "✓ ${NODE2_NAME} added to cluster"
        return 0
    else
        local error_msg=$(echo "$response" | jq -r '.errors[0].message // "Unknown error"')
        warn "API method failed: ${error_msg}"
        warn "Cluster creation may require SSH access or manual setup"
        return 1
    fi
}

verify_cluster() {
    log "Verifying cluster status..."
    
    sleep 5  # Wait for cluster to stabilize
    
    local node1_nodes=$(curl -k -s -H "Authorization: PVEAPIToken ${NODE1_TOKEN}" \
        "https://${NODE1_IP}:8006/api2/json/cluster/config/nodes" 2>/dev/null | \
        jq -r '.data | length // 0')
    
    local node2_nodes=$(curl -k -s -H "Authorization: PVEAPIToken ${NODE2_TOKEN}" \
        "https://${NODE2_IP}:8006/api2/json/cluster/config/nodes" 2>/dev/null | \
        jq -r '.data | length // 0')
    
    if [ "$node1_nodes" -ge 2 ] && [ "$node2_nodes" -ge 2 ]; then
        log "✓ Cluster verified - both nodes see 2+ members"
        return 0
    else
        warn "Cluster verification incomplete"
        warn "Node 1 sees ${node1_nodes} members"
        warn "Node 2 sees ${node2_nodes} members"
        return 1
    fi
}

main() {
    echo ""
    echo "╔══════════════════════════════════════════════════════════════╗"
    echo "║          Proxmox Cluster Creation                           ║"
    echo "╚══════════════════════════════════════════════════════════════╝"
    echo ""
    
    check_prerequisites
    echo ""
    
    if ! check_cluster_status; then
        error "One or both nodes are already in a cluster"
    fi
    echo ""
    
    info "Cluster Configuration:"
    echo "  Cluster Name: ${CLUSTER_NAME}"
    echo "  Node 1: ${NODE1_NAME} (${NODE1_IP})"
    echo "  Node 2: ${NODE2_NAME} (${NODE2_IP})"
    echo ""
    
    read -p "Create cluster? (y/N): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        log "Cluster creation cancelled"
        exit 0
    fi
    echo ""
    
    # Try API-based cluster creation
    if create_cluster_on_node1; then
        log "Cluster created on ${NODE1_NAME}"
    else
        error "Failed to create cluster via API"
    fi
    echo ""
    
    # Try to add second node
    if add_node2_to_cluster; then
        log "Node 2 added to cluster"
    else
        warn "Could not add node 2 via API"
        warn "You may need to add it manually via SSH or web UI"
    fi
    echo ""
    
    # Verify cluster
    verify_cluster
    echo ""
    
    log "Cluster creation process complete!"
    echo ""
    info "Next steps:"
    info "1. Verify cluster: Check both nodes in Proxmox web UI"
    info "2. Test cluster: Create a VM and verify it's visible on both nodes"
    info "3. Configure quorum: For 2-node cluster, set expected votes: pvecm expected 2"
}

main "$@"

