#!/usr/bin/env python


"""
Main running script for lazyrunner. 
"""

# Import all the relevant stuff

import sys
from optparse import OptionParser, OptionGroup, IndentedHelpFormatter
import re
from itertools import izip
import subprocess, logging
from treedict import TreeDict

if __name__ == '__main__':

    ########################################
    # Configure the action parser
    usage = '\n%s [options] preset1, preset2, ...' % sys.argv[0]

    description = "Queued Runner -- module based scientific programming."

    formatter = IndentedHelpFormatter(max_help_position = 50, width=96)
    parser = OptionParser(usage=usage, description=description, formatter=formatter)

    ##############################
    # Now go through and add in all the names

    running_options = OptionGroup(parser, "Run Options")

    running_options.add_option('-g', '--debug', dest='debug_mode', action="store_true",
                               help="Sets the logging level to debug, so all log.debug() "
                               "messages are printed; turns on compiler debug flags.",
                               default=False)

    running_options.add_option('-v', '--verbose', dest='verbose_mode', action="store_true",
                               help="Turns on more detailed printing of lazyrunner actions and messages.",
                               default=False)

    running_options.add_option('-s', '--settings', 
                               help="Run a specified settings file instead of 'defaults'. "
                               "(Path from settings/ subdirectory, '.py suffix is optional).",
                               metavar="<settings module/file>",
                               default="defaults")

    parser.add_option_group(running_options)
    
    ####################
    # Cache options

    cache_options = OptionGroup(parser, "Cache Options and Commands")
    
    cache_options.add_option('', '--nocache', dest='no_cache', action="store_true",
                             help="Disable use of the disk cache.",
                             default=False)

    cache_options.add_option('', '--cache-read-only', '--ro', dest="cache_read_only", action="store_true",
                             help="Make the cache read-only; useful for testing new modules.",
                             default=False)

    cache_options.add_option('','--cache-directory', dest="cache_directory", type="string",
                             help="Use an alternate cache directory instead of the one defined "
                             "in conf.py.",
                             metavar="<directory>",
                             default=None)
                             
    parser.add_option_group(cache_options)

    ####################
    # Creating new things

    creation_options = OptionGroup(parser, "Creating / Initializing Options")
    
    creation_options.add_option('', '--init', dest="init", action="store_true",
                                help="Initialize a new project in the current working directory.",
                                default=False)

    creation_options.add_option('-f', '--force', dest="force", action="store_true",
                                help="Force operation to stop only under fatal errors.",
                                default=False)

    creation_options.add_option('-m', '--new-module', dest="new_module", type="string",
                                help=
                                "Write a new processing module template file.  The argument "
                                "is of the form '[dir[.subdir]].module'.  For 'dir.ModName', a "
                                "template module named 'ModName' is created in 'dir/modname.py'.",
                                default = None, metavar="<Module Name>")

    parser.add_option_group(creation_options)


    ####################
    # Query options

    query_options = OptionGroup(parser, "Querying and Information Options")

    query_options.add_option('-l', '--list-presets', dest="list_presets", action="store_true",
                             help="List available presets and exit.",
                             default=False)

    parser.add_option_group(query_options)

    ####################
    # Cleaning options

    cleaning_options = OptionGroup(parser, "Cleaning / Deletion Options")

    cleaning_options.add_option('', '--clean', dest="clean", action="store_true",
                             help="Clean all intermediate compiling files.",
                             default=False)

    parser.add_option_group(cleaning_options)

    ################################################################################
    
    options, args = parser.parse_args()

    ####################
    # See what's going on...
    
    def print_use_help():
        print "Usage: %s\n" % usage
        print "\nUse --help to get a list of options."
        sys.exit(1)

    ##################################################
    # Put in common options; sanitize input options
    import os

    base_dir = os.getcwd()

    opttree = TreeDict()

    opttree.debug_mode      = options.debug_mode
    opttree.verbose_mode    = options.verbose_mode
    opttree.no_cache        = options.no_cache
    opttree.force           = options.force
    opttree.cache_read_only = options.cache_read_only
    opttree.cache_directory = options.cache_directory
    opttree.presets         = args

    ########################################
    # 
    opttree.config_module_name = "conf"

    ########################################
    # Sanitization of running presets

    # Settings module
    sm = "settings." + options.settings

    if sm.endswith(".py"):
        sm = sm[:-3]

    opttree.settings_module = sm.replace("/", ".")

    ########################################
    # Run the specific options 

    opttree.freeze()

    # This allows modules to be loaded from this one as a base
    sys.path.append(base_dir)

    if options.list_presets:
        import lazyrunner.running as running
        import lazyrunner.presets as presets

        running.loadBase(base_dir, opttree)
        print ""
        print "Available presets:"
        print "-"*50
        presets.printPresetHelpList()
        print ""
        
    elif options.init:
        import lazyrunner.creation as creation
        creation.createInitial(base_dir, opttree)
       
    elif options.new_module is not None:
        import lazyrunner.creation as creation
        creation.createNewModule(base_dir, opttree, options.new_module)

    elif options.clean:
        import lazyrunner.running as running
        import lazyrunner.cleaning as cleaning
        config = running.loadConfigInformation(base_dir, opttree)
        cleaning.cleanAll(opttree, config, base_dir)

    else:
        print ""

        if len(args) == 0:
            print "Warning: Running with no presets specified; use --help to get a list of options.\n"

        import lazyrunner.running as running
        running.run(base_dir, opttree)

        print ""

       
