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

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

"""
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.
"""


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}",
    'UBSAN_OPTIONS': "${RUNTIME_UBSAN_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
