#!/usr/bin/env python3
##===----------------------------------------------------------------------===##
##
## This source file is part of the Swift open source project
##
## Copyright (c) 2014-2019 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 argparse
import os
import subprocess
import platform
from helpers import note, error, symlink_force, mkdir_p, call, call_output

def main():
    parser = argparse.ArgumentParser(description="""
        This script runs the automated tests located in IntegrationTests against a toolchain to validate it behaves
        correctly.
        """)

    parser.add_argument(
        "--toolchain-path",
        help="path to the toolchain to test",
        metavar="PATH")
    parser.add_argument(
        "--swift-path",
        help="path to the Swift main executable to use for tests",
        metavar="PATH")
    parser.add_argument(
        "--swiftc-path",
        help="path to the Swift compiler to use for tests",
        metavar="PATH")
    parser.add_argument(
        "--lldb-path",
        help="path to the LLDB binary to use for tests",
        metavar="PATH")
    parser.add_argument(
        "--swiftpm-bin-dir",
        help="path to the SwiftPM binary directory to get SwiftPM executables from",
        metavar="PATH")
    parser.add_argument(
        "--filter",
        help="filter which tests to run",
        metavar="PATH")
    parser.add_argument(
        "-v", "--verbose",
        action="store_true",
        help="whether to print verbose output")

    args = parser.parse_args()
    clean_args(args)
    test(args)

def clean_args(args):
    """Parses and cleans arguments."""
    args.project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    # On Darwin, always push SDKROOT in the environment.
    if platform.system() == "Darwin":
        args.sdk_root = call_output(["xcrun", "--sdk", "macosx", "--show-sdk-path"])

    # Get the toolchain path.
    if args.toolchain_path is None:
        # If a package wasn't provided, use the current selected toolchain on Darwin.
        if platform.system() == "Darwin":
            swiftc_path = call_output(["xcrun", "--find", "swift"])
            args.toolchain_path = os.path.join(swiftc_path, "../../../")
    if args.toolchain_path is None:
        error("'--package-path=PATH' is required")
    args.toolchain_path = os.path.abspath(args.toolchain_path)

    # Find the tools we need.

    if args.swift_path:
        args.swift_path = os.path.abspath(args.swift_path)
    else:
        args.swift_path = os.path.join(args.toolchain_path, "usr", "bin", "swift")
    note("testing using 'swift': %s" % args.swift_path)

    if args.swiftc_path:
        args.swiftc_path = os.path.abspath(args.swiftc_path)
    if args.lldb_path:
        args.lldb_path = os.path.abspath(args.lldb_path)

    # Add substitutions for swiftpm executables.

    if args.swiftpm_bin_dir:
        args.swiftpm_bin_dir = os.path.abspath(args.swiftpm_bin_dir)
        note("testing using swiftpm binary directory: %s" % args.swiftpm_bin_dir)
        args.swift_test_path = os.path.join(args.swiftpm_bin_dir, "swift-test")
    else:
        args.swift_test_path = args.swift_path + '-test'

def test(args):
    cmd = ["env"]
    for key, value in get_env(args).items():
        if " " in value:
            error("Can't set environment variable %s as it contains a space: %s" % (key, value))
        else:
            cmd += ['%s=%s' % (key,value)]

    integration_test_dir = os.path.join(args.project_root, "IntegrationTests")
    cmd += [
        args.swift_test_path,
        "--package-path", integration_test_dir,
        "--parallel"
    ]

    if args.filter:
        cmd += ["--filter", args.filter]

    call(cmd, cwd=args.project_root, verbose=True)

def get_env(args):
    env = {
        "SWIFT_PATH": args.swift_path,
    }

    if args.sdk_root:
        env['SDKROOT'] = args.sdk_root
    if args.swiftc_path:
        env['SWIFTC_PATH'] = args.swiftc_path
    if args.lldb_path:
        env['LLDB_PATH'] = args.lldb_path
    if args.swiftpm_bin_dir:
        env["SWIFTPM_BIN_DIR"] = args.swiftpm_bin_dir

    return env

if __name__ == '__main__':
    main()
