# Giant Virus Finder, a software package to find giant viruses in metagenomes.
# Copyright (C) 2015, Csaba Kerepesi

# This file is part of Giant Virus Finder.

# Giant Virus Finder is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details: <http://www.gnu.org/licenses/>.

# For any other inquiries send an Email to Csaba Kerepesi: kerepesi@caesar.elte.hu
# Giant Virus Finder website: http://pitgroup.org/giant-virus-finder

# $ARGV[0]: genbank search output
# $ARGV[1]: cutoff genome size
# Output files: 
#  AllVirusGenomeFile.csv
#  TopGiants-300000-allacc.csv
#  TopGiants-300000.csv: sorted list with only the NC if exists, and only one NC if there are multiple segments
#  TopGiants-300000.html: sorted html list with only the NC if exists, and only one NC if there are multiple segments
# Run: perl TopGiants.pl TopGiants-gb-300k/TopGiants-gb-300k.csv 300000

my $bps=0; my $filename=""; my %sum_len=(); my %desc=(); my %line_to_name=(); my %length=();  my %length2=();  my %length3=();
my %segments=(); my @list=(); my @out1=(); my @out2=(); my @out3=(); my $first=1; my %acc=(); my %title=();

system('find AllVirusGenome -type f | grep ".fna" > AllVirusGenomeFile.csv');
print "AllVirusGenomeFile.csv\n";
open IN0,"AllVirusGenomeFile.csv";
while (<IN0>) {
    chop;
    $filename=$_;
    @list=split(/\//);
    open IN,$filename;
    $first=1;
    while (<IN>) {
        chomp;
        if ($first==1) {
            if (!exists $desc{$list[1]}) {
                $segments{$list[1]}=1;
            }else {
                $segments{$list[1]}+=1;
            }
            $desc{$list[1]}=$_;
            my @split_line=split(/\|/,$_);
            $NC_filename{$list[1]}{$split_line[3]}=$_;
            $first=0;
        }else {
            $bps += length($_);
        }
    }
    close IN;
    $sum_len{$list[1]}+=$bps;
    $bps=0;
}
close IN0;
foreach my $name (keys %sum_len) {
    my @split_line=split(/\|/,$desc{$name});
    if ($split_line[4] =~ /^\s(.+)/) {
        $split_line[4]=$1;
    }
    my $out="$split_line[3]|$split_line[4]|$sum_len{$name}|$segments{$name}\n";
    if ($sum_len{$name}>= $ARGV[1]) {
        $uid{$split_line[3]}=$name;
        push @out1,$out;
    }
}
open IN,"$ARGV[0]";
while (<IN>) {
    chomp;
    my @split_line=split(/\|/, $_);
    my $out="$split_line[0]|$split_line[1]|$split_line[2]|1\n";
    push @out1,$out;
}
close IN;
foreach my $line (@out1) {
    my @split_line=split( /\|/,$line);
    if (!exists $acc{$split_line[0]}) {
        $acc{$split_line[0]}=1;
        push @out2,$line;
    }
}
&out_allacc;
foreach my $line (@out2) {
    my @split_line=split(/\|/,$line);
    if (!exists $line_to_name{$split_line[1]}) {
        $line_to_name{$split_line[1]}=$line;
    }elsif ($split_line[0] =~ /NC/) {
        $line_to_name{$split_line[1]}=$line;
    }
}
foreach my $key (keys %line_to_name) {
    push @out4, $line_to_name{$key};
}
@out2=@out4;
&out_csv;
&out_html;

#########################

sub out_allacc {
open OUT,'>',"TopGiants-$ARGV[1]-allacc.csv";
print "TopGiants-$ARGV[1]-allacc.csv\n";
foreach my $line (@out2){
    my @split_line=split(/\|/,$line);
    if ($split_line[3]>1) {
        #print OUT "--$uid{$split_line[0]}\n";
        foreach my $key (keys %{$NC_filename{$uid{$split_line[0]}}}) {
            #print OUT "$NC_filename{$uid{$split_line[0]}}{$key}\n"
            print OUT "$key\n"
        }
    }else {
        print OUT "$split_line[0]\n";
        #print OUT $line;
    }
}
close OUT;
}

sub out_allacc_old {
foreach my $line (@out2) {
    chomp $line;
    my @split_line=split(/\|/,$line);
    $length3{$line}=$split_line[2];
}
open OUT,'>',"TopGiants-$ARGV[1]-allacc.csv";
print "TopGiants-$ARGV[1]-allacc.csv\n";
foreach my $key (sort { $length3{$b} <=> $length3{$a} } keys %length3) {
    my @split_line=split(/\|/,$key);
    print OUT "$key\n";
}
close OUT;
}


sub out_csv {
foreach my $line (@out2) {
    chomp $line;
    my @split_line=split(/\|/,$line);
    $line="$split_line[1]|$split_line[2]|$split_line[3]|$split_line[0]\n";
    $length2{$line}=$split_line[2];
    $title2{$line}=$split_line[1];
    $segm2{$line}=$split_line[3];
    $acc2{$line}=$split_line[0];
}
open OUT,'>',"TopGiants-$ARGV[1].csv";
open OUT,'>',"TopGiants-$ARGV[1].csv";
print "TopGiants-$ARGV[1].csv\n";
foreach my $key (sort { $length2{$b} <=> $length2{$a} } keys %length2) {
    if (exists $uid{$acc2{$key}}) {
        print OUT "$uid{$acc2{$key}}\|$key";
    } else {   
        print OUT $key;
    }
}
close OUT;
}


sub out_html {
open OUT,'>',"TopGiants-$ARGV[1].html";
print "TopGiants-$ARGV[1].html\n";
print OUT q~
<h2>The largest virus genomes and sequences (> 300k bps):</h2>
Generated: June 11, 2018. <a href="#details">Details are below.</a>

<br><br>

<style type="text/css">
.tg  {border-collapse:collapse;border-spacing:0;border-color:#ccc;}
.tg td{font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;background-color:#fff;}
.tg th{font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;background-color:#f0f0f0;}
.tg .tg-hgcj{font-weight:bold;text-align:center}
.tg .tg-e3zv{font-weight:bold}
.tg .tg-s6z2{text-align:center}
</style>
<table class="tg">
  <tr>
    <th class="tg-hgcj"></th>
    <th class="tg-e3zv">Sequence title</th>
    <th class="tg-hgcj">Length</th>
    <th class="tg-hgcj">Segm.</th>
    <th class="tg-hgcj">Accession</th>
  </tr>
~;

my $row=0;
foreach my $key (sort { $length2{$b} <=> $length2{$a} } keys %length2) {
    $row++;
    print OUT qq~
  <tr>
    <td class="tg-s6z2">$row</td>
    <td class="tg-031e">$title2{$key}</td>
    <td class="tg-s6z2">$length2{$key}</td>
    <td class="tg-s6z2">$segm2{$key}</td>
    <td class="tg-s6z2">$acc2{$key}</td>
  </tr>
~;
}

print OUT q~
</table>

<a name="details"></a>
<ul>
<li><strong>How the toplist were made:</strong> The Giant Virus Toplist was made by the <a href="http://pitgroup.org/giant-virus-finder/">Giant Virus Finder</a> software. 
Reference genome data were downloaded from the <a href="ftp://ftp.ncbi.nlm.nih.gov/genomes/Viruses/all.fna.tar.gz">NCBI Genome FTP</a>. 
Note that the lengths of distinct genome sequences (segments) of a particular complete genome were summarized. 
Other (not complete) genomic sequences were added from the <a href="http://www.ncbi.nlm.nih.gov/nuccore/">NCBI Nucleotide database</a> using the search term: "Viruses"[Organism] AND 300000:10000000[Sequence Length] NOT "Bacteria"[Organism] NOT "Archaea"[Organism].</li>
<li><strong>Sequence title:</strong> Original sequence title retrieved from Genbank. If there were more than one sequence we choosed one.</li>
    <li><strong>Length:</strong> Sequence length. Length of the segments were summarized.</li> 
    <li><strong>Segm.:</strong> Segments. The number of genome sequences (segments) belonged to a particular complete genome</li>
    <li><strong>Accession: </strong>If a reference sequence (NC_) existed then the identical non-reference sequences were ignored from the toplist.
    All accessions (including accessions of every segment files, and also the redundants) are available here: <a href="http://pitgroup.org/public/giant-virus-finder/TopGiants-300000-allacc.csv">TopGiants-300000-allacc.csv</a>.</li>    
</ul>

~;
 
close OUT;
}
