# -*- 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:
    lit_config.fatal("'--param package-path=PATH' is required")
package_path = os.path.abspath(package_path)
# if platform.system() == "Darwin":
#     package_path = os.path.join(package_path, "Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain")
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):
    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 a substitution for swiftpm build directory. This is useful for
# running the integration tests locally, for e.g. by changing:
# %{swift} build -> %{swiftpm_build}/swift-build
swiftpm_build = lit_config.params.get("swiftpm-build")
if swiftpm_build is not None:
    config.substitutions.append( ('%{swiftpm_build}', swiftpm_build) )
    lit_config.note("testing using swiftpm build directory: {}".format(swiftpm_build))

###

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