from hachoir_core.cmd_line import unicodeFilename
from hachoir_core.stream import FileInputStream
from hachoir_core.i18n import _
from hachoir_core import config
from hachoir_subfile.search import SearchSubfile
import hachoir_core
from sys import exit
from optparse import OptionGroup, OptionParser

def displayVersion(*args):
    from hachoir_subfile.version import VERSION, WEBSITE
    print _("Hachoir subfile version %s") % VERSION
    print _("hachoir-core version %s") % hachoir_core.__version__
    print
    print _("Website: %s") % WEBSITE
    exit(0)

def parseOptions():
    parser = OptionParser(usage="%prog [options] filename [output_directory]")

    common = OptionGroup(parser, "hachoir-subfile", _("Option of hachoir-subfile"))
    common.add_option("--offset", help=_("Skip first bytes of input file"),
        action="store", type='int', default=0)
    common.add_option("--size", help=_("Maximum size of input file"),
        action="store", type='int', default=None)
    common.add_option("--category", help=_("Parser category list (separated with a comma)"),
        action="store", type='str', default=None)
    common.add_option("--parser", help=_("Parser identifier list (separated with a comma)"),
        action="store", type='str', default=None)
    common.add_option("--version", help=_("Display version and exit"),
        action="callback", callback=displayVersion)
    common.add_option("--quiet", help=_("Be quiet"),
        action="store_true", default=False)
    common.add_option("--profiler", help=_("Run profiler"),
        action="store_true", default=False)
    common.add_option("--debug", help=_("Enable debug mode"),
        action="store_true", default=False)
    parser.add_option_group(common)

    values, arguments = parser.parse_args()
    if len(arguments) == 1:
        filename, output = arguments[0], None
    elif len(arguments) == 2:
        filename, output = arguments
    else:
        parser.print_help()
        exit(1)
    return values, filename, output

def displaySearchStat(subfile):
    stats = [ (parser.tags["id"], stats[0], stats[1])
        for parser, stats in subfile.stats.iteritems() ]
    print
    print "[ Match statistics ]"
    total_hit = 0
    total_valid = 0
    if stats:
        stats.sort(key=lambda values: values[1])
        for parser_id, hit, valid in stats:
            print " - %s: %u hit/%u valid" % (parser_id, hit, valid)
            total_hit += hit
            total_valid += valid
        print
    else:
        print "(no match)"
    print "Total: %u hit/%u valid" % (total_hit, total_valid)

def runSearch(subfile, values):
    # Load categories and parsers
    categories = values.category
    if categories:
        categories = categories.split(",")
    parsers = values.parser
    if parsers:
        parsers = parsers.split(",")
    subfile.loadParsers(categories=categories, parser_ids=parsers)

    # Search subfiles
    ok = subfile.main()

    # Dump statistics on debug mode
    if values.debug:
        displaySearchStat(subfile)
    return ok

def main():
    # Initialize
    values, filename, output = parseOptions()
    config.quiet = True
    stream = FileInputStream(unicodeFilename(filename), real_filename=filename)
    subfile = SearchSubfile(stream, values.offset, values.size)
    subfile.verbose = not(values.quiet)
    subfile.debug = values.debug
    if output:
        subfile.setOutput(output)
    if values.profiler:
        from hachoir_core.profiler import runProfiler
        ok = runProfiler(runSearch, (subfile, values))
    else:
        ok = runSearch(subfile, values)
    exit(int(not ok))

if __name__ == "__main__":
    main()

