# -*- 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"]

# 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 = ['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 = "/tmp/swift-package-tests"

# We don't make use of this yet.
#
# FIXME: This is pretty compiler specific and probably should just be ripped out
# of lit.
config.target_triple = None

# On Darwin, always push SDKROOT in the environment.
#
# FIXME: Eventually, when we use xcrun to launch the toolchain items, this
# should go away.
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 = os.path.join(package_path, "usr", "bin", "swift")
lit_config.note("testing using 'swift': %r" % (swift_path,))

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

lldb_path = 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( ('%{lldb}', lldb_path) )
config.substitutions.append( ('%{swift}', swift_path) )
config.substitutions.append( ('%{swiftc}', swiftc_path) )
config.substitutions.append( ('%{FileCheck}', filecheck_path) )

###

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