# Tests/Functional/lit.cfg - Functional test suite lit config -*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors

import os
import platform
import tempfile
import sys
import lit

# Set up lit config.
config.name = 'SwiftXCTestFunctionalTests'
config.test_format = lit.formats.ShTest(execute_external=False)
config.suffixes = ['.swift']

# Set up the substitutions used by the functional test suite.

# First, our tests need a way to compile source files into
# executables that are linked against swift-corelibs-xctest.
# We'll provide one via the %swiftc substitution.
#
# Linux tests are run after swift-corelibs-xctest is installed
# in the Swift library path, so we only need the path to `swiftc`
# in order to compile.
def _getenv(name):
    value = os.getenv(name, None)
    if value is None:
        lit_config.fatal(
            'Environment variable ${} is required to run tests on this '
            'platform, but it is not set.'.format(name))
    return value

built_products_dir = _getenv('BUILT_PRODUCTS_DIR')
# Force tests to build with -swift-version 4 for now.
swift_exec = [ _getenv('SWIFT_EXEC'), '-swift-version', '4', ]
if not platform.system() == 'Windows':
    swift_exec.extend(['-Xlinker', '-rpath', '-Xlinker', built_products_dir,])
swift_exec.extend([
    '-L', built_products_dir,
    '-I', built_products_dir,
    '-I', os.path.join(built_products_dir, 'swift'),
])

if platform.system() == 'Linux':
    swift_exec.extend(['-Xcc', '-DDEPLOYMENT_TARGET_LINUX'])
elif platform.system() == 'Darwin':
    swift_exec.extend(['-Xcc', '-DDEPLOYMENT_TARGET_MACOSX'])
elif platform.system() == 'Windows':
    swift_exec.extend(['-Xcc', '-DDEPLOYMENT_TARGET_WINDOWS'])

if platform.system() == 'Darwin':
    # On Darwin, we need to make sure swiftc references the
    # proper SDK, has a deployment target set, and more...
    # Here we rely on environment variables, produced by xcodebuild.
    sdk_root = _getenv('SDKROOT')
    platform_name = _getenv('PLATFORM_NAME')
    deployment_target = _getenv('MACOSX_DEPLOYMENT_TARGET')

    target = '{}-apple-{}{}'.format(
        platform.machine(), platform_name, deployment_target)
    swift_exec.extend([
        '-sdk', sdk_root,
        '-target', target,
        '-F', built_products_dir,
        # FIXME: We must include the C header dependencies of any module we wish
        #        to use, due to a limitation in the Swift compiler. See SR-655
        #        for details. Here, we include the headers from CoreFoundation.
        '-I', os.path.join(built_products_dir, 'usr', 'local', 'include'),
    ])
else:
    # We need to jump through extra hoops to link swift-corelibs-foundation.
    foundation_dir = _getenv('FOUNDATION_BUILT_PRODUCTS_DIR')
    core_foundation_dir = _getenv('CORE_FOUNDATION_BUILT_PRODUCTS_DIR')
    if platform.system() == 'Windows':
        swift_exec.extend(['-Xlinker', '-nodefaultlib:libcmt'])
    else:
        swift_exec.extend(['-Xlinker', '-rpath', '-Xlinker', foundation_dir,])
    swift_exec.extend([
        '-L', foundation_dir,
        '-I', foundation_dir,
        '-I', os.path.join(foundation_dir, 'swift'),
        '-Xcc', '-F', '-Xcc', foundation_dir,

        '-I', core_foundation_dir,
        '-Xcc', '-F', '-Xcc', os.path.join(core_foundation_dir, 'System', 'Library', 'Frameworks'),
    ])

    # We also need to link swift-corelibs-libdispatch, if
    # swift-corelibs-foundation is using it.
    libdispatch_src_dir = os.getenv('LIBDISPATCH_SRC_DIR')
    libdispatch_build_dir = os.getenv('LIBDISPATCH_BUILD_DIR')
    libdispatch_overlay_dir = os.getenv('LIBDISPATCH_OVERLAY_DIR')
    if ((libdispatch_src_dir is not None) 
        and (libdispatch_build_dir is not None)
        and (libdispatch_overlay_dir is not None)):
            swift_exec.extend([
                '-Xcc', '-fblocks',
                '-I', libdispatch_src_dir,
                '-I', libdispatch_overlay_dir,
                '-L', libdispatch_build_dir,
                '-L', os.path.join(libdispatch_build_dir, 'src'),
            ])

    config.environment['LD_LIBRARY_PATH'] = "{}:{}/src:{}".format(libdispatch_build_dir, libdispatch_build_dir, foundation_dir)

# Having prepared the swiftc command, we set the substitution.
config.substitutions.append(('%{swiftc}', ' '.join(swift_exec)))

# Add the %{xctest_checker} substitution, which is a Python script that
# can be used to compare the actual XCTest output to the expected
# output.
xctest_checker = os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    'xctest_checker',
    'xctest_checker.py')
config.substitutions.append(('%{xctest_checker}', '%%{python} %s' % xctest_checker))

# Add Python to run xctest_checker.py tests as part of XCTest tests
config.substitutions.append( ('%{python}', sys.executable) )
