#!/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
}
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

