#! /usr/bin/env python

import os

from pro import runner

DEFAULT_RUNFILE_NAME = 'runfile.py'

def find_runfile(runfile=None):
    """
    Attempt to locate a runfile, either explicitly or by searching parent dirs.

    Cribbed from Fabric's main.py
    """
    # Obtain env value
    names = []
    if runfile is not None:
        names.append(runfile)
    names.append(DEFAULT_RUNFILE_NAME)
    # Create .py version if necessary
    if not names[0].endswith('.py'):
        names += [names[0] + '.py']
    # Does the name contain path elements?
    if os.path.dirname(names[0]):
        # If so, expand home-directory markers and test for existence
        for name in names:
            expanded = os.path.expanduser(name)
            if os.path.exists(expanded):
                if name.endswith('.py') or _is_package(expanded):
                    return os.path.abspath(expanded)
    else:
        # Otherwise, start in cwd and work downwards towards filesystem root
        path = '.'
        # Stop before falling off root of filesystem (should be platform
        # agnostic)
        while os.path.split(os.path.abspath(path))[1]:
            for name in names:
                joined = os.path.join(path, name)
                if os.path.exists(joined):
                    if name.endswith('.py') or _is_package(joined):
                        return os.path.abspath(joined)
            path = os.path.join('..', path)
    # Implicit 'return None' if nothing was found

def load_runfile(path, importer=None):
    """
    Import given runfile path
    
    Cribbed from fabric's main.py
    """
    if importer is None:
        importer = __import__
    # Get directory and fabfile name
    directory, fabfile = os.path.split(path)
    # If the directory isn't in the PYTHONPATH, add it so our import will work
    added_to_path = False
    index = None
    if directory not in sys.path:
        sys.path.insert(0, directory)
        added_to_path = True
    # If the directory IS in the PYTHONPATH, move it to the front temporarily,
    # otherwise other watchfiles may scoop the intended one.
    else:
        i = sys.path.index(directory)
        if i != 0:
            # Store index for later restoration
            index = i
            # Add to front, then remove from original position
            sys.path.insert(0, directory)
            del sys.path[i + 1]
    # Perform the import (trimming off the .py)
    imported = importer(os.path.splitext(fabfile)[0])
    # Remove directory from path if we added it ourselves (just to be neat)
    if added_to_path:
        del sys.path[0]
    # Put back in original index if we moved it
    if index is not None:
        sys.path.insert(index + 1, directory)
        del sys.path[0]

USAGE = """PRO runs processes and restarts them when it observes file changes.

Usage: pro [RUNFILE]

Options:
  -h/--help   Show this help output
"""

def main(manual_runfile=None):
    runfile = find_runfile(manual_runfile)
    if manual_runfile in ('--help', '-h') or runfile is None:
        print USAGE
        return
    load_runfile(runfile)
    runner.run_updates()

if __name__ == '__main__':
    import sys
    main(*sys.argv[1:])
