#!/usr/bin/perl

BEGIN {
#use lib 'd:/Programs/Perl/lib';
#use lib '/home/tkamiya/bin/lib';
my $BaseDir = $ENV{'TkPerlDir'};
#print "\nBaseDir: $BaseDir\n";
@INC = ("$BaseDir/lib", "$BaseDir/VNL", "d:/Programs/Perl/lib", @INC);
}

use strict;
use lib "d:/Programs/Perl/lib";
use Cwd;

use Utils;
use IniFile;

my $IniFile    = ($ARGV[0] eq '')? 'DoBatch.ini' : $ARGV[0];

my $Mode       = "CIF";
my $BaseDir    = cwd(); #"$ENV{HOME}/data-vasp/AB"
my @QueueDir   = (Deps::MakePath($BaseDir, "queue", 0));
my $ScriptName = "DoVASP.sh";
my $ScriptTemplateName = "DoVASP-Template.sh";

my $LogFile    = "Test.log";
my $SkipFiles  = "(\\.moved)\$";
my $SortBy     = "time";
my $Sleep      = 2;

	my $WriteNoActiveTargetLog  = 1;
	my $WriteNoActiveTargetLog2 = 1;
	while(1) {
		my $ini = new IniFile;
		$ini->ReadAll($IniFile);
		$Mode               = $ini->{Mode}               if($ini->{Mode} ne '');
		$Sleep              = $ini->{Sleep}              if($ini->{Sleep} ne '');
		$SkipFiles          = $ini->{SkipFiles}          if($ini->{SkipFiles} ne '');
		$Mode               = $ini->{Mode}               if($ini->{Mode} ne '');
		$BaseDir            = $ini->{BaseDir}            if($ini->{BaseDir} ne '');
		$QueueDir[0]        = $ini->{QueueDir1}          if($ini->{QueueDir1} ne '');
		$QueueDir[1]        = $ini->{QueueDir2}          if($ini->{QueueDir2} ne '');
		$QueueDir[2]        = $ini->{QueueDir3}          if($ini->{QueueDir3} ne '');
		delete $QueueDir[1]                              if($ini->{QueueDir2} eq 'none');
		delete $QueueDir[2]                              if($ini->{QueueDir3} eq 'none');
		$ScriptName         = $ini->{ScriptName}         if($ini->{ScriptName} ne '');
		$ScriptTemplateName = $ini->{ScriptTemplateName} if($ini->{ScriptTemplateName} ne '');
		if(chdir($BaseDir)) {
#			system("ls");
		}
		else {
			print("chdir [$BaseDir] failed.\n");
		}

		for(my $i = 0 ; $i < @QueueDir ; $i++) {
			my $QueueDir = $QueueDir[$i];

			my @files;
			if($Mode eq 'CIF') {
				@files = glob(Deps::MakePath($QueueDir, "*.cif", 0));
			}
			else {
				@files = glob(Deps::MakePath($QueueDir, "*", 0));
			}
			if(@files == 0) {
				print("No active target found.\n");
				&UpdateLog($LogFile, "No active target found.") if($WriteNoActiveTargetLog);
				$WriteNoActiveTargetLog = 0;
				sleep($Sleep);
				next;
			}
			$WriteNoActiveTargetLog = 1;

			if($SortBy eq 'time') {
				@files = sort { Utils::GetWriteDate($a) <=> Utils::GetWriteDate($b); } @files;
			}
			else {
				@files = sort { $a cmp $b; } @files;
			}

			if(&Execute(\@files, $SkipFiles, $LogFile)) {
				last;
			}
			else {
				sleep($Sleep);
				next;
			}
		}
	}

exit;

#=================================================
# Subroutines
#=================================================
sub Execute
{
	my ($pfiles, $SkipFiles, $LogFile) = @_;

	my @files = @$pfiles;
	my ($SourceDir, $DirName);
	for(my $i = 0 ; $i < @files ; $i++) {
		if($Mode eq 'CIF') {
			next if(!-f $files[$i]);
		}
		else {
			next if(!-d $files[$i]);
			next if(!-f Deps::MakePath($files[$i], $ScriptName));
		}

		if($files[$i] =~ /$SkipFiles/) {
			print("Moved directory/file [$files[$i]] found: Skip.\n");
			next;
		}

		my ($drive, $directory, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($files[$i]);
#print("fn: $filename\n");
		if(-e $filebody) {
			print("Directory [$filebody] exists: Skip.\n");
			next;
		}

		my $t = Utils::GetWriteDate($files[$i]);
		print("$i: $files[$i] [", Utils::BuildDateString($t), "]\n");
		$SourceDir = $files[$i];
		$DirName = $filebody;
		last;
	}
	if(!defined $SourceDir) {
		print("No active target found.\n");
		&UpdateLog($LogFile, "No active target found.") if($WriteNoActiveTargetLog2);
		$WriteNoActiveTargetLog2 = 0;
		return 0;
	}
	$WriteNoActiveTargetLog2 = 1;

	my $cmd;
	if($Mode eq 'CIF') {
		$cmd = "mkdir $DirName; cp $SourceDir $DirName; cp $ScriptTemplateName $DirName/$ScriptName";
	}
	else {
		$cmd = "cp -r $SourceDir $DirName";
	}
	my $ret;
	if($ret = system($cmd)) {
		print("Execute [$cmd] failed [$ret].\n");
		return 0;
	}
	else {
		print("Executed: [$cmd]\n");
	}

	if(chdir($DirName)) {
#		system("ls");
	}
	else {
		print("chdir [$DirName] failed.\n");
		return 0;
	}

	$cmd = "mv $SourceDir $SourceDir.moved";
	if($ret = system($cmd)) {
		print("Execute [$cmd] failed.\n");
		return 0;
	}

	print("\n\n");
	print("Execute [$ScriptName] in [$DirName]\n");
	&UpdateLog($LogFile, "Execute [$ScriptName] in [$DirName]: Start");
	if($ret = system($ScriptName)) {
		print("  Error: Execute [$ScriptName] failed [$ret] in [$DirName].\n");
		&UpdateLog($LogFile, "Error: Execute [$ScriptName] failed [$ret] in [$DirName].");
		return 0;
	}

	&UpdateLog($LogFile, "Execute [$ScriptName] in [$DirName]: Finish");

	return 1;
}

sub UpdateLog
{
	my ($LogFile, $message) = @_;
	return if($LogFile eq '');

	my $DateString = Utils::BuildDateString(time());
	
	my $in = new JFile;
	my $content = $in->ReadFile($LogFile, undef, undef);
	my $out = new JFile;
	if(!$out->Open($LogFile, "w")) {
		print "Error: Can not write to log file [$LogFile].\n";
		return;
	}
	$out->print("$DateString: $message\n");
	$out->print($content);
	$out->Close();
}
	