#!/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 - 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

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())
