#!/usr/bin/python -O

__pychecker__ = 'no-shadowbuiltin'

import re

from optparse import OptionParser
from os import makedirs, walk
from os.path import dirname, isdir, join, relpath
from subprocess import check_call, PIPE, Popen
from sys import exit, path


def extract_and_edit(extractor, output, suffix, filepath, section, pattern, edit_source):
    outfile = open('%s.%s' % (output, suffix), 'w')
    argv = [extractor, section, filepath]
    if edit_source:
        exe = Popen(argv, stdout=PIPE)
        for line in exe.stdout:
            line = pattern.sub(edit_source[1], line)
            print >>outfile, line,
    else:
        check_call(argv, stdout=outfile)


def main():
    parser = OptionParser(usage='usage: %prog [options]', epilog='Extract and save paths are required.  Source editing is optional.')
    parser.add_option('--extract', metavar='DIR')
    parser.add_option('--save', metavar='DIR')
    parser.add_option('--edit-source', metavar='PATH PATH', nargs=2)

    options, args = parser.parse_args()
    if options.extract is None or options.save is None or args:
        parser.print_help()
        exit(2)

    options.extract = options.extract.rstrip('/')
    options.save = options.save.rstrip('/')
    if options.edit_source:
        original = re.escape(options.edit_source[0].rstrip('/'))
        edit_sites = re.compile('^' + original)
        edit_cfg = re.compile('(?:^|\t)' + original)

    extractor = join(path[0], 'extract-section')
    typer = Popen(['file', '--print0', '--separator=', '--no-buffer', '--no-pad', '--files-from=-'], stdin=PIPE, stdout=PIPE)
    unstripped_re = re.compile('\0 *ELF .*, not stripped$')

    for dirpath, dirnames, filenames in walk(options.extract):
        for filename in filenames:
            filepath = join(dirpath, filename)
            print >>typer.stdin, filepath
            magic = typer.stdout.readline()
            if not unstripped_re.search(magic): continue

            subpath = relpath(filepath, options.extract)
            output = join(options.save, '/usr/lib/sampler'.lstrip('/'), 'sites', subpath)
            outdir = dirname(output)
            if not isdir(outdir):
                makedirs(outdir)

            extract_and_edit(extractor, output, 'sites', filepath, '.debug_site_info', edit_sites, options.edit_source)
            extract_and_edit(extractor, output, 'cfg', filepath, '.debug_sampler_cfg', edit_cfg, options.edit_source)


if __name__ == '__main__':
    main()
