from utils.fasta_handling import get_sequences_from_fasta
from utils.protein_group_sql_db import ProteinGroupSqlDbInteractor


rule map_to_seq:
  input:
    pg_db = 'pgs/protein_groups_db.sql',
    user_fastas = expand('{fname}', fname=config['input']['fastas'])
  output:
    all='seqs/all.faa'
  message:
    "retrieving sequences ..."
  version: "0.11"
  run:
    # these files are not always produced and can therefore not be listed under output
    missing_seqs = os.path.join(os.getcwd(), 'seqs/missing_sequences.txt')
    ambig_seqs = os.path.join(os.getcwd(), 'seqs/ambiguous_sequences.txt')
    #file reset; remove files from potential prior executions
    for f in [missing_seqs, ambig_seqs]:
        if os.path.isfile(f):
            os.remove(f)

    #get accs
    accs_report = ProteinGroupSqlDbInteractor(input.pg_db).get_all_accs_from_pg_db()

    #screen fasta files submitted by user
    seqs = get_sequences_from_fasta(accs_report, input.user_fastas)

    #accessions with multiple seqs assigned
    ambig = [x for x in seqs if len(seqs[x]) > 1]
    if ambig:
        with open(ambig_seqs, "w") as handle:
            for acc in ambig:
                handle.write(acc + "\n")
        sys.exit("error: ambiguous sequence information in submitted fasta files.\nsee " + ambig_seqs + " for more information")


    #missings seqs
    missing = [x for x in accs_report if not x in seqs]
    if missing:
        with open(missing_seqs, "w") as handle:
            handle.write("\n".join(missing) + "\n")
        trace("error:\nmissing sequence information ({} accessions)\n".format(len(missing)) +
              "see\n" +
              "\t{}\n".format(missing_seqs) +
              "for more information", True)

    #write fasta
    with open(output['all'], "w") as handle:
        for acc, seq in sorted(seqs.items()):
            handle.write(">" + acc + "\n" + seq.pop() + "\n")
