#!/usr/bin/env python3
#
# Copyright (C) 2014-2020 Apple Inc.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import errno
import os
import pathlib
import re
import shutil
import subprocess
import sys
import tempfile

from xml.etree import ElementTree as ET

# We always want the real system version
os.environ['SYSTEM_VERSION_COMPAT'] = '0'

MISSING_HEADERS = [
    "usr/include/libxslt",
    "usr/include/mach/mach.h",
    "usr/include/mach/mach_error.h",
    "usr/include/mach/mach_types.defs",
    "usr/include/mach/machine/machine_types.defs",
    "usr/include/mach/std_types.defs",
    "usr/include/mach/task.h",
    "usr/include/objc/Protocol.h",
    "usr/include/objc/objc-class.h",
    "usr/include/objc/objc-runtime.h",
    "usr/include/readline/history.h",
    "usr/include/readline/readline.h",
]

MISSING_FRAMEWORKS = [
    ("AVKit.framework", True),
    ("AudioToolbox.framework", True),
    ("AudioUnit.framework", False),
    ("CFNetwork.framework", True),
    ("CoreImage.framework", False),
    ("IOKit.framework", True),
    ("IOSurface.framework", True),
    ("LocalAuthentication.framework", False),
    ("MediaAccessibility.framework", True),
    ("MediaToolbox.framework", False),
    ("Metal.framework", True),
    ("OpenGLES.framework", True),
    ("QuartzCore.framework", True),
    ("UIKit.framework", True),
    ("VideoToolbox.framework", False),
]

xcode_version = subprocess.run(['/usr/bin/xcodebuild', '-version'], capture_output=True, encoding='ascii').stdout.splitlines()[0].split(' ')[1]
if tuple(int(n) for n in xcode_version.split('.')) >= (13, 3):
    mac_xcspec_location = f'Platforms/MacOSX.platform/Developer/Library/Xcode/PrivatePlugIns/IDEOSXSupportCore.xcplugindata/Contents/Resources'
elif int(xcode_version.split('.')[0]) >= 12:
    mac_xcspec_location = f'Platforms/MacOSX.platform/Developer/Library/Xcode/PrivatePlugIns/IDEOSXSupportCore.ideplugin/Contents/Resources'
else:
    mac_xcspec_location = 'Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications'

ideplugin = 'XCBSpecifications' if tuple(int(n) for n in xcode_version.split('.')) >= (13, 3) else 'IDEiOSSupportCore'

XCSPEC_INFO = [dict(
    id='com.apple.product-type.tool',
    dest=f'../PlugIns/{ideplugin}.ideplugin/Contents/Resources/Embedded-Shared.xcspec',
    content='''
    // Tool (normal Unix command-line executable)
    {   Type = ProductType;
        Identifier = com.apple.product-type.tool;
        Class = PBXToolProductType;
        Name = "Command-line Tool";
        Description = "Standalone command-line tool";
        IconNamePrefix = "TargetExecutable";
        DefaultTargetName = "Command-line Tool";
        DefaultBuildProperties = {
            FULL_PRODUCT_NAME = "$(EXECUTABLE_NAME)";
            MACH_O_TYPE = "mh_execute";
            EXECUTABLE_PREFIX = "";
            EXECUTABLE_SUFFIX = "";
            REZ_EXECUTABLE = YES;
            INSTALL_PATH = "/usr/local/bin";
            FRAMEWORK_FLAG_PREFIX = "-framework";
            LIBRARY_FLAG_PREFIX = "-l";
            LIBRARY_FLAG_NOSPACE = YES;
            GCC_DYNAMIC_NO_PIC = NO;
            GCC_SYMBOLS_PRIVATE_EXTERN = YES;
            GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
            STRIP_STYLE = "all";
            CODE_SIGNING_ALLOWED = YES;
        };
        PackageTypes = (
            com.apple.package-type.mach-o-executable   // default
        );
        WantsSigningEditing = YES;
        WantsBundleIdentifierEditing = YES;
    }
''',
), dict(
    id='com.apple.package-type.mach-o-executable',
    dest=f'../PlugIns/{ideplugin}.ideplugin/Contents/Resources/Embedded-Shared.xcspec',
    content='''
    {   Type = PackageType;
        Identifier = com.apple.package-type.mach-o-executable;
        Name = "Mach-O Executable";
        Description = "Mach-O executable";
        DefaultBuildSettings = {
            EXECUTABLE_PREFIX = "";
            EXECUTABLE_SUFFIX = "";
            EXECUTABLE_NAME = "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)";
            EXECUTABLE_PATH = "$(EXECUTABLE_NAME)";
        };
        ProductReference = {
            FileType = compiled.mach-o.executable;
            Name = "$(EXECUTABLE_NAME)";
            IsLaunchable = YES;
        };
    }
''',
)]

