#!/usr/bin/env python
# utils/sil-opt-verify-all-modules.py - Verifies Swift modules -*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors

from __future__ import print_function

import argparse
import glob
import multiprocessing
import os
import pipes
import subprocess
import sys
import tempfile


def get_verify_toolchain_modules_commands(toolchain_dir, sil_opt):
    if sil_opt is None:
        sil_opt = os.path.join(toolchain_dir, 'usr', 'bin', 'sil-opt')

    toolchain_basename = os.path.basename(toolchain_dir)
    if toolchain_basename.startswith('Legacy'):
        return []
    if toolchain_basename.startswith('XcodeDefault'):
        toolchain_name = 'XcodeDefault'
    if toolchain_basename.startswith('tvOS'):
        toolchain_name = 'tvOS'
    if toolchain_basename.startswith('OSX'):
        toolchain_name = 'OSX'
    if toolchain_basename.startswith('watchOS'):
        toolchain_name = 'watchOS'
    if toolchain_basename.startswith('iOS'):
        toolchain_name = 'iOS'

    return get_verify_resource_dir_modules_commands(
        os.path.join(toolchain_dir, 'usr', 'lib', 'swift'),
        os.path.join(toolchain_dir, 'usr', 'bin', 'sil-opt'),
        toolchain_name)


def get_verify_build_dir_commands(build_dir, toolchain_name='XcodeDefault'):
    return get_verify_resource_dir_modules_commands(
        os.path.join(build_dir, 'lib', 'swift'),
        os.path.join(build_dir, 'bin', 'sil-opt'),
        toolchain_name)


def get_verify_resource_dir_modules_commands(
        resource_dir, sil_opt, toolchain_name):
    print("================================================================")
    print("Resource dir: " + resource_dir)
    print("sil-opt path: " + sil_opt)

    known_platforms = [
        ('appletvos', 'arm64', 'arm64-apple-tvos9.0'),
        ('appletvsimulator', 'x86_64', 'x86_64-apple-tvos9.0'),
        ('iphoneos', 'armv7', 'armv7-apple-ios7.0'),
        ('iphoneos', 'armv7s', 'armv7s-apple-ios7.0'),
        ('iphoneos', 'arm64', 'arm64-apple-ios7.0'),
        ('iphonesimulator', 'i386', 'i386-apple-ios7.0'),
        ('iphonesimulator', 'x86_64', 'x86_64-apple-ios7.0'),
        ('macosx', 'x86_64', 'x86_64-apple-macosx10.9'),
        ('watchos', 'armv7k', 'armv7k-apple-watchos2.0'),
        ('watchsimulator', 'i386', 'i386-apple-watchos2.0'),
    ]

    commands = []
    module_cache_dir = tempfile.mkdtemp(
        prefix="swift-testsuite-clang-module-cache")
    for (subdir, arch, triple) in known_platforms:
        modules_dir = os.path.join(resource_dir, subdir, arch)
        print(modules_dir)
        modules = glob.glob(os.path.join(modules_dir, '*.swiftmodule'))
        for module_file_name in modules:
            if module_file_name.endswith('XCTest.swiftmodule'):
                # FIXME: sil-opt does not have the '-F' option.
                continue
            commands.append([
                'xcrun', '--toolchain', toolchain_name, '--sdk', subdir,
                sil_opt,
                '-target', triple,
                '-resource-dir', resource_dir,
                '-module-cache-path', module_cache_dir,
                '-verify',
                module_file_name,
            ])

    return commands


def quote_shell_command(args):
    return " ".join([pipes.quote(a) for a in args])


def run_commands_in_parallel(commands):
    makefile = ".DEFAULT_GOAL := all\n"
    targets = []
    for c in commands:
        target_name = "target" + str(len(targets))
        targets.append(target_name)
        makefile += target_name + ":\n"
        makefile += \
            "\t" + quote_shell_command(c) + \
            " > {target}.stdout\n".format(target=target_name)

    makefile += "all: " + " ".join(targets) + "\n"

    temp_dir = tempfile.mkdtemp(prefix="swift-testsuite-main")
    with open(os.path.join(temp_dir, 'Makefile'), 'w') as makefile_file:
        makefile_file.write(makefile)

    max_processes = multiprocessing.cpu_count()
    subprocess.check_call([
        'make',
        '-C', temp_dir,
        '-j', str(max_processes),
        '--keep-going'
    ])


def main():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="""Verifies Swift modules.""")
    parser.add_argument(
        "--sil-opt",
        help="use the specified 'sil-opt' binary",
        metavar="PATH")
    parser.add_argument(
        "--verify-build-dir",
        help="verify the Swift resource directory under the given build dir.",
        metavar="PATH")
    parser.add_argument(
        "--verify-xcode",
        help="verify the Xcode.app that is currently xcode-select'ed",
        action="store_true")
    args = parser.parse_args()

    if args.verify_build_dir is not None and args.verify_xcode:
        print("--verify-build-dir and --verify-xcode can't be used together")
        return 1

    if args.verify_build_dir is not None:
        commands = get_verify_build_dir_commands(args.verify_build_dir)

    if args.verify_xcode:
        # Find Xcode.
        swift_path = subprocess.check_output(['xcrun', '--find', 'swift'])
        xcode_path = swift_path
        for _ in range(0, 7):
            xcode_path = os.path.dirname(xcode_path)

        toolchains_dir = os.path.join(
            xcode_path, 'Contents', 'Developer', 'Toolchains')
        toolchains = glob.glob(os.path.join(toolchains_dir, '*.xctoolchain'))

        commands = []
        for toolchain_dir in toolchains:
            commands += get_verify_toolchain_modules_commands(
                toolchain_dir, args.sil_opt)

    run_commands_in_parallel(commands)

    return 0


if __name__ == "__main__":
    sys.exit(main())
