#! /usr/bin/env python

"""\
%(prog)s <datafile1> [<datafile2> ...]

List the contents of YODA-readable data files (sorted by path name).
"""

from __future__ import print_function

import yoda, sys, argparse
from yoda.script_helpers import filter_aos

parser = argparse.ArgumentParser(usage=__doc__)
parser.add_argument("ARGS", nargs="+", help="infile [outfile]")
parser.add_argument('-v', '--verbose', action="store_const", const=2, default=1, dest='VERBOSITY',
                    help="print extra histogram details")
parser.add_argument('-q', '--quiet', action="store_const", const=0, default=1, dest='VERBOSITY',
                    help="just print histogram details, no cosmetic filenames or blank lines")
parser.add_argument("-m", "--match", dest="MATCH", metavar="PATT", default=None,
                    help="only write out histograms whose path matches this regex")
parser.add_argument("-M", "--unmatch", dest="UNMATCH", metavar="PATT", default=None,
                    help="exclude histograms whose path matches this regex")
args = parser.parse_args()

filenames = args.ARGS
if not filenames:
    print("ERROR! Please supply at least one data file for listing")
    sys.exit(1)

try:
    import natsort
    ysorted = natsort.natsorted
except:
    ysorted = sorted

for i, f in enumerate(filenames):
    if args.VERBOSITY >= 1:
        if i > 0: print()
        print("Data objects in %s:" % f)
    aodict = yoda.read(f)
    filter_aos(aodict, args.MATCH, args.UNMATCH)
    for p, ao in ysorted(aodict.items()):
        extrainfo = ""
        if args.VERBOSITY >= 2:
            if hasattr(ao, "numEntries"):
                extrainfo += " N={sumw:.3g}".format(sumw=ao.numEntries())
            if hasattr(ao, "sumW"):
                extrainfo += " sumW={sumw:.3g}".format(sumw=ao.sumW())
            if hasattr(ao, "underflow"):
                extrainfo += " uflow={sumw:.3g}".format(sumw=ao.underflow().sumW())
            if hasattr(ao, "overflow"):
                extrainfo += " oflow={sumw:.3g}".format(sumw=ao.overflow().sumW())
        try:
            nobjstr = "{n:4d}".format(n=len(ao))
        except:
            nobjstr = "   -"
        print("{path:<50} {type:<10} {nobjs} bins/pts".format(path=p, type=ao.type(), nobjs=nobjstr) + extrainfo)
