#!/usr/bin/env python
##
## Licensed to the Apache Software Foundation (ASF) under one
## or more contributor license agreements.  See the NOTICE file
## distributed with this work for additional information
## regarding copyright ownership.  The ASF licenses this file
## to you under the Apache License, Version 2.0 (the
## "License"); you may not use this file except in compliance
## with the License.  You may obtain a copy of the License at
##
##   http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing,
## software distributed under the License is distributed on an
## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
## KIND, either express or implied.  See the License for the
## specific language governing permissions and limitations
## under the License
##


"""
Run a tool or test in a build tree with the correct PATH, PYTHONPATH, etc.
Run with no arguments for help.
"""

usage="""
Run a tool or test in a build tree with the correct PATH, PYTHONPATH, etc.

Usage:
run.py <program> [<arg>....]               # Run a program, can be an interactive shell. Use PATH.
run.py -m <python-module>  [<arg>....]     # Run a python module. Use PYTHONPATH.
run.py -s <python-script>.py  [<arg>....]  # Run a python script.
run.py --vg <program> [<arg>....]          # Run a program with valgrind if enabled. Use PATH.
run.py --sh                                # Print a shell script to set the run.py environment.

Valgrind can be enabled or disabled by the cmake 'USE_VALGRIND' option and the
environment variable 'USE_VALGRIND' (set to 'ON' or 'OFF'). The environment
variable takes precendence if set.
"""

import os, sys, runpy
from subprocess import Popen, PIPE

def dedup(l):
    """Remove duplicates from list l, keep first instance. Keep order of l."""
    s = set()
    return [i for i in l if i not in s and (s.add(i) or True)]

sys.path = dedup([
    "${CMAKE_SOURCE_DIR}/python",
    "${CMAKE_BINARY_DIR}/python",
    "${CMAKE_SOURCE_DIR}/tests"
] + sys.path)

def getpath(env):
    path = os.environ.get(env)
    if path:
        return path.split(os.pathsep)
    return []

env_vars = {
    'PYTHONPATH': os.pathsep.join(sys.path),
    'PATH': os.pathsep.join(dedup(["${CMAKE_BINARY_DIR}",
                                   os.path.join("${CMAKE_BINARY_DIR}", 'tests'),
                                   os.path.join("${CMAKE_BINARY_DIR}", 'router'),
                                   os.path.join("${CMAKE_SOURCE_DIR}", 'tools'),
                                   os.path.join("${CMAKE_BINARY_DIR}", 'tools'),
                                   os.path.join("${CMAKE_SOURCE_DIR}", 'bin')] +
                                  getpath('PATH'))),
    'MANPATH' : os.pathsep.join([os.path.join("${CMAKE_BINARY_DIR}",'doc','man')] +
                                getpath('MANPATH')),
    'SOURCE_DIR': "${CMAKE_SOURCE_DIR}",
    'BUILD_DIR': "${CMAKE_BINARY_DIR}",
    'QPID_DISPATCH_HOME': "${CMAKE_SOURCE_DIR}",
    'QPID_DISPATCH_LIB': "${CMAKE_BINARY_DIR}/src/${QPID_DISPATCH_LIB}"
}
os.environ.update(env_vars)

# Valgrind setup
valgrind_exe = "${VALGRIND_EXECUTABLE}"

def use_valgrind():
    """True if we should use valgrind"""
    if not os.path.exists(valgrind_exe): return False
    def on(str):
        return str.lower() in ['on', 'yes', '1']
    env = os.environ.get('USE_VALGRIND')
    if env: return on(env)
    return on("${USE_VALGRIND}")

def find_exe(program):
    """Find an executable in the system PATH"""
    def is_exe(fpath):
        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
    mydir, name = os.path.split(program)
    if mydir:
        if is_exe(program): return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            exe_file = os.path.join(path, program)
            if is_exe(exe_file): return exe_file
    return None

def is_binary_exe(program):
    """True if the program is a binary executable"""
    if not program: return None
    p = Popen(['file', '-bi', program], stdout=PIPE, stderr=PIPE)
    return p.communicate()[0].startswith('application/x-executable')

VALGRIND_ERROR = 42   # magic number indicating valgrind found errors
def with_valgrind(args, outfile=None):
    if use_valgrind() and is_binary_exe(find_exe(args[0])):
        opts = ['--trace-children=yes',
                #  '--leak-check=full',  way too noisy due to Python leaks
                '--demangle=yes',
                '--suppressions=${CMAKE_SOURCE_DIR}/tests/valgrind.supp',
                '--num-callers=12',
                '--error-exitcode=%d' % VALGRIND_ERROR,
                '--quiet']
        if outfile: opts.append('--log-file=%s' % outfile)
        return ([valgrind_exe]+opts+args, VALGRIND_ERROR)
    return (args, 0)

def run_path(file_path, run_name=None):
    """Wrapper for run path that falls back to exec python for python < 2.7"""
    if hasattr(runpy, 'run_path'):
        runpy.run_path(file_path, run_name=run_name)
    else:                       # Python < 2.7
        os.execvp(sys.executable, [sys.executable]+sys.argv)

if __name__ == "__main__":
    error_prefix = ""
    try:
        if len(sys.argv) == 1:
            print usage
        elif sys.argv[1] == '-m':
            sys.argv = sys.argv[2:]
            error_prefix = "Run python module '%s': "%(sys.argv[0])
            runpy.run_module(sys.argv[0], alter_sys=True, run_name="__main__")
        elif sys.argv[1] == '-s':
            sys.argv = sys.argv[2:]
            error_prefix = "Run python script '%s':"%(sys.argv[0])
            run_path(sys.argv[0], run_name="__main__")
        elif sys.argv[1] == '--sh':
            for name, value in env_vars.iteritems(): print "%s=%s"%(name, value)
            print "export %s"%' '.join(env_vars.keys())
        elif sys.argv[1] == '--vg':
            args, ignore = with_valgrind(sys.argv[2:])
            error_prefix = "Run executable '%s' with valgrind: "%(args[0])
            os.execvp(args[0], args)
        elif sys.argv[1].startswith('-'):
            print usage
        else:
            args = sys.argv[1:]
            error_prefix = "Run executable '%s': "%(args[0])
            os.execvp(args[0], args)
    except Exception, e:
        print "%s%s: %s"%(error_prefix, type(e).__name__, e)
        raise

