#!/usr/bin/env python

from os.path import splitext
import sys

from csvkit import CSVKitReader, CSVKitWriter
from csvkit.cli import init_common_parser, extract_csv_reader_kwargs, extract_csv_writer_kwargs, install_exception_handler
from csvkit.cleanup import RowChecker

def format_error_row(e):
    """Format a row for """
    err_row = [e.line_number, e.msg]
    err_row.extend(e.row)
    return err_row

def main(args):
    """
    Fix errors in a CSV file.
    """
    install_exception_handler(args.verbose)
   
    reader = CSVKitReader(args.file, **extract_csv_reader_kwargs(args))

    if args.dryrun:
        checker = RowChecker(reader)
        for row in checker.checked_rows():
            pass
        for e in checker.errs:
            sys.stdout.write("Line %i: %s\n" % (e.line_number,e.msg))
        else:
            sys.stdout.write("No errors.\n")
        if checker.joins:
            sys.stdout.write("%i rows would have been joined/reduced to %i rows after eliminating expected internal line breaks.\n" % (checker.rows_joined, checker.joins))
    else:
        base,ext = splitext(args.file.name)
        # should we preserve delimiters and other dialect args from CLI?
        cleaned_file = CSVKitWriter(open("%s_out.csv" % base,"w"), **extract_csv_writer_kwargs(args))

        checker = RowChecker(reader)
        cleaned_file.writerow(checker.column_names)
        for row in checker.checked_rows():
            cleaned_file.writerow(row)
        
        if checker.errs:
            # should we preserve delimiters and other dialect args from CLI?
            err_filename = "%s_err.csv" % base
            err_file = CSVKitWriter(open(err_filename, "w"), **extract_csv_writer_kwargs(args))
            err_header = ['line_number','msg']
            err_header.extend(checker.column_names)
            err_file.writerow(err_header)
            for e in checker.errs:
                err_file.writerow(format_error_row(e))
                err_count = len(checker.errs)
            sys.stdout.write("%i error%s logged to %s\n" % (err_count,"" if err_count == 1 else "s", err_filename))
        else:
            sys.stdout.write("No errors.\n")

        if checker.joins:
            sys.stdout.write("%i rows were joined/reduced to %i rows after eliminating expected internal line breaks.\n" % (checker.rows_joined, checker.joins))

if __name__ == '__main__':
    """
    Process command line arguments.
    """
    parser = init_common_parser(description='Fix errors in a CSV file.')
    parser.add_argument('-n', '--dry-run', dest='dryrun', action='store_true',
                        help='''If this argument is present, no output will be created.
                                Information about what would have been done will be printed
                                to STDERR.
                        ''')
    
    main(parser.parse_args())
