#!/usr/bin/python

import optparse, os, re

import common
from autotest_lib.mirror import trigger

default_config_path = os.path.expanduser(
    os.path.join(os.path.dirname(__file__), 'config.py'))

options = optparse.Values()


def import_config_file(path):
    """
    Import the config file executing it as python code inside a class
    instance namespace to isolate the defined names inside it and return
    the the namespace (ie it emulates __import__ but does not require
    proper packages to the path of the module to import, just a full filename).
    """
    class namespace_type(object):
        def __init__(self):
            # hardcoded default values
            self.filter_exprs = ()
            self.trigger = trigger.trigger()
            self.__file__ = os.path.abspath(path)

    namespace = namespace_type()

    # execute the file using the given namespace
    execfile(path, namespace.__dict__)

    return namespace


def filter_kernels(files, exprs):
    # don't filter anything if no filtering expressions given
    if not exprs:
        return files

    compiled = [re.compile(r) for r in exprs]

    def matches(fname):
        for pattern in compiled:
            match = pattern.match(fname)
            if match:
                return match.groupdict().get('arg', fname)

        return None

    # return a sequence of (possibly transformed) matched filenames
    return set(filter(None, map(matches, files)))


def main():
    # import configuration file
    config = import_config_file(options.config)

    new_files = config.source.get_new_files()
    if options.verbose:
        print 'Found %d new files...' % len(new_files)

    if not new_files:
        return

    # commit the new files to the database
    if options.verbose:
        print 'Committing to the known files database...'
    config.source.store_files(new_files)

    if not options.dry_run:
        config.trigger.run(filter_kernels(new_files, config.filter_exprs))


if __name__ == '__main__':
    usage = 'mirror [options]'
    parser = optparse.OptionParser(usage=usage)
    parser.add_option('-c', '--config-file', dest='config',
                      help='Location of the configuration file; defaults \
                      to %s' % default_config_path, default=default_config_path)
    parser.add_option('-n', '--dry-run', dest='dry_run', action='store_true',
                      default=False,
                      help='Perform a dry run without scheduling jobs but \
                      updating the known files database.')
    parser.add_option('-q', '--quiet', dest='verbose', action='store_false',
                      default=True,
                      help='Do not print anything except errors.')
    (options, args) = parser.parse_args()

    main()
