#!/usr/bin/env python
## Copyright (c) 2004, The Regents of the University of California, through
## Lawrence Berkeley National Laboratory (subject to receipt of any required
## approvals from the U.S. Dept. of Energy).  All rights reserved.
"""
Flag corrupted records in a log file.
"""
__author__ = "Dan Gunter, dkgunter@lbl.gov"
__created__ = "10 November 2004"
__rcsid__ = "$Id: nl_check 26525 2010-09-28 02:47:51Z dang $"

import sys
#
from netlogger.nllog import OptionParser, get_logger
from netlogger.parsers import base
from netlogger.util import ProgressMeter, NullProgressMeter

## Functions

def checkFile(infile, cleanfile=None, progress_meter=None,
              parser_class=None):
    """Check for parse errors in a file.
    """
    if cleanfile:
        parser = parser_class(parse_date=False, verify=True)
        for i, line in enumerate(infile):
            try:
                _ = parser.parseLine(line)
                cleanfile.write(line)
                progress_meter.advance(i+1)
            except ValueError, E:
                bpe = BPError(i+1, E)
                printError(line=line, linenum=i+1, error=bpe)
    else:
        parser = parser_class(input_file=infile, err_cb=printError,
                              parse_date=False, verify=True)
        for i, _ in enumerate(parser.parseStream()):
            progress_meter.advance(i+1)

total_errors = 0

def printError(line=None, linenum=None, error=None):
    err_str = str(error).replace('\n',' ')
    sys.stderr.write("*** %s\n" % err_str)
    global total_errors
    total_errors += 1

def run(files, clean=False, progress=False, fast=None):
    cleanfile = (None, sys.stderr)[clean]
    if progress:
        progress_meter = ProgressMeter(sys.stderr)
    else:
        progress_meter = NullProgressMeter()
    clazz = (base.NLPyParser, base.NLFastParser)[fast]
    for infile in files:
        checkFile(infile, cleanfile=cleanfile,
                  progress_meter=progress_meter, parser_class=clazz)
    sys.stderr.write("%d errors found\n" % total_errors)

def main():
    desc = ' '.join(__doc__.split())
    parser = OptionParser(usage="%prog [options] [filename]", description=desc)
    parser.add_option("-c", "--clean", action="store_true", dest='clean',
                      default=False,
                      help="write a copy of all 'clean' lines to stdout")
    parser.add_option("-f", "--fast", action="store_true", dest='fast',
                      default=False,
                      help="Do a quick-and-dirty check")
    parser.add_option("-p", "--progress", action="store_true",
                      dest="progress",
                      default=False, help="report progress to stderr")
    (options, args) = parser.parse_args()
    log = get_logger(__file__)  # Should be first done, just after parsing args
    files = [ ]
    if args:
        try:
            for filename in args:
                files.append(file(filename))
        except IOError, E:
            sys.stderr.write("Error opening input file: '%s': %s\n" %
                         (filename, E))
            return -1
    else:
        files = [sys.stdin]
    if not options.fast and not base.HAVE_PYPARSING:
        log.warn("module_not_found", value="PyParsing",
                 msg="falling back on fast mode parser")
        options.fast = True
    try:
        log.info("run.start", file_list=files)
        run(files, clean=options.clean, progress=options.progress,
            fast=options.fast)
        log.info("run.end", status=0)
    except KeyboardInterrupt:
        log.info("run.end", status=1, msg="keyboard interrupt")
    except:
        log.error("run.end", status=-1, msg="exception")
        return -1
    return 0

if __name__ == "__main__":
    sys.exit(main())
