#!/usr/bin/env python

# This tool dumps imported Swift APIs to help validate changes in the
# projection of (Objective-)C APIs into Swift, which is a function of the
# (Objective-)C APIs, any API notes added on top of those APIs, and the
# Clang importer itself. 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 compatibility mode:
#
#   /path/to/bin/dir/swift-api-dump.py -swift-version 3 -o output-dir \
#       -m UIKit -s iphoneos
#
# 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 macOS, iOS, watchOS, and tvOS,
# in Swift 4, use:
#
#  /path/to/bin/dir/swift-api-dump.py -swift-version 4 -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('-iframework', '--system-framework-dir',
                        action='append',
                        help='Add additional system 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.')
    parser.add_argument('-swift-version', type=int, metavar='N',
                        help='the Swift version to use')
    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 'macOS'
    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 get_short_sdk_name(sdk):
    matched = re.match("[a-zA-Z]+", sdk)
    return matched.group(0)


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)

    # Figure out the "short" name of the SDK
    short_sdk_name = get_short_sdk_name(sdk)

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

    # Determine the output idirectory
    pretty_sdk = pretty_sdk_name(short_sdk_name)
    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',
        '-skip-overrides'
    ]

    # Add -F / -iframework / -I arguments.
    if args.framework_dir:
        for path in args.framework_dir:
            cmd_common = cmd_common + ['-F', path]
    if args.system_framework_dir:
        for path in args.system_framework_dir:
            cmd_common = cmd_common + ['-iframework', 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']
    if args.swift_version:
        extra_args = extra_args + ['-swift-version', '%d' % args.swift_version]

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