# -*- Python -*-

import os
import sys

import lit.formats

# Configuration file for the 'lit' test runner.

# name: The name of this test suite.
config.name = 'lit'

# testFormat: The test format to use to interpret tests.
config.test_format = lit.formats.ShTest(execute_external=False)

# suffixes: A list of file extensions to treat as test files.
config.suffixes = ['.py']

# excludes: A list of individual files to exclude.
config.excludes = ['Inputs']

# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)
config.test_exec_root = config.test_source_root

config.target_triple = '(unused)'

src_root = os.path.join(config.test_source_root, '..')
llvm_src_root = getattr(config, 'llvm_src_root', None)
if llvm_src_root != None:
  # ``src_root`` may be in LLVM's binary build directory which does not contain
  # ``lit.py``, so use `llvm_src_root` instead.
  lit_path = os.path.join(llvm_src_root, 'utils', 'lit')
else:
  lit_path = src_root

pythonpath_list = [lit_path] # Required because some tests import the lit module

# Ensure the user's PYTHONPATH is included.
if 'PYTHONPATH' in os.environ:
    pythonpath_list.append(os.environ['PYTHONPATH'])
if 'PYTHONPATH' in config.environment:
    pythonpath_list.append(config.environment['PYTHONPATH'])
config.environment['PYTHONPATH'] = os.pathsep.join(pythonpath_list)

config.substitutions.append(('%{src_root}', src_root))
config.substitutions.append(('%{inputs}', os.path.join(
            src_root, 'tests', 'Inputs')))
config.substitutions.append(('%{lit}', "%%{python} %s" % (
            os.path.join(lit_path, 'lit.py'),)))
config.substitutions.append(('%{python}', '"%s"' % (sys.executable)))


# Enable coverage.py reporting, assuming the coverage module has been installed
# and sitecustomize.py in the virtualenv has been modified appropriately.
if lit_config.params.get('check-coverage', None):
    config.environment['COVERAGE_PROCESS_START'] = os.path.join(
        os.path.dirname(__file__), ".coveragerc")

# Add a feature to detect the Python version.
config.available_features.add("python%d.%d" % (sys.version_info[0],
                                                  sys.version_info[1]))

# Add a feature to detect if psutil is available
try:
    import psutil
    lit_config.note('Found python psutil module')
    config.available_features.add("python-psutil")
except ImportError:
    lit_config.warning('Could not import psutil. Some tests will be skipped and'
                       ' the --timeout command line argument will not work.')

if sys.platform.startswith('win') or sys.platform.startswith('cygwin'):
    config.available_features.add('windows')

# Add llvm and lit tools directories if this config is being loaded indirectly.
path = config.environment['PATH']
for attribute in ('llvm_tools_dir', 'lit_tools_dir'):
    directory = getattr(config, attribute, None)
    if directory:
        path = os.path.pathsep.join((directory, path))
config.environment['PATH'] = path
