#!@WHICHPERL@
=head1 NAME

cismapper_webservice - Run cismapper in a restricted mode and create an index webpage.

=head1 SYNOPSIS

  cismapper_webservice [options] <locus_file> <rna_source>
  
  Options:
  
    -tissues <tissues>              comma-separated list (no spaces) of tissue names
    -histone-root <hrd>             histone root directory
    -histone-names <hnames>         comma-separated list (no spaces) of histone names
    -max-link-distances <mlds>      comma-separated list of maximum distances between an RE and its target
    -expression-root <erd>          expression root directory
    -expression-file-type <eft>     file type of expression files
    -annotation-file-name <afile>   annotation file name
    -annotation-type <atype>        type of annotation [Gencode|RefSeq]
    -transcript-types <ttypes>      types of transcript to use from annotation file
    -min-feature-count <mfc>        only consider links where there is both histone and
				    expression data for at least this many tissues: default: 7
    -min-max-expression <mme>       maximum expression of a target must be at least <mme> for
				    the target to be included in the map; default: 2
    -max-html-score <mhs>           only include links with this score or better in the HTML
    
    Files present in the server cismapper databases can be specified by appending 'db/'
    to the file name.
=cut

use strict;
use warnings;
# load standard perl libraries
use Cwd;
use Getopt::Long qw(:config permute auto_help);
use Pod::Usage;
# load custom perl libraries
use lib qw(@PERLLIBDIR@);
use StatusPage qw(arg_checks opt_uploaded opt_safe opt_integer opt_evalue);
use MemeWebUtils qw(dir_listing_set dir_listing added_files create_tar);

# constants
my $bin_dir = '@BINDIR@';
my $libexec_dir = '@LIBEXECDIR@';
my $cismapper_db_dir = '@MEMEDB@/cismapper_databases';
my $workdir = &getcwd();

# required parameters
my $locus_file;
my $rna_source;

# options
my ($tissues, $histone_root, $histone_names, $max_link_distances, $expression_root, 
  $expression_file_type, $expression_file_name, $annotation_file_name, $annotation_type,
  $transcript_types, $min_feature_count, $min_max_expression, $max_html_score, $nostatus, $noecho);

#status page
my $status = new StatusPage('CISMAPPER', \@ARGV);
$status->add_message('Parsing arguments');
my @arg_errors = ();
my $program = 'CisMapper';
my $page = 'index.html';
my $refresh = 10;

# parse options
my $opts_ok = do {
  local $SIG{__WARN__} = sub { my ($msg) = @_; chomp($msg); push(@arg_errors, $msg); };
  GetOptions(
    '<>' => arg_checks(opt_uploaded(\$locus_file), opt_safe(\$rna_source)),
    'tissues=s' => \$tissues,
    'histone-root=s' => \$histone_root,
    'histone-names=s' => \$histone_names,
    'max-link-distances=s' => \$max_link_distances,
    'expression-root=s' => \$expression_root,
    'expression-file-type=s' => \$expression_file_type,
    'expression-file-name=s' => \$expression_file_name,
    'annotation-file-name=s' => \$annotation_file_name,
    'annotation-type=s' => \$annotation_type,
    'transcript-types=s' => \$transcript_types,
    'min-feature-count=i' => opt_integer(\$min_feature_count),
    'min-max-expression=i' => opt_integer(\$min_max_expression),
    'max-html-score=f' => opt_evalue(\$max_html_score),
    'nostatus' => \$nostatus,
    'noecho' => \$noecho
  );
};
# add additional error messages for missing sequences and motifs
push(@arg_errors, "No locus file provided.") unless defined $locus_file;
push(@arg_errors, "No RNA source type provided.") unless $rna_source;
$opts_ok = 0 if (scalar(@arg_errors) > 0);

# 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);
}

# setup status page
$status->add_file('html', 'cismapper.html', 'CisMapper HTML output');
$status->add_file('gene_targets', 'gene_targets.tsv', 'Gene Targets in TSV format');
$status->add_file('gene_elements', 'gene_elements.tsv', 'Gene Elements in TSV format');
$status->add_file('tss_targets', 'tss_targets.tsv', 'TSS Targets in TSV format');
$status->add_file('tss_elements', 'tss_elements.tsv', 'TSS Elements in TSV format');
$status->add_file('links', 'links.tsv', 'Links in TSV format');
$status->add_file('tracks', 'tracks.bed', 'Browser Tracks in BED format');
$status->add_file('loci', $locus_file, 'Uploaded Loci');
# Add the histone and expression files
$status->add_file('expression', 'TrEx.tsv', 'Expression level across panel in TSV format');
foreach my $histone (split(/,/, $histone_names)) {
  $status->add_file("histone_$histone", "HistLev.$histone.tsv", "Histone $histone level across panel in TSV format");
}
$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($cismapper_db_dir, 'db');
# ensure it will be removed on completion (when the log is written)
$status->set_cleanup( sub { unlink('db'); } );

# take a listing of all the files in the current directory
my $before = &dir_listing_set($workdir);

# Run cismapper
my @cismapper_args = ('-oc', '.');
push(@cismapper_args, '-tissues', $tissues) if (defined($tissues));
push(@cismapper_args, '-histone-root', $histone_root) if (defined($histone_root));
push(@cismapper_args, '-histone-names', $histone_names) if (defined($histone_names));
push(@cismapper_args, '-max-link-distances', $max_link_distances) if (defined($max_link_distances));
push(@cismapper_args, '-expression-root', $expression_root) if (defined($expression_root));
push(@cismapper_args, '-expression-file-type', $expression_file_type) if (defined($expression_file_type));
push(@cismapper_args, '-expression-file-name', $expression_file_name) if (defined($expression_file_name));
push(@cismapper_args, '-annotation-file-name', $annotation_file_name) if (defined($annotation_file_name));
push(@cismapper_args, '-annotation-type', $annotation_type) if (defined($annotation_type));
push(@cismapper_args, '-transcript-types', $transcript_types) if (defined($transcript_types));
push(@cismapper_args, '-min-feature-count', $min_feature_count) if (defined($min_feature_count));
push(@cismapper_args, '-min-max-expression', $min_max_expression) if (defined($min_max_expression));
push(@cismapper_args, '-max-html-score', $max_html_score) if (defined($max_html_score));
push(@cismapper_args, '-fdesc', 'description') if (-e 'description');
push(@cismapper_args, '-nostatus') if (defined($nostatus));
push(@cismapper_args, '-noecho') if (defined($noecho));
push(@cismapper_args, '-remove-map');
push(@cismapper_args, $locus_file, $rna_source);

$status->run(PROG => 'cismapper', BIN => $libexec_dir, ARGS => \@cismapper_args);

# determine all files added
my @tar_files = &added_files($before, &dir_listing_set($workdir));
# read inputs
push(@tar_files, $locus_file);
# create tar with all new files plus the input files
my $tar = &create_tar(0, "", "", "", "", "", @tar_files);
$status->add_file('tgz', $tar, 'Gzipped Tar file of all output');

# done
$status->add_message("Done");
$status->update();
$status->write_log();
1;
