#!/usr/bin/env perl
# -*- perl -*-

=head1 NAME

exploc_p

=head1 SYNOPSIS

exploc_p [options] <inputFile1> <inputFile2>

Options:

	--help			brief help message
	--man			full documentation
	--verbose		verbose
	--exparnap-params	parameters for ExpaRNA-P
	--locarna-params	parameters for LocARNA
	--output		path to output folder
	--output-time		output individual runtimes

=head1 OPTIONS

=over 20

=item  B<--help>

prints brief help message and exits.

=item  B<--man>

prints full documentation and exits.

=item B<--verbose>

shows in addition the output of ExpaRNA-P and LocARNA.

=item B<--exparnap-params>

parameters for ExpaRNA-P (def="").

=item B<--locarna-params>

parameters for LocARNA (def="").

=item B<--output>

path to output folder where intermediate results are stored.

=item B<--output-time>

print individual times for Preprocessing, ExpaRNA-P and LocARNA.

=back

=head1 DESCRIPTION

 Implementation of the ExpLoc-P pipeline

=cut

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/../lib/perl";
my $prefix = "$FindBin::Bin/..";
my $bindir = "$FindBin::Bin";

use Pod::Usage;
use Getopt::Long;

my $exparnap_params = "";
my $locarna_params = "";
my $output_folder = "";
my ($output_time,$verbose,$help,$man);

GetOptions("exparnap-params=s" => \$exparnap_params,
           "locarna-params=s" => \$locarna_params,
           "output=s" => \$output_folder,
           "output-time" => \$output_time,
           "verbose" => \$verbose,
		 "help" => \$help,
		 "man" => \$man
           ) || pod2usage(2);

pod2usage(1) if $help;
pod2usage(-exitstatus => 1, -verbose => 2) if $man;

if(scalar(@ARGV)<2){
	print STDERR "Not enough arguments provided! \n";
	pod2usage(2);
}

if($output_folder ne ""){
	## change to output directory -> output will be written there
	chdir $output_folder or die "Couldn't change to directory $output_folder: $!";
}

my $input_file1 = $ARGV[0];
my $input_file2 = $ARGV[1];

## check ExpaRNA-P params (output-anchor-pp)
my @exparnap_params_arr = split(/ /,$exparnap_params);
my $name_anchor_pp="";
for my $i (0 .. scalar(@exparnap_params_arr)-1) {
	if($exparnap_params_arr[$i] eq "--output-anchor-pp"){$name_anchor_pp=$exparnap_params_arr[$i+1] if $i+1<scalar(@exparnap_params_arr);}
}
if($name_anchor_pp eq ""){
	$name_anchor_pp = "anchor-pp";
	$exparnap_params = $exparnap_params . " --output-anchor-pp $name_anchor_pp";
}

## check if LocARNA params specify --min-prob
my @locarna_params_arr = split(/ /,$locarna_params);
my $min_prob_locarna = -1;
for my $i (0 .. scalar(@locarna_params_arr)-1) {
	if($locarna_params_arr[$i] eq "--min-prob"){
		$min_prob_locarna = $locarna_params_arr[$i+1] if $i+1<scalar(@locarna_params_arr);
	}
}

## set --out-min-prob for ExpaRNA-P
if($min_prob_locarna != -1) {
	$exparnap_params = $exparnap_params . " --out-min-prob $min_prob_locarna";
}

## add option stopwatch in order to extract the runtimes
if($output_time){
	$exparnap_params = $exparnap_params . " --stopwatch";
	$locarna_params = $locarna_params . " --stopwatch";
}

## call ExpaRNA-P
$exparnap_params = $exparnap_params . " " . $input_file1 . " " . $input_file2 ;
my $exparnap_call = $bindir."/exparna_p " . $exparnap_params;

if($verbose){ print "ExparnaP call: $exparnap_call \n \n"; }

my $exparnap_out = `$exparnap_call 2>&1`;

if($verbose){ print $exparnap_out . "\n";}

## check whether pp files with anchor constraints exist
my $anchor_pp_A = $name_anchor_pp . "_A.pp";
my $anchor_pp_B = $name_anchor_pp . "_B.pp";

if(! (-e $anchor_pp_A && -e $anchor_pp_B) ){
	die "anchor pp files - $anchor_pp_A and $anchor_pp_B - do not exist! \n";
}

## call LocARNA with anchor constraints

my $locarna_call = $bindir."/locarna " . $locarna_params . " " . $anchor_pp_A . " " . $anchor_pp_B;

if($verbose){ print "LocARNA call: $locarna_call \n";}

my $locarna_out = `$locarna_call 2>&1`;

print $locarna_out;

if($output_time){

	## parse preprocessing and total time
	my ($preproc_time, $exparnap_time) = (0,0);
	extract_times(\$exparnap_out,\$preproc_time,\$exparnap_time);

	## substract preprocessing time from total ExpARNA-P time
	$exparnap_time -= $preproc_time;

	## parse total time
	my ($dummy, $locarna_time) = (0,0);
	extract_times(\$locarna_out,\$dummy,\$locarna_time);

	print "\n";
	print "------------------------------- \n";
	print "Stopped Times \n";
	print "time Preprocessing: $preproc_time \n";
	print "time Exparna-P: $exparnap_time \n";
	print "time LocARNA: $locarna_time \n";
}

##-------------------------------------------------------------------------------------------------------------

sub extract_times{
	my $out = shift; # reference to output
	my $preproc_time = shift;
	my $total_time  = shift;
	my @output = split(/\n/,$$out);
	foreach(@output){
		if($_ =~ m/\s*bpp\s*(\d+\.\d+)s.*/){
			$$preproc_time = $1;
		}
		elsif($_ =~ m/\s*total\s*(\d+\.\d+)s.*/){
			$$total_time = $1;
		}
	}
}