AVAILABILITY_FILE = pathlib.Path("usr/local/include/AvailabilityProhibitedInternal.h")
AVAILABILTY_TEXT = """\
// Handle __IOS_PROHIBITED and friends.
#undef __OS_AVAILABILITY
#define __OS_AVAILABILITY(...)

// Take care of {A,S}PI_AVAILABLE{,_BEGIN,_END}
#undef __API_AVAILABLE_GET_MACRO
#define __API_AVAILABLE_GET_MACRO(...) __NULL_AVAILABILITY

#undef SWIFT_AVAILABILITY
#define SWIFT_AVAILABILITY __NULL_AVAILABILITY

// Take care of {A,S}PI_DEPRECATED{,WITH_REPLACEMENT}{,_BEGIN,_END}
#undef __API_DEPRECATED_MSG_GET_MACRO
#define __API_DEPRECATED_MSG_GET_MACRO(...) __NULL_AVAILABILITY

// Take care of API_UNAVAILABLE{,_BEGIN,_END}
#undef __API_UNAVAILABLE_GET_MACRO
#define __API_UNAVAILABLE_GET_MACRO(...) __NULL_AVAILABILITY

#define __NULL_AVAILABILITY(...)
"""

SDKS_TO_UPDATE = [
    "iphoneos",
    "iphonesimulator",
    "appletvos",
    "appletvsimulator",
    "watchos",
    "watchsimulator",
]

PLIST_BUDDY_PATH = pathlib.Path("/usr/libexec/PlistBuddy")


def xcode_developer_dir():
    result = subprocess.run(
        ["xcode-select", "-p"],
        capture_output=True, encoding="utf-8", check=True,
    )
    return pathlib.Path(result.stdout.strip())


def sdk_directory(sdk):
    result = subprocess.run(
        ["xcrun", "--sdk", sdk, "--show-sdk-path"],
        capture_output=True, encoding="utf-8", check=True,
    )
    return pathlib.Path(result.stdout.strip())


def get_and_check_sdk_directories(source_sdk, dest_sdk):
    source_sdk_path = sdk_directory(source_sdk)
    dest_sdk_path = sdk_directory(dest_sdk)

    if not source_sdk_path:
        raise RuntimeError(f"Could not find SDK: {source_sdk}")

    if not dest_sdk_path:
        raise RuntimeError(f"Could not find SDK: {dest_sdk}")

    print(source_sdk_path)
    print(dest_sdk_path)
    return source_sdk_path, dest_sdk_path


def do_copy(source_path, dest_path):

    def ensure_parent_exists(path):
        os.makedirs(path.parent, exist_ok=True)

    def copy_file(source_path, dest_path):
        print(f"Copying file")
        print(f"From: {source_path}")
        print(f"To:   {dest_path}")
        if dest_path.exists():
            dest_path.unlink()
        ensure_parent_exists(dest_path)
        shutil.copy2(source_path, dest_path)

    def copy_directory(source_path, dest_path):
        print(f"Copying directory")
        print(f"From: {source_path}")
        print(f"To:   {dest_path}")
        if dest_path.exists():
            shutil.rmtree(dest_path)
        ensure_parent_exists(dest_path)
        shutil.copytree(source_path, dest_path)

    if source_path.is_file():
        copy_file(source_path, dest_path)
        return

    if source_path.is_dir():
        copy_directory(source_path, dest_path)
        return

    raise RuntimeError(f"{source_path} does not exist")


# .tbd files contain information about how to link a product to a
# library/framework. This information includes the architecture that the
# library is built for. If we're copying from an SDK that supports one set of
# architectures to an SDK that supports another set of architectures, we need
# to adjust that information in the .tbd file.
#
# Note that we don't need to be too particular about this. We only need to
# link; we don't need to run. This allows us to simply specify the full set of
# architectures for which WebKit is built, regardless of whether the associated
# library/framework was actually built for all those architectures.

