#!/Users/runner/bioconda/conda-bld/maker_1616698748543/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_place/bin/perl 

eval 'exec /Users/runner/bioconda/conda-bld/maker_1616698748543/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_place/bin/perl  -S $0 ${1+"$@"}'
    if 0; # not running under some shell

use warnings;
use strict;
use Getopt::Long;
use File::Temp qw(tempfile);
use URI::Escape;

my $usage = "

Synopsis:

gff3_merge -d maker_datastore_index.log
gff3_merge -o genome.all.gff <gff3_file1> <gff3_file2> ...

Descriptions:

This script will take a MAKER datastore index log file, extract all
the relevant GFF3 files and combined GFF3 file.  The script can also
combine other correctly formated GFF3 files.  For this to work
properly you need to be in the same directory as the datastore index.

Options:

  -d The location of the MAKER datastore index log file.
  -o Alternate base name for the output files.
  -s Use STDOUT for output.
  -g Only write MAKER gene models to the file, and ignore evidence.
  -n Do not print fasta sequence in footer
  -l Merge legacy annotation sets (ignores already having seen
     features more than once for the same contig)
";

my $datastore;
my @files;
my $outfile;
my $g_flag;
my $l_flag;
my $s_flag;
my $n_flag;
my $b_flag;

GetOptions ("datastor|d=s" => \$datastore,
	    "o=s" => \$outfile,
	    "g" => \$g_flag,
	    "l" => \$l_flag,
	    "s" => \$s_flag,
	    "n" => \$n_flag,
	    "break|b=s" => \$b_flag,
	    "help|?" => sub{print $usage; exit();}
	    );

if(! $datastore){
    @files = @ARGV;
}

if(! $datastore && ! @files) {
    print $usage;
    exit();
}

if (! $outfile && $datastore){
    ($outfile) = $datastore =~ /([^\/]+)$/;
    $outfile =~ s/_master_datastore_index.log//;
    $outfile .= ".all.gff";
}
$outfile = "genome.all.gff" if(! $outfile);

die "ERROR: The file \'$datastore\' does not exist\n" if ($datastore && ! -f $datastore);
if ($datastore){
    open(IN, "< $datastore");

    #uniq the entries
    my %seen;
    while(my $e = <IN>){
	next unless ($e =~ /FINISHED/);
	next if $seen{$e};
	$seen{$e}++;
	chomp $e;
	my ($id, $dir, $status) = split("\t", $e);
	$dir =~ s/\/$//;
	push(@files, $dir);
    }

    foreach my $file (@files){
	$file =~ /([^\/]+)$/;
	$file = "$file/".uri_escape($1, '\*\?\|\\\/\'\"\{\}\<\>\;\,\^\(\)\$\~\:\.').".gff";
    }
}

@files = sort @files;

my $GFF;
if($s_flag){
    open ($GFF, ">&STDOUT")
}
else{
    open($GFF, "> $outfile");
}

print $GFF "\#\#gff-version 3\n";

my ($ANN, $ann_file) = tempfile();
my ($FAS, $fas_file) = tempfile() unless($n_flag);

unless($n_flag){
    print $FAS "\#\#FASTA\n" || die "ERROR: $!";
}

my $i = 0;
my %uniq;
my $last;
foreach  my $file (@files){
    my $file = $files[$i];
    #fix for not being in working directory with datastore
    if (! -f $file){
	my $dir = $datastore;
	$dir =~ s/[^\/]+$/\./;
	$file = "$dir/$file";
    }

    die "ERROR: The file \'$file\' does not exist\n" if (! -f $file);
    open(IN, "< $file") || die "ERROR: Could not open file \'$file\'\n";

    my $seen_flag; #keep seen fasta sequnce from being printed twice
    my $FH = $ANN;
    while (defined(my $line = <IN>)){
	if($last && $line =~ /^\#\#\#/ && $last =~ /^\#\#\#/){
	    next;
	}

	if ($line =~ /^\#\#gff-version 3/){
	    next;
	}
	elsif($line =~ /^\#\#genome-build/){
	    next if exists $uniq{$line};
	    $uniq{$line}++;
	    #print $GFF $line; #don't print this anymore
	    next;
	}
	elsif($line =~ /^\#\#sequence-region\s+(^[\s]+)/){
	    if(exists $uniq{$line}){
		die "ERROR: This contig has already been added\: $line\n"
		    if (! $l_flag);
		$seen_flag = 1;
	    } 
	    $uniq{$line}++;
	    print $GFF $line || die "ERROR: $!";
	    $last = $line;
	    next;
	}
	elsif($line =~ /^\#\#FASTA/){
	    last if($seen_flag || $n_flag);
	    $FH = $FAS;
	    next;
	}
	elsif($line =~ /^>/){
	    last if($n_flag);
	    $FH = $FAS;
	}
	elsif($line =~ /^[^\s\t\#\>\n]+\t([^\t]+)\t/){
	    $FH = $ANN;
	    if($l_flag){
		$line =~ s/ID=/ID=$i:/;
		if($line =~ /Parent=([^\;\n]+)/){
		    my @p = map {"$i:$_"} split(/\,/, $1);
		    my $n = join(',', @p);
		    $line =~ s/Parent=[^\;\n]+/Parent=$n/;
		}
	    }
	    next if($g_flag && $1 ne 'maker');
	}

	chomp $line;
	if($line){
	    print $FH $line."\n" || die "ERROR: $!";
	    $last = $line;
	}
    }

    $i++; #for unique identifier
}
close($GFF);
close($ANN);
close($FAS) unless($n_flag);
if($s_flag){
    print `cat $ann_file`;
    print `cat $fas_file` unless($n_flag);
}
else{
    system ("cat $ann_file >> $outfile") && die "ERROR: $!";
    unless($n_flag){
	system ("cat $fas_file >> $outfile") && die "ERROR: $!";
    }
}

unlink("$ann_file");
unlink("$fas_file") unless($n_flag);
