#!/usr/bin/env python

# This tool dumps imported Swift APIs to help validate changes in the
# Clang importer and its heuristics. One can execute it to dump the
# API of a given module within a particular SDK, e.g., UIKit from the
# iOS SDK as seen in Swift 3 after the "grand renaming":
#
#   /path/to/bin/dir/swift-api-dump.py -3 -o output-dir -m UIKit -s iphoneos
#
# The -3 argument indicates that we're using the Swift 3 Clang
# importer rules. The "-m" argument can be omitted, in which case the
# script will collect all of the frameworks in the named SDK(s) and
# dump their APIs.
#
# One can supply multiple SDKs, written as a list. For example, to
# dump the API for all frameworks across OS X, iOS, watchOS, and tvOS,
# with the Swift 3 rules, use:
#
#  /path/to/bin/dir/swift-api-dump.py -3 -o output-dir -s macosx iphoneos \
#      watchos appletvos
#

from __future__ import print_function

import argparse
import multiprocessing
import os
import re
import subprocess
import sys

DEFAULT_TARGET_BASED_ON_SDK = {
    'macosx': 'x86_64-apple-macosx10.11',
    'iphoneos': 'arm64-apple-ios9.0',
    'iphonesimulator': 'x86_64-apple-ios9.0',
    'watchos': 'armv7k-apple-watchos2.0',
    'watchos.simulator': 'i386-apple-watchos2.0',
    'appletvos': 'arm64-apple-tvos9',
    'appletvos.simulator': 'x86_64-apple-tvos9',
}

SKIPPED_FRAMEWORKS = {
    'AppKitScripting',
    'CalendarStore',
    'CoreMIDIServer',
    'DrawSprocket',
    'DVComponentGlue',
    'InstallerPlugins',
    'InstantMessage',
    'JavaFrameEmbedding',
    'JavaVM',
    'Kerberos',
    'Kernel',
    'LDAP',
    'Message',
    'PCSC',
    'PubSub',
    'QTKit',
    'QuickTime',
    'Ruby',
    'Scripting',
    'SyncServices',
    'System',
    'Tk',
    'VideoDecodeAcceleration',
    'vecLib',
}


def create_parser():
    script_path = os.path.dirname(sys.argv[0])
    script_path = os.path.abspath(script_path)
    default_swift_ide_test = '%s/swift-ide-test' % (script_path)

    parser = argparse.ArgumentParser(
        description="Dumps imported Swift APIs for a module or SDK",
        prog='swift-api-dump.py',
        usage='%(prog)s -s iphoneos')
    parser.add_argument('-m', '--module', help='The module name.')
    parser.add_argument('-j', '--jobs', type=int,
                        help='The number of parallel jobs to execute')
    parser.add_argument('-s', '--sdk', nargs='+',
                        required=True, help="The SDKs to use.")
    parser.add_argument('-t', '--target', help="The target triple to use.")
    parser.add_argument('-i', '--swift-ide-test',
                        default=default_swift_ide_test,
                        help="The swift-ide-test executable.")
    parser.add_argument('-o', '--output-dir', default=os.getcwd(),
                        help='Directory to which the output will be emitted.')
    parser.add_argument('-q', '--quiet', action='store_true',
                        help='Suppress printing of status messages.')
    parser.add_argument('-v', '--verbose', action='store_true',
                        help='Print extra information.')
    parser.add_argument('-F', '--framework-dir', action='append',
                        help='Add additional framework directories')
    parser.add_argument('-I', '--include-dir', action='append',
                        help='Add additional include directories')
    parser.add_argument('--enable-infer-import-as-member', action='store_true',
                        help='Infer when a global could be imported as a ' +
                        'member.')
    return parser


def output_command_result_to_file(command_args, filename):
    with open(filename, 'w') as output_file:
        subprocess.call(command_args, stdout=output_file)


