#!/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')
    parser.add_argument('-show-overlay', action='store_true',
                        help='Show overlay API in addition to Objective-C ' +
                        'module API')
    parser.add_argument('-show-doc-comments', action='store_true',
                        help='Show documentation comments')
    parser.add_argument('-show-unavailable', action='store_true',
                        help='Show declarations that are unavailable in Swift')
    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,
        '-skip-overrides'
    ]

    # Add -module-print-skip-overlay
    if not args.show_overlay:
        cmd_common += ['-module-print-skip-overlay']

    # Add -skip-print-doc-comments
    if not args.show_doc_comments:
        cmd_common += ['-skip-print-doc-comments']

    # Add -skip-unavailable
    if not args.show_unavailable:
        cmd_common += ['-skip-unavailable']

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