#!/bin/env perl

use strict;
use warnings;
use Bio::SeqIO;
use FindBin;
use File::Spec;

## usage:
##     perl terp_predicat.pl query.faa > prediction.tsv

print join("\t", 'Query_ID', 'prediCAT_Call', 'Forced_prediCAT_Call', 'prediCAT_NN_Dist', 'prediCAT_NN_Score', 'prediCAT_SNN_Score', 'prediCAT_Top_Hit_Description', 'prediCAT_Top_Hit_Organism', 'prediCAT_Top_Hit_Topology', 'prediCAT_Top_Hit_Accession')."\n";

## Get annotations list
my %ann = ();
open my $afh, '<', File::Spec->catfile($FindBin::Bin, 'terpene_synthase_annotations.txt') or die $!;
while(<$afh>){
    next if($_ =~ m/^Description/);
    chomp;
    my ($desc, $mtype, $fullname, $org, $top) = split(/\t/, $_);
    $top =~ s/\s+/-/g;
    $top =~ s/-$//;
    my ($name, @rest) = split(/\s+/, $fullname);
    my $uname = $name;
    $name =~ s/_/-/g;
    $ann{$name} = {
	'desc' => $desc,
	'org' => $org,
	'top' => $top,
	'uname' => $uname
    };
}
close $afh;
$ann{'no_confident_result'} = {
    'desc' => 'NA',
    'org' => 'NA',
    'top' => 'NA',
    'uname' => 'NA'
};

my $wildcard = 'UNK';

my $query = shift; ## FAA
my @dir = split(/\//, $query);
my $trainfaa = File::Spec->catfile($FindBin::Bin, 'allterp.faa');
my $fa = new Bio::SeqIO(-file=> $query, -format=> 'fasta');
while(my $seq = $fa->next_seq){
    open my $tf, '>', 'tmpt.fa' or die $!;
    print $tf '>' . $seq->id . '_' . $wildcard . "\n" . $seq->seq . "\n";
    close $tf;
    my ($at, $atname, $atf, $nndist, $nnscore, $snnscore) = treescanner($trainfaa, 'tmpt.fa', $wildcard);
    print join("\t", $seq->id, $at, $atf, $nndist, $nnscore, $snnscore, $ann{$atname}{'desc'}, $ann{$atname}{'org'}, $ann{$atname}{'top'}, $ann{$atname}{'uname'}) . "\n";
    system("rm tmp*");
}

sub treescanner{
	my ($basefaa, $q, $wc) = @_;
	my $pl = File::Spec->catfile($FindBin::Bin, 'treeparserscore.pl');
	## Grab first seq
	my $bfa = new Bio::SeqIO(-file=>$basefaa, -format=>'fasta');
	my $seq = $bfa->next_seq;
	open my $ttf, '>', 'tmp.trim.faa' or die $!;
	print $ttf '>' . $seq->id . "\n" . $seq->seq . "\n";
	close $ttf;
	system("cat $q >> tmp.trim.faa");
	## Align query to first seq
	system("mafft --quiet --namelength 100 --op 5 tmp.trim.faa > tmp.trim.afa");
	## Trim query
	my $pfa = new Bio::SeqIO(-format=>'fasta', -file=>'tmp.trim.afa');
	my ($head, $tail) = (undef, undef);
	my ($id, $s) = (undef, undef);
	while(my $qseq = $pfa->next_seq){
		if($qseq->id =~ m/$wc/){
			($id, $s) = ($qseq->id, $qseq->seq);
		}else{
			($head, $tail) = ($qseq->seq, $qseq->seq);
			if($head =~ m/^-/){
				$head =~ s/^(-+).+/$1/;
			}else{
				$head = '';
			}
			if($tail =~ m/-$/){
				$tail =~ s/\w(-+)$/$1/;
			}else{
				$tail = '';
			}
		}
	}
	$head = length($head);
	$tail = length($tail);
	substr($s, -1, $tail) = '';
	substr($s, 0, $head) = '';
	$s =~ s/-//g;
	## Compile all seqs
	open my $newfaa, '>', 'tmp.tree.faa' or die $!;
	print $newfaa '>' . $id . "\n" . $s . "\n";
	close $newfaa;
	system("cat $basefaa >> tmp.tree.faa");
	system("perl -pi -e 's/[\(\)]/-/g' tmp.tree.faa");
	## Align all seqs, make tree
	#system("mafft --clustalout --quiet --namelength 60 tmp.tree.faa > tmp.tree.aln");
	system("mafft --quiet --namelength 100 tmp.tree.faa > tmp.tree.aln");
	#system("clustalw -TREE -INFILE=tmp.tree.aln -QUIET 1> /dev/null");
	system("fasttree -quiet < tmp.tree.aln > tmp.tree.ph 2>/dev/null");
	## Make calls
	chomp(my $cwd = `pwd -P`);
	system("perl $pl $cwd/tmp.tree.ph > tmp.tp.tsv");
	## Parse calls
	open my $tp, '<', 'tmp.tp.tsv' or die $!;
	while(<$tp>){
		chomp;
		my ($i, $c, $atn, $fc, $nn, $nnsc, $snnsc) = split(/\t/, $_);
		if(defined $c && defined $fc){
			close $tp;
			return ($c, $atn, $fc, $nn, $nnsc, $snnsc);
		}
	}
	close $tp;
	
}