def patch_tbd_architecture(framework_path):
    for tbd_path in framework_path.glob("*.tbd"):
        with open(tbd_path, "r") as f:
            lines = f.readlines()

        modified_lines = []
        for line in lines:
            if re.match(".*(archs|targets): +\[.*\]", line) is not None:
                line = re.sub("\[.*\]", "[ i386, x86_64, arm64, arm64e, arm64_32, armv7k ]", line)
            modified_lines.append(line)

        with open(tbd_path, "w") as f:
            f.writelines(modified_lines)


# Xcode is driven by .xcspec files. These describe many aspects of the system,
# including what to build and how to build it. These .xcspec files can be
# global or they can be platform- or SDK-specific. In the case of building
# products for the embedded systems, there is some information in some macOS
# .xcspec files that need to be transferred to the embedded platforms. This
# function finds that information, extracts it from the macOS files, and copies
# it to the embedded files.

def update_xcspec_files():
    for spec_info in XCSPEC_INFO:
        dest_spec_path = xcode_developer_dir() / spec_info['dest']
        if not dest_spec_path.exists():
            raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), dest_spec_path)

        result = subprocess.run(
            [PLIST_BUDDY_PATH, '-x', '-c', 'Print', dest_spec_path],
            capture_output=True, encoding='utf-8', check=True,
        )
        if result.returncode != 0:
            raise OSError(f'Failed to convert {dest_spec_path} to XML')

        found = False
        for topLevel in ET.fromstring(result.stdout.strip()):
            for element in topLevel:
                for key in element:
                    if key.tag == 'string' and key.text == spec_info['id']:
                        found = True
                        break
                if found:
                    break
            if found:
                break
        if found:
            print(f'{spec_info["id"]} alread in {dest_spec_path}')
            continue

        with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8") as temp:
            temp.write(spec_info['content'])
            temp.flush()

            print(f'Inserting:  {spec_info["id"]}')
            print(f'To:         {dest_spec_path}')
            subprocess.run([PLIST_BUDDY_PATH, '-c', 'add 0 dict', dest_spec_path], capture_output=True, check=True)
            subprocess.run([PLIST_BUDDY_PATH, '-c', f'merge {temp.name} 0', dest_spec_path], capture_output=True, check=True)


def copy_missing_headers(source_sdk, dest_sdk):
    if source_sdk == dest_sdk:
        return
    source_sdk_path, dest_sdk_path = get_and_check_sdk_directories(source_sdk, dest_sdk)
    for missing_header in MISSING_HEADERS:
        do_copy(source_sdk_path / missing_header, dest_sdk_path / missing_header)


def copy_missing_frameworks(source_sdk, dest_sdk):
    if source_sdk == dest_sdk:
        return
    source_sdk_path, dest_sdk_path = get_and_check_sdk_directories(source_sdk, dest_sdk)
    source_frameworks_path = source_sdk_path / "System" / "Library" / "Frameworks"
    dest_frameworks_path = dest_sdk_path / "System" / "Library" / "Frameworks"
    for missing_framework, force in MISSING_FRAMEWORKS:
        source_framework_path = source_frameworks_path / missing_framework
        dest_framework_path = dest_frameworks_path / missing_framework
        if force or not dest_framework_path.exists():
            do_copy(source_framework_path, dest_framework_path)
            patch_tbd_architecture(dest_framework_path)


# Some functions that WebKit needs to call are marked as "unavailable" on the
# embedded platforms. Create a stub header that will nullify the effect of the
# annotations on those functions. Note that there's no guarantee that the
# resulting product can run -- we just want to build.

def create_availability_header(sdk):
    sdk_path = sdk_directory(sdk)
    availability_header_path = sdk_path / AVAILABILITY_FILE
    print(f"Creating/updating {availability_header_path}")
    os.makedirs(availability_header_path.parent, exist_ok=True)
    with open(availability_header_path, "w") as f:
        f.write(AVAILABILTY_TEXT)


def main():
    if not os.geteuid() == 0 and not os.access(xcode_developer_dir(), os.R_OK | os.W_OK | os.X_OK, effective_ids=True):
        raise RuntimeError(f"{__file__} must be run as root")

    update_xcspec_files()

    for sdk in SDKS_TO_UPDATE:
        copy_missing_headers("macosx", sdk)
        copy_missing_frameworks("iphoneos", sdk)
        create_availability_header(sdk)
    return 0


if __name__ == "__main__":
    main()
