#!/bin/bash

# Defaults
maxcpus=7
left=10
dryrun=false
verbose=true

args=($@)

# Read args
while [[ -n "${args[@]}" ]] ; do
    a=${args[0]};       # Use first element
    if [[ `expr match ${a} '.*='` != "0" ]] ; then
	args=(${args[@]:1}) # Element processed, pop it off
	#echo Evaluating "$a"
	eval "$a"
    else
	break
    fi
done



eval "p0=({0..$maxcpus})"
p1=()
u=()

echo "Running test"
while [[ $left -gt 0 ]] ; do
    $verbose && echo "Left: $left"
    source=$(shuf -n 1 -e p0 p1 u)
    $verbose && echo " source: $source"

    # Common: Choose a victim
    eval "count=\${#$source[@]}"
    if [[ $count == "0" ]] ; then
	$verbose && echo "  source empty; no action taken"
	continue
    fi
    count=$(($count-1))
    eval "index=\$(shuf -n 1 -e {0..$count})"
    $verbose && echo " index: $index of $count"
    eval "cpu=\${$source[$index]}"
    $verbose && echo " cpu: $cpu"
    
    case $source in
	p*)
	    dest="u"

	    # Generate the command
	    cmd="xl cpupool-cpu-remove $source $cpu"
	    ;;

	u)
	    # Choose a destination
	    dest=$(shuf -n 1 -e p0 p1)
	    $verbose && echo " dest: $dest"
	    
	    # Generate the command
	    cmd="xl cpupool-cpu-add $dest $cpu"
	    ;;
    esac

    # Try the command
    success=true
    $verbose && echo " cmd: $cmd"
    if ! $dryrun ; then
	if  ! $cmd ; then
	    success=false
	    # This is expected if we're removing the last cpu from p0
	    if ! [[ $source=="p0" && $count=="0" ]] ; then
		echo "Command $cmd failed"
		xl cpupool-list -c
		for i in p0 p1 u ; do
		    eval "echo \" $i: \${$i[@]}\""
		done
	    fi
	fi
    fi

    # Move the victim
    if $success ; then
	eval "unset $source[$index]"
	eval "${source}=(\${$source[@]})"
	eval "${dest}=(\${$dest[@]} $cpu)"
	$verbose && eval "echo \" $source: \${$source[@]}\""
	$verbose && eval "echo \" $dest: \${$dest[@]}\""

	left=$(($left-1))
    fi
done

$dryrun || xl cpupool-list -c

echo "Resetting"
for source in p1 u; do
    eval "count=\${#$source[@]}"
    if [[ $count == "0" ]] ; then
	$verbose && echo "  source empty; no action taken"
	continue;
    fi

    while eval "[[ -n \"\${$source[@]}\" ]]" ; do
	# Designate victim 
	index=0
	eval "count=\${#$source[@]}"
	$verbose && echo " index: $index of $count"
	eval "cpu=\${$source[$index]}"
	$verbose && echo " cpu: $cpu"

	case $source in
	    p*)
		dest="u"
		
	    # Generate the command
		cmd="xl cpupool-cpu-remove $source $cpu"
		;;
	    
	    u)
	    # Choose a destination
		dest="p0"
		$verbose && echo " dest: $dest"
		
	    # Generate the command
		cmd="xl cpupool-cpu-add $dest $cpu"
		;;
	esac

	eval "unset $source[$index]"
	eval "${source}=(\${$source[@]})"
	eval "${dest}=(\${$dest[@]} $cpu)"
	$verbose && eval echo " $source: \${$source[@]}"
	$verbose && eval echo " $dest: \${$dest[@]}"

	$verbose && echo " cmd: $cmd"
	if ! $dryrun ; then
	    if  ! $cmd ; then
		echo "Command $cmd failed"
		xl cpupool-list -c
		for i in p0 p1 u ; do
		    eval "echo \" $i: \${$i[@]}\""
		done
	    fi
	fi
    done
done

$dryrun || xl cpupool-list -c
