#!/usr/local/bin/perl
#
#Script to modify 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;

sub usage()
{	print STDERR <<EOF;
$0: Adds a department to HPC projects DB

Usage:
$0 [ --dryrun ] [ --verbose ]  [ --force ] \\
	[ -cluster CLUSTER ] -code CODE \\
	[ -newcode NEWCODE ] \\
	[ -college NEWCOLLEGE ] \\
	[ -name NEWNAME ] \\
	[ -desc NEWDESC ]

Modifies a row in the department table of the
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 following fields can be given.
	CODE: the (current) code for the department to modify.
		E.g. cmns, engr.  REQUIRED
	NEWCODE: the code to change to.
	NEWNAME: the name to change to.
	NEWDESC: the desc to change to.
	NEWCOLLEGE: the code for college to change to
If any of NEWCODE, NEWNAME, NEWDESC, NEWCOLLEGE not given, 
that field will not be changed.

In dryun mode, the SQL will be printed but not executed.
In verbose mode, the SQL will be printed AND executed.
In force mode, bypass the verification prompt.

EOF
}

sub verify_changes($$$)
{	my $hpc = shift;
	my $old = shift;
	my $changes = shift;

	my $pkey = $old->dept_pkey;
	my $oldcode = $old->code;
	my $oldname = $old->name;
	my $olddesc = $old->description;
	my $oldcollid = $old->college;

	my $notchanging = '(not changing)';
	my $newcode = $changes->{code} || $notchanging;
	my $newname = $changes->{name} || $notchanging;
	my $newdesc = $changes->{description} || $notchanging;
	my $newcollid = $changes->{college};

	my $oldcoll = Glue::HPCC::Project::College->college_by_pkey(
		$hpc, $oldcollid);
	my $oldcollege = $oldcoll->code;
	$oldcollege = "$oldcollege ($oldcollid)";

	my $newcollege = $notchanging;
	if (defined $newcollid)
	{	my $newcoll = Glue::HPCC::Project::College->college_by_pkey(
			$hpc, $newcollid);
		$newcollege = $newcoll->code;
		$newcollege = "$newcollege ($newcollid)";
	}


	print <<EOF;
The following update was requested to the department table.
Record: key=$pkey, code=$oldcode
Code: $oldcode => $newcode
Name: $oldname => $newname
College: $oldcollege => $newcollege
Description: $olddesc => $newdesc

Type yes to continue, or ctrl-c to abort:
EOF

	my $ans = <STDIN>;
	chomp $ans;
	return if $ans =~ /^\s*y(es)?\s*$/i;
	die "Aborting at user request.\n";
}

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

my ($help, $verbose, $dryrun, $cluster, $force);
my ( $code, $newcode, $name, $desc, $collcode );

my $res = GetOptions(
	'help!' => \$help,
	'verbose!' => \$verbose,
	'force!' => \$force,
	'dryrun!' => \$dryrun,
	'cluster=s' => \$cluster,

	'code=s' => \$code,
	'newcode=s' => \$newcode,
	'name=s' => \$name,
	'desc=s' => \$desc,
	'college=s' => \$collcode,
);

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;

$hpc->dryrun($dryrun);
$hpc->verbose($verbose);

unless ( $code )
{	usage;
	die "\nMissing required parameter 'code' for department.\n";
}
$code = lc $code;
$newcode = lc $newcode if $newcode;

my $dept = Glue::HPCC::Project::Department->dept_by_code(
	$hpc, $code);
unless ( $dept )
{	die "\nNo department with code $code found in $cluster, aborting.\n";
}
unless ( ref($dept) )
{	die "\nError looking up department $code in $cluster: $dept.  Aborting.\n";
}

my $changes = {};
my $dept2;
if ( $newcode )
{	die "Ignoring attempt to change code $code to itself" 
		if $code eq $newcode; #This could happen due to case
	$dept2 = Glue::HPCC::Project::Department->dept_by_code(
		$hpc, $newcode);
	if ( $dept2 && ref($dept2) )
	{	die "\nA department with code $newcode already exists.\n";
	}
	$changes->{code} = $newcode;
}

if ( $name )
{	die "Ignoring attempt to change name $name to itself"
		if $name eq $dept->name;
	$dept2 = Glue::HPCC::Project::Department->dept_by_name(
		$hpc, $name);
	if ( $dept2 && ref($dept2) )
	{	die "\nA department with name $name already exists.\n";
	}
	$changes->{name} = $name;
}

if ( $collcode )
{	$collcode = lc $collcode;
	my $newcoll = Glue::HPCC::Project::College->college_by_code(
		$hpc, $collcode);
	die "Illegal value '$collcode' for college; not found in PDB.\n"
		unless $newcoll;
	die "Error looking up college $collcode: $newcoll.\n"
		unless ref($newcoll);
	die "Ignoring attempt to change college $collcode to itself.\n"
		if $newcoll->coll_pkey == $dept->college;
	$changes->{college} = $newcoll->coll_pkey;
}
	
if ( $desc )
{	die "Ignoring attempt to change desc $desc to itself"
		if $desc eq $dept->desc;
	$changes->{description} = $desc;
}

unless ( scalar(%$changes) )
{	usage;
	die "No changes requested, aborting.\n";
}

verify_changes($hpc, $dept, $changes) unless $force;

my $error = Glue::HPCC::Project::Department->pdb_update( $hpc,
	{ dept_pkey => $dept->dept_pkey } , $changes);

if ( $error )
{	die "\nERROR: error updating department: $error\n";
}

$hpc->db_commit;
print "Successfully updated record for department $code\n";
