#!/usr/local/bin/perl
#
#Script to list departments in PDB
use strict;
use warnings;

use lib "/cell_root/software/HPCC/lib/site_perl";
#Temporary for debugging
#use lib "/afs/.glue.umd.edu/software/HPCC/1.1/lib/site_perl";

use Glue::HPCC::Cluster;
use Glue::HPCC::Project::College;
use Glue::HPCC::Project::Department;

use Getopt::Long;

my $PARSABLE;

sub usage()
{	print STDERR <<EOF;
$0: List departments

Usage:
$0 [ -verbose [ ---parsable ] ] [ -cluster CLUSTER ] [ -college COLLEGE ] \\
	[ -grep REGEXP [ --[no]case-sensitive ] ]

List departments for projects DB for a HPC cluster.  
If CLUSTER is not provided, it will be defaulted based on the 
system you are running the command on (i.e. whatever HPC 
cluster it belongs to).

The --college parameter can be repeated.  If one of more
COLLEGE codes are given, only departments in one of the 
specified colleges are listed.  If no COLLEGEs specified,
all departments are listed.

In non-verbose mode, only a list of department 'codes' printed.  
In verbose mode, some additional information is printed.
If --parsable also given, output is machine parsable.

If REGEXP is given, only departments whose descriptions match 
the regular expression are displayed.  The regular expression is matched
case-insensitively unless --case-sensitive is given.
Note that you still need to 
give -verbose to see more than the dept code displayed.

EOF
}

sub dump_verbose($;$)
#Dumps college entry in verbose mode
#If no arg given, print header
#Otherwise, we want a College object
{	my $hpc = shift;
	my $dept = shift;
	my $me = 'dump_verbose';

	die "Missing req parm hpc at " unless $hpc && ref($hpc);
	my $cluster = $hpc->db_clustername;

	#           clu pkey coll code name des
	my $fmt = "%-8s %-4s %-7s %-12s %-20s %-s\n";
	my $hfmt = $fmt;
	$fmt = "%s|%s|%s|%s|%s|%s\n" if $PARSABLE;
	$hfmt = "#$fmt" if $PARSABLE;
	unless ( $dept )
	{	#Print header mode
		printf $hfmt, "Cluster", "Pkey", "College", "Code", "Name", "Description";
		return;
	}

	my $code = $dept->code;
	my $name = $dept->name;
	my $desc = $dept->description;
	my $pkey = $dept->dept_pkey;
	my $collid = $dept->college;
	my $coll = Glue::HPCC::Project::College->college_by_pkey($hpc, $collid);
	my $college = $coll->code;

	
	printf $fmt, $cluster, $pkey, $college, $code, $name, $desc;
	return;
}


#-------------------------------------------------------------------
#		Main
#-------------------------------------------------------------------

my ($help, $verbose, $cluster);
my $colleges = [];
my $regexp;
my $casesens = 0;

my $res = GetOptions(
	'help!' => \$help,
	'verbose!' => \$verbose,
	'parsable!' => \$PARSABLE,
	'cluster=s' => \$cluster,
	'college=s' => $colleges,
	'grep=s' => \$regexp,
	'case-sensitive|case_sensitive|casesensitive!' => \$casesens,

);

unless ( $res )
{	usage;
	die "\nError processing options.\n";
}
if ( $help )
{	usage;
	exit 0;
}
if ( scalar(@ARGV) )
{	usage;
	my $tmp = join ", ", @ARGV;
	die "\nError: extraneous arguments [ $tmp ], aborting.\n";
}

#Default cluster if needed
my $hpc = Glue::HPCC::Cluster->new_from_clustername($cluster);
die "\nInvalid cluster $cluster at " if $cluster && ! $hpc && ! ref($hpc);
die "\nError instantiating cluster $hpc " unless $hpc && ref($hpc);
$cluster = $hpc->db_clustername;

#Get all dept entries
my $depts = Glue::HPCC::Project::Department->pdb_query($hpc);
die "No departments found.  Error???? at " unless $depts;
die "Error looking up depts: $depts at " unless ref($depts);

my @depts = @$depts;

#Restrict to those in specified colleges.
if ( scalar(@$colleges) )
{	my $colls = [ map { Glue::HPCC::Project::College->college_by_code(
		$hpc, $_ ) } @$colleges ];
	my %collids = map { $_->coll_pkey => undef } @$colls;
	@depts = grep { exists $collids{$_->college} } @depts;
}

if ( $regexp )
{	if ( $casesens )
	{	@depts = grep { $_->description =~ /$regexp/ } @depts;
	} else
	{	@depts = grep { $_->description =~ /$regexp/i } @depts;
	}
}

unless ( scalar(@depts) )
{	print "*** No departments found in $cluster meeting requested criteria\n";
	exit;
}

if ( $verbose )
{	dump_verbose($hpc);
}

@depts = sort { $a->code cmp $b->code } @depts;

foreach my $dept (@depts)
{	
	if ( $verbose )
	{	#We print for each matching entry
		dump_verbose($hpc,$dept);
	} else
	{	#We only print once
		print $dept->code, "\n";
	}
}
