""" Brute force caller for noncanonical peptides of noncoding gene """
import argparse
import re
from typing import List
from pathlib import Path
import pickle
import sys
from moPepGen import aa, gtf, dna
from moPepGen.aa.AminoAcidSeqRecord import AminoAcidSeqRecord
from moPepGen.cli import common


# pylint: disable=W0212
def parse_args(subparsers:argparse._SubParsersAction):
    """ parse command line arguments """
    parser:argparse.ArgumentParser = subparsers.add_parser(
        name='bruteForceNovelORF',
        help='Call noncanonical peptides from noncoding gnees with the brute'
        'force algorithm'
    )
    parser.add_argument(
        '-t', '--tx-id',
        type=str,
        help='Transcript ID'
    )
    parser.add_argument(
        '-r', '--reference-dir',
        type=Path,
        help='Reference directory. Must contain genome.fa, annotation.gtf, and'
        ' proteome.fasta. The directory should be generated by'
        ' the downsampleReference command'
    )
    parser.add_argument(
        '--canonical-peptides',
        type=Path,
        help='Path to the pickled canonical peptide sequence.',
        default=None
    )
    common.add_args_cleavage(parser)
    common.add_args_debug_level(parser)
    parser.set_defaults(func=main)
    common.print_help_if_missing_args(parser)
    return parser

def main(args:argparse.Namespace):
    """ main entrance """
    anno = gtf.GenomicAnnotation()
    anno.dump_gtf(args.reference_dir/'annotation.gtf')

    genome = dna.DNASeqDict()
    genome.dump_fasta(args.reference_dir/'genome.fasta')

    proteome = aa.AminoAcidSeqDict()
    proteome.dump_fasta(args.reference_dir/'proteome.fasta')

    rule = args.cleavage_rule
    exception = args.cleavage_exception

    if args.canonical_peptides:
        with open(args.canonical_peptides, 'rb') as handle:
            canonical_pool = pickle.load(handle)
    else:
        canonical_pool = None

    tx_id = args.tx_id
    tx_model = anno.transcripts[tx_id]
    tx_seq = tx_model.get_transcript_sequence(genome[tx_model.transcript.chrom])

    noncanonical_peptides = set()

    three_frame_translates:List[AminoAcidSeqRecord] = []
    for i in range(3):
        j = len(tx_seq.seq) - (len(tx_seq.seq) - i) % 3
        three_frame_translates.append(tx_seq[i:j].translate(to_stop=False))

    for frame_seq in three_frame_translates:
        for it in re.finditer('M', str(frame_seq.seq)):
            i = it.start()
            j = frame_seq.seq[i:].find('*')
            if j == -1:
                j = len(frame_seq.seq)
            else:
                j += i
            aa_seq = frame_seq[i:j]
            peptides = aa_seq.enzymatic_cleave(rule, exception)
            for peptide in peptides:
                if peptide is peptides[0] and peptide.seq.startswith('M'):
                    seq = str(peptide.seq[1:])
                    if canonical_pool and seq not in canonical_pool:
                        noncanonical_peptides.add(seq)
                seq = str(peptide.seq)
                if not canonical_pool or seq not in canonical_pool:
                    noncanonical_peptides.add(str(peptide.seq))

    noncanonical_peptides = sorted(noncanonical_peptides)
    for peptide in noncanonical_peptides:
        print(peptide, file=sys.stdout)
