#!/usr/bin/env python

import os
import re
import sys
import argparse
from Bio import SeqIO


def parse_gff(gff_file, min_len):
    '''
    extract pep id under the requirement of the minimal contig length cutoff from the GFF file generated by prodigal 
    '''
    save = False
    min_len = int(min_len)
    pep_id_list = []
    with open(gff_file, "r") as ih:
        for line in ih:
            seq_len = 0

            if line.startswith("##") or line.startswith("# Model Data") or line.strip() == '"':
                continue

            elif line.startswith("# Sequence Data"):
                line_split = line.strip().split(";")
                for token in line_split:
                    if "seqlen=" in token:
                        seq_len = int(token[token.find("=") + 1:])
                if seq_len < min_len:
                    save = False 
                else:
                    save = True
            elif save:
                line_split = re.split("\s+", line.strip())
                seq_id = line_split[0]
                trans_id = line_split[-1].split(";")[0].split("_")[-1]
                pep_id = f'''{seq_id}_{trans_id}'''
                pep_id_list.append(pep_id)
            else:
                continue
    return pep_id_list


def extract_faa(faa_file, pep_id_list, out_file, assembly_group=None):
    if os.path.dirname(out_file) != "":
        os.makedirs(os.path.dirname(out_file), exist_ok=True)

    with open(out_file, "w") as oh:
        for seq in SeqIO.parse(faa_file, "fasta"):
            if seq.id in pep_id_list:
                if assembly_group is not None:
                    seq.id = f'''{assembly_group}C{seq.id}'''
                    seq.name = f'''{assembly_group}C{seq.name}'''
                    seq.description = f'''{assembly_group}C{seq.description}'''
                SeqIO.write(seq, oh, "fasta")


def main():
    parser = argparse.ArgumentParser("PEP extractor")
    parser.add_argument("--faa-file", dest="faa_file", type=str, required=True, help="protein file")
    parser.add_argument("--gff-file", dest="gff_file", type=str, required=True, help="gff file")
    parser.add_argument("--min-contig", dest="min_contig", default=2000, type=int, help="minimal contig length, default: 2000")
    parser.add_argument("--out-file", dest="out_file", type=str, required=True, help="output protein file")
    args = parser.parse_args()

    pep_id_list = parse_gff(args.gff_file, args.min_contig)
    if len(pep_id_list) > 0:
        extract_faa(args.faa_file, pep_id_list, args.out_file)
    else:
        sys.exit("Emplty protein file after contigs length control")


if __name__ == '__main__':
    main()