#!/usr/bin/perl

#This is a wrapper script that allows us to run phylip with command line arguments. 
#Basically it writes a temp file transparently and feeds that as input to phylip. It 
#ensures nonoverlap by using the full time to name the tempfile; you will never have
#two processes running exactly at the same time. Also, it allows parallelizability
#by doing all operations in a temporary directory, which is then moved up to the main
#directory at the end of the program. This imposes File I/O overhead but what else can
#we do for a program that insists on writing to "outfile"?

use warnings;
use strict;

#The first three command line arguments are program name, input file, output file.
#After that, all remaining options are written to a text file and passed into phylip
#with standard in. 

#Example: phylip_wrapper.pl protdist CDD1008_N16.faa.out CDD1008_N16.faa.out.dist P 2 Y 
#Last three flags give as inputs P (which toggles to PMB distances), 2 (which turns off feedback), and Y (which ends option
#input)

my($progname,$inputfile,$outputfile,@commands) = @ARGV;
my($tempcommandfile,$syscall,$tempdir,$curdir,$tempout,$tempinput);
$syscall = 'date +%s%N';  #gives time since 1970 down to the nanosecond; just a hack to ensure uniqueness of tempfile
$tempcommandfile = 'temp_' . `$syscall`;
chomp($tempcommandfile);
($tempdir = $tempcommandfile) =~ s/temp_/tempdir_/g;
($tempout = $tempcommandfile) =~ s/temp_/tempout_/g;
($tempinput = $tempcommandfile) =~ s/temp_/tempinput_/g;


#Because phylip does not allow us to specify the filename which we want to write to, we will need to
#build a temporary directory, link the tempcommandfile and the infile there, run the program in there
# and then at the end remove the file, move the outfile to the final outputfile, and finally remove
#the directory entirely

#Build tempdir, store current dir, link input file to temp, and change dirs
$curdir = `pwd`;
chomp($curdir);
mkdir($tempdir);
system("ln $inputfile $tempdir\/$tempinput");
chdir($tempdir);

#Print out a temporary command file within this dir
open(TEMP,">$tempcommandfile");
print TEMP join("\n",($tempinput,@commands)) . "\n";
close(TEMP);

#Run the phylip program, suppressing screenout; move the results up to a tempfile
$syscall = "$progname < $tempcommandfile > /dev/null; mv outfile ..\/$tempout;";
system("$syscall");

#Remove the temporary command & input file, move up a directory, remove the tempdir, and finally
#send the outfile to its final destination. 
$syscall = "rm $tempcommandfile; rm $tempinput; cd ..; rmdir $tempdir; mv $tempout $outputfile";
system("$syscall");
