#!/usr/bin/env python

import os
import sys
import string

sys.path.insert(0,'/dcslib/allsys/packages/python/local-lib')
sys.path.insert(0,'/usr/local/lib')
sys.path.insert(0,os.path.expanduser('~/lib'))
try:
    import modunits
    modunits_builtins = modunits.builtins()
except:
    modunits_builtins = []

by=[]
sep='\0' # this will rarely need to be changed
dict={}
sum=1
sumby=-1
total=0
percentages=0
units=''
after_decimal = 1000

def usage(retval):
    sys.stderr.write('Usage: %s [-t] [-p] [-i separator] [-h] -b field1 -b field2 ... -b fieldn -s field\n' % sys.argv[0])
    sys.stderr.write('-h\t\tsays to show this help message\n')
    sys.stderr.write('-t\t\tsays to give totals\n')
    sys.stderr.write('-p\t\tsays to give percentages\n')
    sys.stderr.write('-i separator\tsays to use separator internally for aggregating keys\n')
    sys.stderr.write('-b field\tindicates what fields to summarize by\n')
    sys.stderr.write('-s field\tindicates what field to add up\n')
    sys.stderr.write('-u units\tindicates what units to use, if any.  Options are: %s\n' % string.join(modunits_builtins))
    sys.stderr.write('-d digits\tindicates how many digits to put after the decimal point, at maximum\n')
    sys.exit(retval)

while sys.argv[1:]:
    if sys.argv[1] == '-b' and sys.argv[2:]:
        by.append(string.atoi(sys.argv[2]))
        del sys.argv[1]
    elif sys.argv[1] == '-i' and sys.argv[2:]:
        sep=sys.argv[2]
        del sys.argv[1]
    elif sys.argv[1] == '-d' and sys.argv[2:]:
        after_decimal=string.atoi(sys.argv[2])
        del sys.argv[1]
    elif sys.argv[1] == '-s' and sys.argv[2:]:
        sumby=string.atoi(sys.argv[2])
        del sys.argv[1]
    elif sys.argv[1] == '-t':
        totals=1
    elif sys.argv[1] == '-p':
        percentages=1
    elif sys.argv[1] == '-h':
        usage(0)
    elif sys.argv[1] == '-u' and sys.argv[2:]:
        units=sys.argv[2]
        if not units in modunits_builtins:
            sys.stderr.write('Sorry, illegal units specified\n')
            usage(1)
        del sys.argv[1]
    else:
        usage(1)
    del sys.argv[1]

if len(by) == 0:
    sys.stderr.write('Must specify at least one -b\n')
    usage(1)

if sumby < 0:
    sys.stderr.write('Must specify a positive -s\n')
    usage(1)

if totals == 0 and percentages == 0:
    sys.stderr.write('Must give one or both of -t or -p\n')
    usage(1)

while 1:
    line = sys.stdin.readline()
    if not line:
        break
    fields=string.split(line)
    badline=0
    for b in by:
        if not fields[b:]:
            badline=1
    if not fields[sumby:]:
        badline=1
    if badline:
        sys.stderr.write("Bad line: %s" % line)
    else:
        key = ''
        for b in by:
            if key == '':
                key = key + fields[b]
            else:
                key = key + sep + fields[b]
        if dict.has_key(key):
            try:
                dict[key] += string.atof(fields[sumby])
            except:
                sys.stderr.write('Could not convert %s to a float\n' % fields[sumby])
        else:
            dict[key] = sumby

keys = dict.keys()
keys.sort()
#print len(keys)

if totals:
    for key in keys:
        prefix=string.splitfields(key,sep)
        for p in prefix:
            sys.stdout.write(p+'\t')
        #sys.stdout.write(str(dict[key])+'\n')
        # give a pure number, whether the user requested it or not
        # (should be an option someday)
        if units == '':
            s = str(dict[key])
        else:
            s = modunits.modunits(units,dict[key])
        fields = string.splitfields(s,'.')
        sys.stderr.write('s is %s, fields is %s\n' % (s, str(fields)))
        len_fields = len(fields)
        if len_fields == 1:
            pass
        elif len_fields == 2:
            s = fields[0] + '.' + fields[1][0:after_decimal]
        else:
            sys.stderr.write('Internal error, too many fields from modunits\n')
        sys.stdout.write(s+'\n')

def percent(numerator,denominator):
    perc = int(numerator*1000.0/denominator)/10.0
    return perc

if percentages:
    if totals:
        print
    total=0

    # generate our total
    for key in keys:
        total+=dict[key]

    for key in keys:
        prefix=string.splitfields(key,sep)
        for p in prefix:
            sys.stdout.write(p+'\t')
        if total == 0:
            sys.stdout.write('INF\n')
        else:
            sys.stdout.write(str(percent(dict[key],total))+'%\n')