#!/usr/bin/env pypy

import os
import sys
from collections import OrderedDict
from operator import itemgetter
from optparse import OptionParser

import app
from lru import LRUFileCache

class SplatApp(app.App):
    bakext = '.bak'

    optparser = OptionParser()
    optparser.set_defaults(verbose=False)
    optparser.add_option('-v', '--verbose',
        dest='verbose', action='store_true')
    optparser.add_option('-q', '--quiet',
        dest='verbose', action='store_false')
    optparser.add_option('-i', '--inplace',
        dest='inplace', action='store_true', default=False)

    def __init__(self, args=None):
        self.opts, args = self.optparser.parse_args(args)
        if not len(args):
            self.optparser.error('no extrator given')
        self.extractor = args[0]
        self.files = args[1:]
        self.inplace = self.opts.inplace

    def __call__(self):
        if self.inplace and not self.files:
            print >>sys.stderr, 'No files given, ignoring --inplace'
            self.inplace = False
        if self.inplace:
            for fp in self.input_files():
                os.rename(fp.name, fp.name + self.bakext)
                os.mkdir(fp.name)
                self.keyfilebase = fp.name
                self.splat_records(self.parse_file_records(fp))
                del self.keyfilebase
        else:
            self.splat_records(self.records())

    def splat_records(self, records):
        if self.opts.verbose:
            counts = OrderedDict()
            paths = []

        with LRUFileCache(self.openkeyfile) as filecache:
            for record in records:
                key = self.extractor(record)
                filecache.use(key).write(record)
                if self.opts.verbose:
                    try:
                        counts[key] += 1
                    except KeyError:
                        counts[key] = 1
                        paths.append(filecache[key].name)

        if self.opts.verbose:
            counts = counts.values()
            fmt = '  %% %dd %%s' % len(str(max(counts)))
            for count_path in sorted(zip(counts, paths), key=itemgetter(0)):
                print fmt % count_path

SplatApp()()

# vim:set ft=python ts=4 sw=4 et:
