#!/usr/bin/env ${PY_STRING}
##
# 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
#

from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function

"""
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 -x <program> [<arg>....]            # Run an executable with the test runner
run.py --sh                                # Print a shell script to set the run.py environment.
"""

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

extra_paths = [
    "${CMAKE_SOURCE_DIR}/python",
    "${CMAKE_BINARY_DIR}/python",
    "${CMAKE_SOURCE_DIR}/tests"
]

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)]

def getpath(env):
    """Return a path environment variable split into a list"""
    path = os.environ.get(env)
    if path:
        return path.split(os.pathsep)
    return []

sys.path = dedup(extra_paths + sys.path)
python_path = dedup(extra_paths + getpath("PYTHONPATH"))

# runner program (e.g. valgrind) and args used to run qdrouterd
qdrouterd_runner = "${QDROUTERD_RUNNER}"

env_vars = {
    'PYTHONPATH': os.pathsep.join(python_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}",
    'QPID_DISPATCH_RUNNER': qdrouterd_runner,
    'MALLOC_CHECK_': "3",      # 3 = print error and abort
    'MALLOC_PERTURB_': "153",  # 153 = 0x99 freed memory pattern
    'TSAN_OPTIONS': "${RUNTIME_TSAN_ENV_OPTIONS}",
    'ASAN_OPTIONS': "${RUNTIME_ASAN_ENV_OPTIONS}",
    'LSAN_OPTIONS': "${RUNTIME_LSAN_ENV_OPTIONS}",
}
os.environ.update(env_vars)


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')

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("%s" % 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.items(): print('%s="%s"'%(name, value))
            print("export %s"%' '.join(env_vars.keys()))
        elif sys.argv[1] == '-x':
            args = qdrouterd_runner.split() + sys.argv[2:]
            error_prefix = "Running '%s': "%(args)
            os.execvp(args[0], args)
        elif sys.argv[1].startswith('-'):
            print(usage)
        else:
            args = sys.argv[1:]
            error_prefix = "Running '%s': "%(args)
            os.execvp(args[0], args)
    except Exception as e:
        print("%s%s: %s"%(error_prefix, type(e).__name__, e))
        raise

