#!/usr/local/bin/perl

use strict;
use warnings;

use lib '/cell_root/software/HPCC/lib/site_perl';
#For testing, use RW replica
#use lib '/afs/.glue.umd.edu/software/HPCC/1.1/lib/site_perl';

use Glue::HPCC::Cluster;
use Glue::HPCC::Utils::FileUtils qw(
	delete_archived_data_dir
	delete_archived_home_dir
);
use Glue::HPCC::Project::Person;
use Glue::HPCC::Project::PersonProject;

use Glue::HPCC::Utils::UserRevocationReasons;

use Getopt::Long;
use File::Basename;
use Time::ParseDate;
#use Data::Dumper;

my %deftype_by_basename =
(	'archive_lustre_dir' => 'lustre-data',
	'archive_nfs_dir' => 'nfs-data',
	'archive_home_dir' => 'home',
);
my $deftype = $deftype_by_basename{basename($0)};

my $DEBUG;
$DEBUG=1;

my $defExpiration = "6 months";

my $urevoc_options = {};


sub usage()
{	print STDERR <<EOF;
$0: Delete a previously archived directory

Usage:
$0 [ --dryrun ] [ --verbose ] \
	[ --force ] [ --grace GRACEDAYS ] \
	[ -reason REASON ] \
	PATH

PATH should be a full path to an archived directory or
the metadata file associated with the archived directory.
(I.e., something in a "pending_deletion" directory).

GRACEDAYS specifies a grace period between when archive expires
and when it should first be normally eligible for deletion.
If the archive is not expired (and past the grace period), it
cannot be deleted unless the --force option is given.  It
is defaulted (in FileUtils, 35 days?).

REASON is the reason for deleting the archive.  If the archive
is expired (and past the grace period), this will be defaulted
to something like "Archive expired".  Otherwise, it is REQUIRED.
It may be repeated to give multiple reasons.

--verbose increases verbosity of actions.
--dryrun causes us to just pretend to delete the archive, but
not actually do anything.

This script will log actions to PDB as well as update the
metadata file for the archive and move it to the DELETED directory.

EOF
}

sub delete_archived_directory(@)
#Does the actual work of deleting the archived directory (or at least setting
#up the call to the method in FileUtils to do so).
#Takes key => value pairs for arguments, recognizing
#	path: path to existing archived directory or metadata file, REQUIRED
#	hpc: A Glue:HPCC::Cluster instance, used to access PDB for logging
#	reason: list ref of reasons.  REQUIRED unless archive is expired
#	logreason: list ref of reasons, for PDB logs.  Defaults from reason.
#	gracedays: grace period, in days.  It is defaulted in FileUtils.
#	force: if set, we are willing to clobber existing archives/metainfo/etc.
#
{	my %args = @_;
	my $me = 'delete_archived_directory';

	my $path = delete $args{path};
	my $hpc = delete $args{hpc};
	my $reason = delete $args{reason};
	my $logreason = delete $args{logreason};
	my $force = delete $args{force};
	my $gracedays = delete $args{gracedays};

	if ( scalar(%args) )
	{	my @temp = keys %args;
		my $temp = join ", ", @temp;
		die "$me: Extraneous arguments [ $temp ], aborting.\n";
	}

	die "$me: Missing required parameter 'path' at " unless $path;
	die "$me: Missing required parameter 'hpc' at " unless $hpc;

	die "$me: Illegal value '$hpc' for hpc, expecting " .
		"Glue::HPCC::Cluster instance at "
		if $hpc && ! ref($hpc);


	#Convert path to absolute
	if ( $path =~ /^\~/ )
	{	die "$me: Unable to handle ~'s in path\n";
	}

	if ( $path !~ /^\// )
	{	#Not absolute
		my $cwd = $ENV{PWD};
		unless ( $cwd =~ /^\// )
		{	die "$me: Unable to convert '$path' to absolute path" 
				. " (cwd=$cwd)";
		}
		$path = "$cwd/$path";
	}

	unless ( -e $path )
	{	die "$me: Path '$path' does not exist, aborting.";
	}

	my $dtype = 'data';
	$dtype = 'home' if ( $path =~ /\/home\// || $path =~ /\/homes\// );

	#Undefine reason/logreason if empty lists
	if ( $reason )
	{	$reason = [ $reason ] unless ref($reason) eq 'ARRAY';
		$reason = undef unless scalar(@$reason);
	} else
	{	$reason = undef;
	}

	if ( $logreason )
	{	$logreason = [ $logreason ] unless ref($logreason) eq 'ARRAY';
		$logreason = undef unless scalar(@$logreason);
	} else
	{	$logreason = undef;
	}


	my @args = 
	( 	archive => $path,
		hpc => $hpc,
		force => $force,
		reason => $reason,
		logreason => $logreason,
		gracedays => $gracedays,
	);

	my $err;
	if ( $dtype eq 'home' )
	{	$err = delete_archived_home_dir(@args)
	} else
	{	$err = delete_archived_data_dir(@args)
	}
	if ( $err )
	{	die "ERROR: Error deleting archived directory: $err\n";
	}
	return;
}

#=====================================================================
#	Main
#=====================================================================
	
my $help;
my $path;
my ( $force, $dryrun, $verbose );
my $reason = [];
my $logreason = [];
my $gracedays;

my $res = GetOptions(
	'help!' => \$help,
	'dryrun!' => \$dryrun,
	'force!' => \$force,
	'debug!' => \$DEBUG,
	'verbose!' => \$verbose,
	'reason=s' => $reason,
	'logreason=s' => $logreason,
	'gracedays=f' => \$gracedays,

);

unless ( $res )
{	usage;
	die "Error parsing options.\n";
}

$path = shift @ARGV;

if ( @ARGV )
{	my $temp = join ", ", @ARGV;
	usage;
	die "Extraneous arguments [ $temp ], aborting.\n";
}

unless ( $path )
{	usage;
	die "You must provide a path to the archived directory to delete.\n";
}

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

$hpc->verbose($verbose);
$hpc->dryrun($dryrun);
#Glue::HPCC::Utils::MailUtils::verbose($verbose);
#Glue::HPCC::Utils::MailUtils::dryrun($dryrun);
Glue::HPCC::Utils::FileUtils::verbose($verbose);
Glue::HPCC::Utils::FileUtils::dryrun($dryrun);

my $err = delete_archived_directory(
	path => $path,
	hpc => $hpc,
	reason => $reason,
	logreason => $logreason,
	force => $force,
	gracedays => $gracedays,
);

die "Error deleting archived directory: $err\n" if $err;
exit 0;