def run_command(args):
    proc = subprocess.Popen(
        args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = proc.communicate()
    exitcode = proc.returncode
    return (exitcode, out, err)

# Collect the set of submodules for the given module.


def collect_submodules(common_args, module):
    # Execute swift-ide-test to print the interface.
    my_args = ['-module-print-submodules', '-module-to-print=%s' % (module)]
    (exitcode, out, _) = run_command(common_args + my_args)
    if exitcode != 0:
        print(
            'error: submodule collection failed for module %s with error %d' %
            (module, exitcode))
        return ()

    # Find all of the submodule imports.
    import_matcher = re.compile(r'.*import\s+%s\.([A-Za-z_0-9.]+)' % (module))
    submodules = set()
    for line in out.splitlines():
        match = import_matcher.match(line)
        if match:
            submodules.add(match.group(1))

    return sorted(list(submodules))

# Print out the command we're about to execute


def print_command(cmd, outfile=""):
    retstr = " ".join(cmd)
    if outfile != "":
        retstr += " > " + outfile
    print(retstr)

# Dump the API for the given module.


def dump_module_api((cmd, extra_dump_args, output_dir, module, quiet,
                     verbose)):
    # Collect the submodules
    submodules = collect_submodules(cmd, module)

    # Dump the top-level module
    if verbose:
        print("mkdir -p %s/%s" % (output_dir, module))
    subprocess.call(['mkdir', '-p', ('%s/%s' % (output_dir, module))])
    output_file = '%s/%s/%s.swift' % (output_dir, module, module)
    if not quiet:
        print('Writing %s...' % output_file)

    top_level_cmd = cmd + extra_dump_args + ['-module-to-print=%s' % (module)]
    if verbose:
        print_command(top_level_cmd, output_file)

    output_command_result_to_file(top_level_cmd, output_file)

    # Dump each submodule.
    for submodule in submodules:
        output_file = '%s/%s/%s.swift' % (output_dir, module, submodule)
        if not quiet:
            print('Writing %s...' % output_file)

        full_submodule = '%s.%s' % (module, submodule)
        submodule_cmd = cmd + extra_dump_args
        submodule_cmd = submodule_cmd + \
            ['-module-to-print=%s' % (full_submodule)]
        if verbose:
            print_command(submodule_cmd, output_file)

        output_command_result_to_file(submodule_cmd, output_file)

    return


def pretty_sdk_name(sdk):
    if sdk.find("macosx") == 0:
        return 'OSX'
    if sdk.find("iphoneos") == 0:
        return 'iOS'
    if sdk.find("watchos") == 0:
        return 'watchOS'
    if sdk.find("appletvos") == 0:
        return 'tvOS'
    return 'unknownOS'

# Collect the set of frameworks we should dump


def collect_frameworks(sdk):
    (exitcode, sdk_path, _) = run_command(
        ["xcrun", "--show-sdk-path", "-sdk", sdk])
    if exitcode != 0:
        print('error: framework collection failed to find SDK path for %s '
              'with error %d' % (sdk, exitcode))
        return ()
    sdk_path = sdk_path.rstrip()

    (exitcode, sdk_version, _) = run_command(
        ["xcrun", "--show-sdk-version", "-sdk", sdk])
    if exitcode != 0:
        print('error: framework collection failed to find SDK version for %s '
              'with error %d' % (sdk, exitcode))
        return ()
    sdk_version = sdk_version.rstrip()

    print('Collecting frameworks from %s %s at %s' %
          (pretty_sdk_name(sdk), sdk_version, sdk_path))

    # Collect all of the framework names
    frameworks_dir = '%s/System/Library/Frameworks' % sdk_path
    framework_matcher = re.compile(r'([A-Za-z_0-9.]+)\.framework')
    frameworks = set()
    for entry in os.listdir(frameworks_dir):
        match = framework_matcher.match(entry)
        if match:
            framework = match.group(1)
            if framework not in SKIPPED_FRAMEWORKS:
                frameworks.add(framework)

    return (sorted(list(frameworks)), sdk_path)


def create_dump_module_api_args(cmd_common, cmd_extra_args, sdk, module,
                                target, output_dir, quiet, verbose):

    # Determine the SDK root and collect the set of frameworks.
    (frameworks, sdk_root) = collect_frameworks(sdk)

    # Determine the default target.
    if target:
        sdk_target = target
    else:
        sdk_target = DEFAULT_TARGET_BASED_ON_SDK[sdk]

    # Determine the output idirectory
    pretty_sdk = pretty_sdk_name(sdk)
    sdk_output_dir = '%s/%s' % (output_dir, pretty_sdk)

    # Create the sets of arguments to dump_module_api.
    results = []
    cmd = cmd_common + ['-sdk', sdk_root, '-target', sdk_target]
    if module:
        results.append(
            (cmd, cmd_extra_args, sdk_output_dir, module, quiet, verbose))
    else:
        for framework in frameworks:
            results.append(
                (cmd, cmd_extra_args, sdk_output_dir, framework, quiet,
                 verbose))

    return results


def main():
    source_filename = 'swift-api-dump.swift'
    parser = create_parser()
    args = parser.parse_args()

    cmd_common = [
        args.swift_ide_test,
        '-print-module',
        '-source-filename',
        source_filename,
        '-module-print-skip-overlay',
        '-skip-unavailable',
        '-skip-print-doc-comments',
        '-always-argument-labels',
        '-skip-overrides'
    ]

    # Add -F / -I arguments.
    if args.framework_dir:
        for path in args.framework_dir:
            cmd_common = cmd_common + ['-F', path]
    if args.include_dir:
        for path in args.include_dir:
            cmd_common = cmd_common + ['-I', path]

    # Determine the set of extra arguments we'll use.
    extra_args = ['-skip-imports']
    if args.enable_infer_import_as_member:
        extra_args = extra_args + ['-enable-infer-import-as-member']
    # Create a .swift file we can feed into swift-ide-test
    subprocess.call(['touch', source_filename])

    # Construct the set of API dumps we should perform.
    jobs = []
    for sdk in args.sdk:
        jobs = jobs + create_dump_module_api_args(
            cmd_common, extra_args, sdk, args.module,
            args.target, args.output_dir,
            args.quiet, args.verbose)

    # Execute the API dumps
    pool = multiprocessing.Pool(processes=args.jobs)
    pool.map(dump_module_api, jobs)

    # Remove the .swift file we fed into swift-ide-test
    subprocess.call(['rm', '-f', source_filename])

if __name__ == '__main__':
    main()
