#!/usr/bin/env python3

"""
This housekeeping script reads a GFF3 file and writes a new one, excluding any features
which appear to be duplicated based on their type and location.

The initial use-case here was a GFF file generated by WebApollo which had duplicate exon
features with different IDs but the same coordinates and parentage.

A row is considered a removable duplicate if:
  - It shares the same location as another feature of the same type
  - It shared the same parent feature

Why the parent restriction?  If this wasn't included, two different isoforms at the same
location which had shared exons could lose them (for example.)

Author: Joshua Orvis
"""

import argparse

from biocode import gff


def main():
    parser = argparse.ArgumentParser( description='Removes duplicate features in a GFF3 file')

    ## output file to be written
    parser.add_argument('-i', '--input', type=str, required=True, help='Path to the input GFF3 file' )
    parser.add_argument('-o', '--output', type=str, required=True, help='Output GFF3 file to write' )
    args = parser.parse_args()

    # just reduce the keys to a string:
    # "molecule__parent__type__start__stop"
    found = list()

    infile  = open(args.input)
    outfile = open(args.output, 'wt')
    
    for line in infile:
        if line.startswith('#'):
            outfile.write(line)
            continue
        
        line = line.rstrip()
        cols = line.split("\t")

        if len(cols) != 9:
            continue

        parent = gff.column_9_value(cols[8], 'Parent')
        type   = cols[2]
        mol_id = cols[0]

        if parent is None:
            outfile.write("{0}\n".format(line))
            continue

        id_string = "{0}__{1}__{2}__{3}__{4}".format(mol_id, parent, type, cols[3], cols[4])

        if id_string in found:
            print("INFO: duplicate feature to be removed:\n{0}\n".format(line) )
            continue
        else:
            found.append(id_string)
            outfile.write("{0}\n".format(line) )
            
            
            

        

if __name__ == '__main__':
    main()







