#!@WHICHPERL@
=head1 NAME

ame_webservice - Run ame.

=head1 SYNOPSIS

ame_webservice [options] <sequences> <motifs>+

  Options: 
    -control_type user|shuffle|none	user: use sequences provided via -control
					shuffle: use shuffled primary sequences
					none: use no control sequences
    -control <control sequences>  Use the specified control sequences.
    -kmer <k>			  preserve frequencies when shuffling letters
    -xalph <alphabet file>        Translate the motifs to the alphabet.
    -method 
    -scoring
    -hit-lo-fraction
    -evalue-report-threshold
    -bgfile
    -help                         Show this brief help message.

  Motif databases can be specified by prefixing the file name by "db/".

=cut

use strict;
use warnings;
# load standard perl libraries
use Getopt::Long qw(:config permute auto_help);
use Pod::Usage;
# load custom perl libraries
use lib qw(@PERLLIBDIR@);
use Alphabet qw(rna dna protein);
use StatusPage qw(arg_checks arg_end opt_uploaded opt_db_or_uploaded opt_choice opt_integer opt_number);
use Globals;
# constants
my $bin_dir = '@BINDIR@';
my $libexec_dir = '@LIBEXECDIR@';
my $motif_db_dir = '@MEMEDB@/motif_databases';
# Required parameters
my $sequences;
my @motifs;
# Optional parameters
my ($control_type, $control, $xalph_file, $bgfile,
  $hit_lo_fraction, $evalue_report_threshold, $kmer);
my $method = "fisher";
my $scoring = "avg";
#status page
my $status = new StatusPage('AME', \@ARGV);
$status->add_message('Parsing arguments');
# parse options
my @arg_errors = ();
my $opts_ok = do {
  local $SIG{__WARN__} = sub { my ($msg) = @_; chomp($msg); push(@arg_errors, $msg); };
  GetOptions(
  '<>' => arg_checks(
      opt_uploaded(\$sequences),
      opt_db_or_uploaded(\@motifs, $motif_db_dir, 'db')),
  'control_type=s' => opt_choice(\$control_type, 'user', 'shuffle', 'none'),
  'control=s' => opt_uploaded(\$control),
  'kmer=f' => \$kmer,
  'method=s' => opt_choice(\$method, 'fisher', 'ranksum', 'pearson', 'spearman', '3dmhg', '4dmhg'),
  'scoring=s' => opt_choice(\$scoring, 'avg', 'max', 'sum', 'totalhits'),
  'hit-lo-fraction=f' => opt_number(\$hit_lo_fraction, '>', 0, '<=', 1),
  'evalue-report-threshold=f' => opt_number(\$evalue_report_threshold, '>', 0, '<=', 1e300),
  'bgfile=s' => opt_uploaded(\$bgfile),
  'xalph=s' => opt_uploaded(\$xalph_file)
  );
};
# add additional error messages for missing sequences and motifs
push(@arg_errors, "No sequences provided.") unless defined $sequences;
push(@arg_errors, "No motifs provided.") unless @motifs;
# display the error messages both to the status page and stdout
foreach my $arg_error (@arg_errors) {
  print STDERR $arg_error, "\n";
  $status->add_message($arg_error);
}
$opts_ok = 0 if (scalar(@arg_errors) > 0);
# declare some derived file names
# setup status page
$status->add_file('html', 'ame.html', 'AME HTML output');
$status->add_file('tsv', 'ame.tsv', 'AME TSV output');
$status->add_file('seq', 'sequences.tsv', 'AME true- and false-positive sequences') if ($method eq 'fisher');
$status->add_file('pos', $sequences, 'Uploaded Sequences');
$status->add_file('neg', $control, 'Uploaded Control Sequences');
$status->add_file('alph', $xalph_file, 'Uploaded Alphabet');
$status->add_file('bg', $bgfile, 'Uploaded Background');
$status->add_message($opts_ok ? 'Arguments ok' : "Error parsing arguments");
$status->update($opts_ok ? 'Starting' : 'Error');
# exit if there was an error reading the arguments
unless ($opts_ok) {
  $status->write_log();
  pod2usage(2);
}
# create the symlink to the databases
symlink($motif_db_dir, 'db');
# ensure it will be removed on completion (when the log is written)
$status->set_cleanup( sub { unlink('db'); } );
# Run AME
my @ame_args = ('--verbose', 1, '--oc', '.');
if (defined($bgfile)) {
  push(@ame_args, '--bgfile', $bgfile);
}
push(@ame_args, '--scoring', $scoring, '--method', $method);
push(@ame_args, '--hit-lo-fraction', $hit_lo_fraction) if defined $hit_lo_fraction;
push(@ame_args, '--evalue-report-threshold', $evalue_report_threshold) if defined $evalue_report_threshold;
push(@ame_args, '--xalph', $xalph_file) if defined $xalph_file;
push(@ame_args, '--control', $control) if $control;
push(@ame_args, '--control', "--shuffle--") if $control_type eq 'shuffle';
push(@ame_args, '--kmer', $kmer) if defined $kmer;
push(@ame_args, $sequences, @motifs);
$status->run(PROG => 'ame', BIN => $bin_dir, ARGS => \@ame_args);
# done
$status->add_message("Done");
$status->update();
$status->write_log();
1;
