import sys, os, subprocess

def quote_first_command_arg( arg):
    """
    There's a bug in Windows when running an executable that's
    located inside a path with a space in it.  This method handles
    that case, or on non-Windows systems or an executable with no
    spaces, it just leaves well enough alone.
    """
    if (sys.platform!='win32'
        or ' ' not in arg):
        # Problem does not apply:
        return arg
    try:
        import win32api
    except ImportError:
        raise ValueError(
            'The executable %r contains a space, and in order to '
            'handle this issue you must have the win32api module '
            'installed' % arg)
    arg = win32api.GetShortPathName(arg)
    return arg

def _turn_sigterm_into_systemexit():
    """
    Attempts to turn a SIGTERM exception into a SystemExit exception.
    """
    try:
        import signal
    except ImportError:
        return
    def handle_term(signo, frame):
        raise SystemExit
    signal.signal(signal.SIGTERM, handle_term)

def restart_with_monitor():
    while 1:
        args = [quote_first_command_arg(sys.executable)] + sys.argv
        new_environ = os.environ.copy()
        new_environ['_run'] = '1'
        proc = None
        try:
            try:
                _turn_sigterm_into_systemexit()
                proc = subprocess.Popen(args, env=new_environ)
                exit_code = proc.wait()
                proc = None
            except KeyboardInterrupt:
                print '^C caught in monitor process'
                return 1
        finally:
            if (proc is not None
                and hasattr(os, 'kill')):
                import signal
                try:
                    os.kill(proc.pid, signal.SIGTERM)
                except (OSError, IOError):
                    pass

        # Reloader always exits with code 3; but if we are
        # a monitor, any exit code will restart
        if exit_code != 3:
            return exit_code

def _auto_reload(app):
    if os.environ.get('_run'):
        import reloader
        reloader.install()
        app()
    else:
        restart_with_monitor()

def auto_reload(app):
    from time import sleep
    while True:
        _auto_reload(app)
        print '\nAuto Reloading After 3 seconds : '
        for i in xrange(10, 0, -1):
            sleep(0.3)
            print i,
        print ''
