# -*- Python -*-

import platform
import os
import subprocess

import lit.formats

# Configuration file for the 'lit' test runner.

def which(command, paths = None):
    """which(command, [paths]) - Look up the given command in the paths string
    (or the PATH environment variable, if unspecified)."""

    if paths is None:
        paths = os.environ.get('PATH','')

    # Check for absolute match first.
    if os.path.exists(command):
        return command

    # Would be nice if Python had a lib function for this.
    if not paths:
        paths = os.defpath

    # Get suffixes to search.
    pathext = os.environ.get('PATHEXT', '').split(os.pathsep)

    # Search the paths...
    for path in paths.split(os.pathsep):
        for ext in pathext:
            p = os.path.join(path, command + ext)
            if os.path.exists(p):
                return p

    return None

###
# Retrieve expected values from lit.site.cfg

srcroot = os.path.dirname(os.path.abspath(__file__))
srcroot = os.path.normpath(srcroot)

###
# Basic Configuration Parameters

# name: The name of this test suite.
config.name = 'swift-package-tests'

# 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.
#
# We override this in specific subdirectories to change what we test.
config.suffixes = [".txt", ".py", ".md"]

# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
config.excludes = ['README.md', 'CONTRIBUTING.md', 'Inputs']

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

# test_source_root: The root path where tests are executing.
config.test_exec_root = lit_config.params.get(
    "test-exec-root",
    "/tmp/swift-integration-tests")

# The triple is used during XFAIL processing.  If the triple
# specified here matches one of the XFAIL triples, a failing
# test is allowed to fail.  We don't actually need the whole
# thing, just enough to identify Linux, so for now only fill
# in enough to handle that.
#
# TODO figure out how to grab the whole triple for the build
# target and stick it in here.
if platform.system() == 'Linux':
    config.target_triple = 'linux'
elif platform.system() == 'Darwin':
    config.target_triple = 'darwin'


# On Darwin, always push SDKROOT in the environment.
#
# FIXME: Eventually, when we use xcrun to launch the toolchain items, this
# should go away.
config.environment["HOME"] = os.getenv("HOME")
if platform.system() == "Darwin":
    config.environment["SDKROOT"] = subprocess.check_output(
        ["xcrun", "--sdk", "macosx", "--show-sdk-path"]).strip()

###

# Use features like this in lit:
#   # REQUIRES: platform=<platform>
# where <platform> is Linux or Darwin
# Add a platform feature.
config.available_features.add("platform="+platform.system())

# Check if 'pexpect' is available.
have_pexpect = False
try:
    import pexpect
    have_pexpect = True
except ImportError as e:
    pass
if have_pexpect:
    config.available_features.add("have-pexpect")
else:
    lit_config.note("'pexpect' module unavailable, skipping related tests")

# For tests that need access to the outside world, let them know if
# that's possible
if lit_config.params.get("have-network"):
    config.available_features.add("have-network")
    
###

# Get the package path.
package_path = lit_config.params.get("package-path")
if package_path is None:
    # If a package wasn't provided, use the current selected toolchain on Darwin.
    if platform.system() == "Darwin":
        package_path = os.path.abspath(
            os.path.join(subprocess.check_output(["xcrun", "--find", "swift"]).strip(), "../../../"))
if package_path is None:
    lit_config.fatal("'--param package-path=PATH' is required")
package_path = os.path.abspath(package_path)
lit_config.note("testing package: %r" % (package_path,))

# Find the path to FileCheck. We just pick any one out of the build directory.
swift_build_path =  os.path.join(srcroot, "..", "build")
filecheck_path = lit_config.params.get("filecheck")
if filecheck_path is None:
    for variant in os.listdir(swift_build_path):
        variant_path = os.path.join(swift_build_path, variant)
        for tree in os.listdir(variant_path):
            if tree.startswith("llvm-"):
                path = os.path.join(variant_path, tree, "bin", "FileCheck")
                if os.path.exists(path):
                    filecheck_path = path
                    break
if filecheck_path is None:
    lit_config.fatal("unable to locate FileCheck, '--param filecheck=PATH' is required")

# Use the default Swift src layout if swiftpm is not provided as a
# param
swiftpm_srcdir = lit_config.params.get("swiftpm-srcdir")
if swiftpm_srcdir is None:
    swiftpm_srcdir = os.path.join(srcroot, "..", "swiftpm")
if os.path.exists(swiftpm_srcdir):
    config.available_features.add("have-swiftpm")
    config.substitutions.append( ('%{swiftpm_srcdir}', swiftpm_srcdir) )
    
# Find the tools we need.
lit_config.note("testing using 'FileCheck': %r" % (filecheck_path,))

swift_path = lit_config.params.get(
    "swift",
    os.path.join(package_path, "usr", "bin", "swift"))
lit_config.note("testing using 'swift': %r" % (swift_path,))

swiftc_path = lit_config.params.get(
    "swiftc",
    os.path.join(package_path, "usr", "bin", "swiftc"))
lit_config.note("testing using 'swiftc': %r" % (swiftc_path,))

lldb_path = lit_config.params.get(
    "lldb",
    os.path.join(package_path, "usr", "bin", "lldb"))
lit_config.note("testing using 'lldb': {}".format(lldb_path))
                    
# Verify they exist.
if not os.path.exists(swift_path):
    lit_config.fatal("swift does not exist!")
if not os.path.exists(swiftc_path):
    lit_config.fatal("swiftc does not exist!")
if not os.path.exists(filecheck_path):
    lit_config.fatal("filecheck does not exist!")
if not os.path.exists(lldb_path):
    if platform.system() == "Darwin":
        lldb_path = subprocess.check_output(["xcrun", "--find", "lldb"]).strip()
    else:
        lit_config.fatal("lldb does not exist!")

# Define our supported substitutions.
config.substitutions.append( ('%{not}', os.path.join(srcroot, "not")) )
config.substitutions.append( ('%{lldb}', lldb_path) )
config.substitutions.append( ('%{swift}', swift_path) )
config.substitutions.append( ('%{swiftc}', swiftc_path) )
config.substitutions.append( ('%{FileCheck}', filecheck_path) )

# Add substitutions for swiftpm executables.
swiftpm_build = lit_config.params.get("swiftpm-build")
if swiftpm_build is not None:
    lit_config.note("testing using swiftpm build directory: {}".format(swiftpm_build))
    config.substitutions.append( ('%{swift-build}',  os.path.join(swiftpm_build, "swift-build")) )
    config.substitutions.append( ('%{swift-test}',  os.path.join(swiftpm_build, "swift-test")) )
    config.substitutions.append( ('%{swift-run}',  os.path.join(swiftpm_build, "swift-run")) )
else:
    config.substitutions.append( ('%{swift-build}', swift_path + ' build') )
    config.substitutions.append( ('%{swift-test}', swift_path + ' test') )
    config.substitutions.append( ('%{swift-run}', swift_path + ' run') )

###

# Protected against unquoted use of substitutions.
for name in ('swift-build', 'FileCheck'):
  config.substitutions.append((' {0} '.format(name),
                               ' unquoted-command-name-{0} '.format(name)))
