# -*- Python -*-

import os
import platform

# Configuration file for the 'lit' test runner.

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

# testFormat: The test format to use to interpret tests.
#
# For now we require '&&' between commands, until they get globally killed and
# the test runner updated.
execute_external = platform.system() != 'Windows'
config.test_format = lit.formats.ShTest(execute_external,
                                        require_and_and = True)

# suffixes: A list of file extensions to treat as test files.
config.suffixes = ['.c', '.cpp', '.m', '.mm']

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

# test_exec_root: The root path where tests should be run.
clang_obj_root = getattr(config, 'clang_obj_root', None)
if clang_obj_root is not None:
    config.test_exec_root = os.path.join(clang_obj_root, 'test')

# Set llvm_{src,obj}_root for use by others.
config.llvm_src_root = getattr(config, 'llvm_src_root', None)
config.llvm_obj_root = getattr(config, 'llvm_obj_root', None)

# Tweak the PATH to include the tools dir and the scripts dir.
if clang_obj_root is not None:
    llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
    if not llvm_tools_dir:
        lit.fatal('No LLVM tools dir set!')
    path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH']))
    config.environment['PATH'] = path

    llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
    if not llvm_libs_dir:
        lit.fatal('No LLVM libs dir set!')
    path = os.path.pathsep.join((llvm_libs_dir,
                                 config.environment.get('LD_LIBRARY_PATH','')))
    config.environment['LD_LIBRARY_PATH'] = path

###

# Check that the object root is known.
if config.test_exec_root is None:
    # Otherwise, we haven't loaded the site specific configuration (the user is
    # probably trying to run on a test file directly, and either the site
    # configuration hasn't been created by the build system, or we are in an
    # out-of-tree build situation).

    # Try to detect the situation where we are using an out-of-tree build by
    # looking for 'llvm-config'.
    #
    # FIXME: I debated (i.e., wrote and threw away) adding logic to
    # automagically generate the lit.site.cfg if we are in some kind of fresh
    # build situation. This means knowing how to invoke the build system
    # though, and I decided it was too much magic.

    llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
    if not llvm_config:
        lit.fatal('No site specific configuration available!')

    # Get the source and object roots.
    llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip()
    llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip()
    clang_src_root = os.path.join(llvm_src_root, "tools", "clang")
    clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang")

    # Validate that we got a tree which points to here, using the standard
    # tools/clang layout.
    this_src_root = os.path.dirname(config.test_source_root)
    if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root):
        lit.fatal('No site specific configuration available!')

    # Check that the site specific configuration exists.
    site_cfg = os.path.join(clang_obj_root, 'test', 'lit.site.cfg')
    if not os.path.exists(site_cfg):
        lit.fatal('No site specific configuration available!')

    # Okay, that worked. Notify the user of the automagic, and reconfigure.
    lit.note('using out-of-tree build at %r' % clang_obj_root)
    lit.load_config(config, site_cfg)
    raise SystemExit

###

# Discover the 'clang' and 'clangcc' to use.

import os

def inferClang(PATH):
    # Determine which clang to use.
    clang = os.getenv('CLANG')

    # If the user set clang in the environment, definitely use that and don't
    # try to validate.
    if clang:
        return clang

    # Otherwise look in the path.
    clang = lit.util.which('clang', PATH)

    if not clang:
        lit.fatal("couldn't find 'clang' program, try setting "
                  "CLANG in your environment")

    return clang

def inferClangCC(clang, PATH):
    clangcc = os.getenv('CLANGCC')

    # If the user set clang in the environment, definitely use that and don't
    # try to validate.
    if clangcc:
        return clangcc

    # Otherwise try adding -cc since we expect to be looking in a build
    # directory.
    if clang.endswith('.exe'):
        clangccName = clang[:-4] + '-cc.exe'
    else:
        clangccName = clang + '-cc'
    clangcc = lit.util.which(clangccName, PATH)
    if not clangcc:
        # Otherwise ask clang.
        res = lit.util.capture([clang, '-print-prog-name=clang-cc'])
        res = res.strip()
        if res and os.path.exists(res):
            clangcc = res

    if not clangcc:
        lit.fatal("couldn't find 'clang-cc' program, try setting "
                  "CLANGCC in your environment")

    return clangcc

config.clang = inferClang(config.environment['PATH'])
if not lit.quiet:
    lit.note('using clang: %r' % config.clang)
config.substitutions.append( (' clang ', ' ' + config.clang + ' ') )

config.clang_cc = inferClangCC(config.clang, config.environment['PATH'])
if not lit.quiet:
    lit.note('using clang-cc: %r' % config.clang_cc)
config.substitutions.append( (' clang-cc ', ' ' + config.clang_cc + ' ') )
