#!/usr/bin/env python
#
# This is a thing wrapper around the 'seqstat' program
# The input is any number of key-value pairs.  Those keys starting with
# 'input.' are taken to correspond to input tags containg fasta files.
# 'seqstat' is run on each file in the input tag and the results are combined
# into a single metric.  The following values are returned
#
# params.MAX_QUERY_SEQ_LEN
# params.MIN_QUERY_SEQ_LEN
# params.AVG_QUERY_SEQ_LEN
# params.NUM_QUERY_SEQ
import sys
import os

from igs.utils import commands

from vappio.webservice import tag

def seqstat(f):
    ret = []
    commands.runSingleProgramEx('seqstat ' + f, stdoutf=ret.append, stderrf=None)
    kv = {'Number of sequences': None,
          'Total # residues': None,
          'Smallest': None,
          'Largest': None,
          'Average length': None,
          }

    for r in ret:
        if ':' not in r: continue
        k, v = r.split(':', 1)
        if k in kv:
            kv[k] = v.strip()

    return (int(kv['Number of sequences']),
            int(kv['Total # residues']),
            float(kv['Average length']),
            int(kv['Smallest']),
            int(kv['Largest']))

          


# Ensure we are dealing with kv pairs
if sys.stdin.readline().strip() != 'kv':
    raise Exception('Header needs to be kv')

# Write our header out
sys.stdout.write('kv\n')

tags = []
for line in sys.stdin:
    sys.stdout.write(line.strip() + '\n')
    if not line.strip(): continue
    k, v = line.strip().split('=', 1)
    if k.startswith('input.'):
        tags.append(v)


stats = {'num_seq': 0,
         'avg_len': 0.0,
         'max_len': 0,
         'min_len': 0
         }

for t in tags:
    tagFile = tag.listTags('localhost', 'local', {'tag_name': t}, True)[0]
    for f in tagFile['files']:
        
        # Skip if the file is empty
        if os.stat(f).st_size == 0:
            continue
        
        numSeq, totRes, avgLen, minLen, maxLen = seqstat(f)
        stats['avg_len'] = (stats['num_seq'] * stats['avg_len'] + totRes)/(numSeq + stats['num_seq'])
        stats['num_seq'] += numSeq
        stats['max_len'] = maxLen if maxLen > stats['max_len'] else stats['max_len']
        stats['min_len'] = minLen if minLen < stats['min_len'] or stats['min_len'] == 0 else stats['min_len']

sys.stdout.write('\n'.join([k + '=' + str(v) for k, v in [('params.MAX_QUERY_SEQ_LEN', stats['max_len']),
                                                          ('params.MIN_QUERY_SEQ_LEN', stats['min_len']),
                                                          ('params.AVG_QUERY_SEQ_LEN', stats['avg_len']),
                                                          ('params.NUM_QUERY_SEQ', stats['num_seq'])]]))
