# Path: SDDetector/Entities/Alignment.py
# class Alignment(object):
# 
#     __slots__ = ['query','sbjct','qstart','qend','sstart','send',
#                  'length', 'identities', 'qstrand', 'sstrand','id']
# 
#     def __init__(self, query, sbjct, qstart, qend, sstart, send, length, identities, qstrand, sstrand, id=''):
#         """Alignment constructor"""
# 
#         self.query = query
#         self.sbjct = sbjct
#         self.qstart = qstart
#         self.qend = qend
#         self.sstart = sstart
#         self.send = send
#         self.length = length
#         self.identities = identities
#         self.qstrand = qstrand
#         self.sstrand = sstrand
#         self.id = id
# 
#     def __eq__(self, other):
#         """Equality on all args"""
#       
#         return (self.query,self.sbjct,self.qstart,self.qend,self.sstart,self.send,self.length,self.identities,self.qstrand,self.sstrand, self.id) == (other.query,other.sbjct,other.qstart,other.qend,other.sstart,other.send,other.length,other.identities,other.qstrand,other.sstrand, other.id)
# 
#     def __repr__(self):
#         """representation"""
# 
#         return ('{}-{}-{}-{}-{}-{}-{}-{}-{}-{}-{}'.format(self.query,self.sbjct,self.qstart,self.qend,self.sstart,self.send,self.length,self.identities,self.qstrand,self.sstrand, self.id))
# 
#     def convertToGff3(self):
#         """Write alignment in gff3 format"""
# 
#         if self.sstrand == 1:
#             strand = '+'
#         else:
#             strand = '-'
# 
#         gff3line = '{}\tSQLiteDB\tmatch\t{}\t{}\t.\t{}\t.\tID=match{};Target={} {} {}\n'.format(self.sbjct,self.sstart,self.send,strand,self.id,self.query,self.qstart,self.qend)
#         return gff3line


import logging
import sys
from Bio.Blast import NCBIXML
from SDDetector.Entities.Alignment import Alignment

class BlastXMLParser(object):

    def __init__(self, inputBlastXMLFile=""):
        """Constructor"""
        self.inputBlastXMLFile = inputBlastXMLFile

    def getAllAlignments(self):
        """Return list of all Alignments"""

        lAlignments = []
        with open(self.inputBlastXMLFile,  'r') as input :

            blast_records = NCBIXML.parse(input)
            index = 0

            for blast_record in blast_records:
                logging.debug('QUERY: {}'.format(blast_record.query))

                for alignment in blast_record.alignments:
                    logging.debug('SUBJECT: {}'.format(alignment.hit_id))
                    nb_hsp = 0
                    for hsp in alignment.hsps:
                        nb_hsp += 1
                        index += 1
                        if hsp.frame[1] == 1:
                            lAlignments.append(Alignment(blast_record.query, alignment.hit_id,
                                               hsp.query_start, hsp.query_end, hsp.sbjct_start,
                                               hsp.sbjct_end, hsp.align_length, hsp.identities, hsp.frame[0], hsp.frame[1], id=index))
                        elif hsp.frame[1] == -1:

# Path: SDDetector/Entities/Alignment.py
# class Alignment(object):
# 
#     __slots__ = ['query','sbjct','qstart','qend','sstart','send',
#                  'length', 'identities', 'qstrand', 'sstrand','id']
# 
#     def __init__(self, query, sbjct, qstart, qend, sstart, send, length, identities, qstrand, sstrand, id=''):
#         """Alignment constructor"""
# 
#         self.query = query
#         self.sbjct = sbjct
#         self.qstart = qstart
#         self.qend = qend
#         self.sstart = sstart
#         self.send = send
#         self.length = length
#         self.identities = identities
#         self.qstrand = qstrand
#         self.sstrand = sstrand
#         self.id = id
# 
#     def __eq__(self, other):
#         """Equality on all args"""
#       
#         return (self.query,self.sbjct,self.qstart,self.qend,self.sstart,self.send,self.length,self.identities,self.qstrand,self.sstrand, self.id) == (other.query,other.sbjct,other.qstart,other.qend,other.sstart,other.send,other.length,other.identities,other.qstrand,other.sstrand, other.id)
# 
#     def __repr__(self):
#         """representation"""
# 
#         return ('{}-{}-{}-{}-{}-{}-{}-{}-{}-{}-{}'.format(self.query,self.sbjct,self.qstart,self.qend,self.sstart,self.send,self.length,self.identities,self.qstrand,self.sstrand, self.id))
# 
#     def convertToGff3(self):
#         """Write alignment in gff3 format"""
# 
#         if self.sstrand == 1:
#             strand = '+'
#         else:
#             strand = '-'
# 
#         gff3line = '{}\tSQLiteDB\tmatch\t{}\t{}\t.\t{}\t.\tID=match{};Target={} {} {}\n'.format(self.sbjct,self.sstart,self.send,strand,self.id,self.query,self.qstart,self.qend)
#         return gff3line


# Path: SDDetector/Parser/Blast/BlastXMLParser.py
import logging
import sys
from Bio.Blast import NCBIXML
from SDDetector.Entities.Alignment import Alignment


class BlastXMLParser(object):

    def __init__(self, inputBlastXMLFile=""):
        """Constructor"""
        self.inputBlastXMLFile = inputBlastXMLFile

    def getAllAlignments(self):
        """Return list of all Alignments"""

        lAlignments = []
        with open(self.inputBlastXMLFile,  'r') as input :

            blast_records = NCBIXML.parse(input)
            index = 0

            for blast_record in blast_records:
                logging.debug('QUERY: {}'.format(blast_record.query))

                for alignment in blast_record.alignments:
                    logging.debug('SUBJECT: {}'.format(alignment.hit_id))
                    nb_hsp = 0
                    for hsp in alignment.hsps:
                        nb_hsp += 1
                        index += 1
                        if hsp.frame[1] == 1:
                            lAlignments.append(Alignment(blast_record.query, alignment.hit_id,
                                               hsp.query_start, hsp.query_end, hsp.sbjct_start,
                                               hsp.sbjct_end, hsp.align_length, hsp.identities, hsp.frame[0], hsp.frame[1], id=index))
                        elif hsp.frame[1] == -1:

                            lAlignments.append(Alignment(blast_record.query, alignment.hit_id,