#!/usr/bin/perl -I/usr/local/teamfile/tfsplugin/lib/perl
#
# $Id$
#-------------------------------------------------------------------------------
# TeamFile scheduler script
#
# Copyright (c) BAYBITS LLC, All rights reserved.
#-------------------------------------------------------------------------------
use strict;
use utf8;
use LWP::UserAgent;
use HTTP::Request::Common qw(POST);
use XML::DOM;
use Encode;
use TF::XMLUtils;
use TF::CommonUtils;
use Getopt::Long;

require "/usr/local/teamfile/www/bin/mt-lib.pl";

# global
my $USERAGENT   = 'Mozilla/4.0 (compatible; PerlRedirecter)';
my $LOCK_FILE   = getLogPath() . '/autodelete.pid';
my $LOG_FILE    = getJobsWorkPath() . '/autodelete.log';

my $F_LOG       = undef;
my $opt_h       = undef;
my $opt_v       = undef;

# get argument
my $ret = GetOptions("h" => \$opt_h, "v" => \$opt_v);

if ($opt_h) {
	usage();
	exit(0);
}

main();

#
# main
#
sub main {

	my $now = time();

	# Check Apache status
	my $cRetry = 0;
	while (!isRunning(getApachePidPath())) {
		sleep 1;
		if ($cRetry == 0) {
			printerr("Waiting for Apache to start.");
		}
		$cRetry++;

		printerr(".");

		if ($cRetry >= 30) {
			printerr("\nApache had been stopped. we give up execution of batch job.");
			exit(1);
		}
	}
	my $now2 = time();

	# Check Lock
	if ((my $pid = lockScript($LOCK_FILE)) != 0) {
		printerr("This script had been already started.");
		printerr('If NOT, Please check ' . $pid . ' process and remove ' . $LOCK_FILE . ' file manually.');
		return 1;
	}

	# Initialize logfile
	initLog();

	# read TeamFile configuration
	my %gparams = readTfGlobalSettings();

	$cRetry = 0;
	# check batch JOB status
	while (isRunning($gparams{DAILYBAT_LOOKFILE})) {
		sleep 1;
		$cRetry++;

		if ($cRetry >= 600) {
			writeLog("The backup script is running. we could not execute Autodelete operation.");
			closeLog();
			unlockScript($LOCK_FILE);
			return 0;
		}
	}
	my $now3 = time();

	# read location configuration
	my @files = getLocationConflist();
	foreach my $f (@files) {
		my $now4 = time();

		my %lcparams = parseLocationConf($f, \%gparams);
		if (!%lcparams || !$lcparams{Location}) {
			next;
		}

		if ($lcparams{UseAutodelete} == 0) {
			writeLcLog($lcparams{Location}, "Off");
			next;
		}

		my %adparams = readAutoDeleteSettings($lcparams{Location});
		if (!%adparams || $adparams{isActive} == 0) {
			writeLcLog($lcparams{Location}, "Inactive");
			next;
		}

		# check job time
		if (isItTimeToRunJob($now,  $adparams{hour}, $adparams{min}) ||
			isItTimeToRunJob($now2, $adparams{hour}, $adparams{min}) ||
			isItTimeToRunJob($now3, $adparams{hour}, $adparams{min}) ||
			isItTimeToRunJob($now4, $adparams{hour}, $adparams{min})) {

			doAutodelete(\%gparams, \%lcparams);
		}
		else {
			writeLcLog($lcparams{Location}, "Skipped");
		}
	}

	closeLog();
	unlockScript($LOCK_FILE);

	return 0;
}

#
# Show usage
#
sub usage {
	print <<"_EOF_";
Usage: autodelete [-v] | [-h]
       -v : Show detail status
       -h : Show usage
_EOF_
}

#
# Print message for error
#
sub printerr {
	my $msg = shift || undef;

	if ($opt_v && $msg) {
		print STDERR $msg;
	}
}

#
# Read AutoDelete settings
#
sub readAutoDeleteSettings {
	my $location_name = shift || '';

	if (!$location_name) {
		return undef;
	}
	my %params = ();
	my $filepath = getConfigPath() . '/autodelete/' . $location_name . '.set.xml';

	$params{isActive} = 0;
	$params{hour} = -1;
	$params{min}  = -1;

	if (-f $filepath) {
		my $xml = new XML::DOM::Parser;
		my $doc = $xml->parsefile($filepath);

		for my $elem ( $doc->getElementsByTagName("state") ) {
			my $nodelist = $elem->getElementsByTagName("active");
			if ($nodelist && $nodelist->getLength > 0) {
				$params{isActive} = 1;
			}
			else {
				$params{isActive} = 0;
			}
		}

		for my $elem ( $doc->getElementsByTagName("starttime") ) {
			$params{hour} = TF::XMLUtils::getText($elem,"hour");
			$params{min}  = TF::XMLUtils::getText($elem,"minutes");
		}
		$doc->dispose;
	}
	if ($params{hour} == -1 || $params{min} == -1) {
		$params{isActive} = 0;
	}

	return %params;
}

#
# send AutoDelete request to server
#
sub doAutodelete {
	my $gparams_ref = shift || undef;
	my $param_ref   = shift || undef;

	if (!$gparams_ref || !$param_ref) {
		return 1;
	}

	my %gparams = %{$gparams_ref};
	my $req_uid       = $gparams{TF_SYSEXEC_USER}   || '';
	my $req_pw        = $gparams{TF_SYSEXEC_USERPW} || '';

	my %params = %{$param_ref};
	my $baseuri       = $params{BaseUri};
	my $location_name = $params{Location};

	my $ua  = LWP::UserAgent->new(ssl_opts => {verify_hostname => 0});
	my $req = HTTP::Request->new;

	$req->uri($baseuri . "/.autodelete/");
	$req->method("POST");
	$req->protocol("HTTP/1.1");
	if ($req_uid && $req_pw) {
		$req->authorization_basic($req_uid, $req_pw);
	}
	$req->header("Accept-Language" => "en");
	$ua->agent($USERAGENT);

	my $res = $ua->request($req);
	if ($res->code == 200) {
		writeLcLog($location_name, "Success");
	}
	elsif ($res->code == 401) {
		writeLcLog($location_name, "Error (auth-failure)");
	}
	elsif ($res->code == 403) {
		writeLcLog($location_name, "Error (access-denied)");
	}
	elsif ($res->code == 503) {
		writeLcLog($location_name, "Error (not-available)");
	}
	else {
		writeLcLog($location_name, "Error (" . $res->code . ")");
	}

	return 0;
}

#
# Initialize logfile
#
sub initLog {
	open F_LOG, ">", $LOG_FILE;
}

#
# write logfile
#
sub writeLog {
	my $msg = shift || '';

	if (!$msg) {
		return;
	}

	my $ctime = localtime(time);
	print F_LOG $ctime . ' : ' . $msg . "\n";
}

#
# write location log
#
sub writeLcLog {
	my $location = shift || '';
	my $msg = shift || '';
	if (!$location || !$msg) {
		return;
	}
	writeLog("[" . $location . "]\t\t: " . $msg);
}

#
# Finalize logfile
#
sub closeLog {
	close F_LOG;
}

