#!/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 788 2008-06-02 17:11:49Z dang $"

import logging
from optparse import OptionParser
import sys
import time
import warnings
#
from netlogger import nllog
from netlogger.parsers import base
from netlogger.util import ProgressMeter, NullProgressMeter

# Logging
log = nllog.NullLogger()
def activateLogging(name="netlogger.nl_check"):
    global log
    log = nllog.getScriptLogger(name)

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.setLine(i+1)
            except ValueError, E:
                bpe = BPError(i+1, E)
                printError(line=line, linenum=i+1, error=bpe)
    else:
        parser = parser_class(err_cb=printError, parse_date=False,
                              verify=True)
        for i, _ in enumerate(parser.parseStream(infile)):
            progress_meter.setLine(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():
    parser = OptionParser(usage="%prog [options] [filename]", version="2.0")
    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()
    files = [ ]
    if args:
        try:
            for filename in args:
                files.append(file(filename))
        except IOError, E:
            parser.error("Error opening input file: i'%s': %s" % 
                         (filename, E))
    else:
        files = [sys.stdin]
    if not options.fast and not base.HAVE_PYPARSING:
        warnings.warn("PyParsing not found, falling back on -f/--fast mode")
        options.fast = True
    run(files, clean=options.clean, progress=options.progress,
        fast=options.fast)

if __name__ == "__main__":
    main()                                                       
