# 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',
    '-Xlinker', '-rpath',
    '-Xlinker', built_products_dir,
    '-L', built_products_dir,
    '-I', built_products_dir,
    '-I', os.path.join(built_products_dir, 'swift'),
]

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:
    # On Linux, 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')
    swift_exec.extend([
        '-Xlinker', '-rpath',
        '-Xlinker', foundation_dir,
        '-L', foundation_dir,
        '-I', foundation_dir,
        '-I', os.path.join(foundation_dir, 'swift'),
        '-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}', xctest_checker))

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