#!python

"""Merges (averages, adds, or subtracts) preferences or differential preferences.

Written by Jesse Bloom."""


import sys
import os
import time
import dms_tools.utils
import dms_tools.parsearguments
import dms_tools.file_io


def main():
    """Main body of script."""

    # Parse command line arguments
    parser = dms_tools.parsearguments.MergeParser()
    args = vars(parser.parse_args())
    prog = parser.prog

    # print initial information
    versionstring = dms_tools.file_io.Versions() 
    print 'Beginning execution of %s in directory %s\n' % (prog, os.getcwd())
    print versionstring
    print 'Parsed the following arguments:\n%s\n' % '\n'.join(['\t%s = %s' % tup for tup in args.iteritems()])

    # remove outfile if it exists
    if os.path.isfile(args['outfile']):
        print "Removing existing output file of %s" % args['outfile']
        os.remove(args['outfile'])

    # read data, merge, and create outfile
    if not args['minus']:
        args['minus'] = [] # reassign from None to empty list
    (sites, characters, wts, databyfile) = dms_tools.file_io.ReadMultiPrefOrDiffPref(\
            args['infiles'] + args['minus'], args['excludestop'])
    filetypes = dict([(fname, dms_tools.utils.Pref_or_DiffPref(databyfile[fname])) for fname in args['infiles'] + args['minus']])
    print "\nHere are the apparent file types of the input files:\n%s\n" % '\n'.join(['%s is %s' % tup for tup in filetypes.iteritems()])
    sums = dms_tools.utils.SumPrefsDiffPrefs([databyfile[fname] for fname in args['infiles']], minus=[databyfile[fname] for fname in args['minus']])
    if args['merge_method'] == 'average':
        if args['minus']: 
            raise ValueError('Cannot use --minus option when the merge_method is "average"; can only use it for "sum".')
        # now conver the sums to averages by dividing values by number of files
        for r in sums.keys():
            for x in sums[r].keys():
                sums[r][x] /= float(len(databyfile))
        if all([ftype == 'preferences' for ftype in filetypes.values()]):
            print "Writing the average of the preferences to %s" % args['outfile']
            dms_tools.file_io.WritePreferences(args['outfile'], sites, wts, sums, None)
        elif all([ftype == 'diffprefs' for ftype in filetypes.values()]):
            print "Writing the average of the differential preferences to %s" % args['outfile']
            dms_tools.file_io.WriteDiffPrefs(args['outfile'], sites, wts, sums, None, None)
        else:
            raise ValueError("The input files do not all specify the same file type, but this is required when averaging. The file types appear to be:\n%s" % '\n'.join(['%s is %s' % tup for tup in filetypes.iteritems()]))
    elif args['merge_method'] == 'sum':
        sumtype = dms_tools.utils.Pref_or_DiffPref(sums)
        if sumtype == 'preferences':
            print "The listed files summed to give valid preferences. Now writing these preferences to %s" % args['outfile']
            dms_tools.file_io.WritePreferences(args['outfile'], sites, wts, sums, None)
        elif sumtype == 'diffprefs':
            print "The listed files summed to give valid differential preferences. Now writing these differential preferences to %s" % args['outfile']
            dms_tools.file_io.WriteDiffPrefs(args['outfile'], sites, wts, sums, None, None)
        else:
            raise ValueError("The sum of the files does not yield either valid preferences or differential preferences. Are you sure you are summing a valid combination?")
    else:
        raise ValueError("Invalid merge_method of %s" % args['merge_method'])

    print 'Successfully completed %s at %s' % (prog, time.asctime())



if __name__ == '__main__':
    main() # run the script
