#!/usr/local/bin/perl
#
#Script to report on prjects in PDB
use strict;
use warnings;

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

use Glue::HPCC::Cluster;
use Glue::HPCC::Project::Person;
use Glue::HPCC::Project::PersonProject;
use Glue::HPCC::Project::Project;

use Getopt::Long;

sub usage()
{	print STDERR <<EOF;
$0: List members of a project

Usage:
$0 [ -cluster CLUSTER ] [ -role (member|poc|coord|all) ] \
	[ -v ] [ --disabled ] [ -project ]  PROJECT

List users belonging to a project.
If role is given, list users which are PoC or coordinator of 
the project (default is member).  If role is all, all users associated
with the project are listed.

If verbose mode, give fullname, email, and role in addition to usernames.
If CLUSTER is given, attach to PDB for that cluster; default is based
on host you are running on.  Normally, only active users are shown,
the --disabled flag will also show disabled users (these will have
asterisk next to username in output)

EOF
}



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

my $help;
my $verbose;
my $projects = [];
my $role = 'member';
my $cluster;
my $inactive;

my $res = GetOptions(
	'help!' => \$help,
	'verbose!' => \$verbose,
	'cluster=s' => \$cluster,
	'disabled!' => \$inactive,
	'project=s' => $projects,
	'role=s' => \$role,
);

unless ( $res ) 
{	usage;
	die "\nError processing options.\n";
}
if ( $help )
{	usage;
	exit 0;
}
if ( scalar(@ARGV) )
{	if ( scalar(@$projects) == 0 )
	{	#Allow user to omit --project
		$projects = [ @ARGV ];
	} else
	{	my $tmp = join ", ", @ARGV;
		usage;
		die "\nError: extraneous arguments [ $tmp ], aborting\n";
	}
}

unless ( $role )
{	usage;
	die "\nRequired parameter role is missing.\n";
}
$role = lc $role;
$role =~ s/s$//;
$role = 'member' if $role eq 'user';
$role = 'coord' if $role eq 'coordinator';
unless ( $role eq 'member' || $role eq 'coord' || $role eq 'poc' || 
	$role  eq 'all' )
{	usage;
	die "\nIllegal role $role; expecting one of " .
		"'member', 'coord', 'poc', or 'all' \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;

unless ( scalar(@$projects) )
{	usage;
	die "\nNo projects specified.\n";
}

PROJECT: foreach my $project (@$projects)
{	if ( scalar(@$projects) > 1 )
	{	print <<EOF;
#---------------------------------------------------------------------------
#-	Project $project
#---------------------------------------------------------------------------
EOF
	}
	my $proj= Glue::HPCC::Project::Project->project_by_name($hpc,$project);
	unless ( $proj )
	{	warn "Project $project NOT found.\n";
		next PROJECT;
	}
	unless ( ref($proj) )
	{	warn "Error looking up project $project: $proj at ";
		next PROJECT;
	}

	my $prj_pkey = $proj->prj_pkey;

	my $people_recs = Glue::HPCC::Project::PersonProject->pdb_query(
		$hpc, prj_pkey => $prj_pkey);
	die "Error looking up people associate with project $project: " .
		"$people_recs at " 
		unless $people_recs && ref($people_recs) eq 'ARRAY';

	if ( $role eq 'member' )
	{	 $people_recs = [ grep { $_->is_member } @$people_recs ];
	} elsif  ( $role eq 'poc' )
	{	 $people_recs = [ grep { $_->is_poc } @$people_recs ];
	} elsif (  $role eq 'coord' )
	{	 $people_recs = [ grep { $_->is_coordinator } @$people_recs ];
	}

	my @people = map { Glue::HPCC::Project::Person->person_by_pkey($hpc,
		$_->ppl_pkey) } @$people_recs;
	@people = grep { $_->active } @people  unless $inactive;
	@people = sort { $a->username cmp $b->username } @people;

	unless ( @people )
	{	print "# No users matching role $role for $project\n";
		next PROJECT;
	}

	my ($user, $username);
	if ( $verbose )
	{	my $fmt="%-10s %-20s %-20s %-10s\n";
		printf $fmt, "Username", "Name", "Email", "Roles";

		my %rec_by_ppl_key = map { $_->ppl_pkey => $_ } @$people_recs;

		foreach $user (@people)
		{	$username = $user->username;
			my $full = $user->fullname;
			my $email = $user->email;
			my $active = $user->active;
			my $disflag = '';
			$disflag = '*' unless $active;
			my $roles = '';
			my $sep = '';
			my $rec = $rec_by_ppl_key{$user->ppl_pkey};

			if ( $rec->is_poc )
			{	$roles .= $sep;
				$sep = ', ';
				$roles .= 'PoC';
			}
			if ( $rec->is_coordinator )
			{	$roles .= $sep;
				$sep = ', ';
				$roles .= 'coordinator';
			}
			if ( $rec->is_member )
			{	$roles .= $sep;
				$sep = ', ';
				$roles .= 'member';
			}

			printf $fmt, $username . $disflag, $full, $email, $roles;
		}
	} else
	{	foreach $user (@people)
		{	$username = $user->username;
			print "$username\n";
		}
	}
}
