#! /usr/bin/perl

# This script queries all of the schedd's and prints out what is going
# on with them concerning wrapped partitions and workloads to be done.

# each classad described one schedd's glidded in startds and workloads.

# from h/proc.h
#define UNEXPANDED  0
#define IDLE        1
#define RUNNING     2
#define REMOVED     3
#define COMPLETED   4
#define HELD        5
#define SUBMISSION_ERR  6

my $condor_q_cmd = "/home/condor/bin/condor_q";
my $condor_status_cmd = "/home/condor/bin/condor_status";

# Find all of the schedds the collector knows about
sub discover_schedds
{
	my @schedds;
	my @results;
	my $cmd;

	# wait until the collector is up
	@results = `$condor_status_cmd -schedd -format "%s\n" Name 2>&1`;
	while(scalar(grep(/(^Error:|Failed to connect)/, @results)) > 0) {
		sleep 1;
		@results = `$condor_status_cmd -schedd -format "%s\n" Name 2>&1`;
	}

	# wait until there is at least one schedd
	@results = `$condor_status_cmd -schedd -format "%s\n" Name 2>&1`;
	while(scalar(grep(/\w/, @results)) <= 0) {
		sleep 1;
		@results = `$condor_status_cmd -schedd -format "%s\n" Name 2>&1`;
	}

	# prepare the names for use, getting rid of empty lines, etc
	@schedds = grep(/\w/, @results);
	map { chomp($_); } @schedds;
	
	return @schedds;
}

# For a specified schedd, figure out how many BGP jobs of what htc kind are
# idle or running.
sub query_schedd
{
	my $schedd = shift(@_);
	my @jobs;
	my $job;
	my ($kind, $state);
	my $name;
	my %sums;
	
	# This will return tab delimited an array like:
	# "VN	1"
	# "VN	2"
	# "SMP	2"
	# "SMP	1"
	# "SMP	1"
	# "VN	2"
	# "SMP	1"
	# "SMP	2"
	# "VN	2"
	# "SMP	2"
	# "SMP	2"
	# "DUAL	1"
	# "DUAL	1"
	# "VN	2"
	# "DUAL	1"
	# "DUAL	1"
	# "VN	2"
	@jobs = `$condor_q_cmd -n $schedd -format "%s\t" BGP_BLOCK_TYPE -format "%d\n" JobStatus 2>&1`;
	map { chomp($_); } @jobs;

	# init the sums
	$sums{"IDLE"}{"SMP"} = 0;
	$sums{"IDLE"}{"DUAL"} = 0;
	$sums{"IDLE"}{"VN"} = 0;

	$sums{"RUNNING"}{"SMP"} = 0;
	$sums{"RUNNING"}{"DUAL"} = 0;
	$sums{"RUNNING"}{"VN"} = 0;

	# now, count up how many IDLE and RUNNING jobs we have of each kind
	foreach $job (@jobs) {
		($kind, $state) = split /\t/, $job;
		$kind = uc($kind); # just in case
		if ($state == 1) {
			$sums{"IDLE"}{$kind}++;
		} elsif ($state == 2) {
			$sums{"RUNNING"}{$kind}++;
		}
	}

	return \%sums;
}

sub emit_ads
{
	my $resultsref = shift(@_);
	my $schedd;
	my $sref;

	foreach $schedd (keys %{$resultsref}) {
		$sref = $resultsref->{$schedd};
		print qq|WorkloadName = "$schedd"\n|;
		print qq|SMPIdle = $sref->{"IDLE"}{"SMP"}\n|;
		print qq|SMPRunning = $sref->{"RUNNING"}{"SMP"}\n|;
		print qq|DUALIdle = $sref->{"IDLE"}{"DUAL"}\n|;
		print qq|DUALRunning = $sref->{"RUNNING"}{"DUAL"}\n|;
		print qq|VNIdle = $sref->{"IDLE"}{"VN"}\n|;
		print qq|VNRunning = $sref->{"RUNNING"}{"VN"}\n|;
		print "---\n";
	}
}

sub query_workloads
{
	my @schedds;
	my $schedd;
	my $sumsref;
	my %results;

	@schedds = discover_schedds();

	foreach $schedd (@schedds) {
		$sumsref = query_schedd($schedd);
		$results{$schedd} = $sumsref;
	}

	emit_ads(\%results);
}

sub main
{
	query_workloads();

	return 0;
}

exit main();


# example stub ads...
#print qq|WorkloadName = "gthain\@cs.wisc.edu"\n|;
#print qq|SMPIdle = 100\n|;
#print qq|SMPRunning = 0\n|;
#print qq|DUALIdle = 0\n|;
#print qq|DUALRunning = 0\n|;
#print qq|VNIdle = 0\n|;
#print qq|VNRunning = 0\n|;

#print qq|---\n|;
#print qq|WorkloadName = "gquinn\@cs.wisc.edu"\n|;
#print qq|SMPIdle = 1024\n|;
#print qq|SMPRunning = 0\n|;
#print qq|DUALIdle = 0\n|;
#print qq|DUALRunning = 0\n|;
#print qq|VNIdle = 256\n|;
#print qq|VNRunning = 0\n|;
