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

MISSING_HEADERS = [
    "usr/include/libxslt",
    "usr/include/mach/mach_types.defs",
    "usr/include/mach/machine/machine_types.defs",
    "usr/include/mach/std_types.defs",
    "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", False),
    ("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),
]

XCSPEC_INFO = [
    {
        "id":       "com.apple.package-type.mach-o-executable",
        "source":   "Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications/MacOSX Package Types.xcspec",
        "dest":     "../PlugIns/IDEiOSSupportCore.ideplugin/Contents/Resources/Embedded-Shared.xcspec"
    },
    {
        "id":       "com.apple.product-type.tool",
        "source":   "Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications/MacOSX Product Types.xcspec",
        "dest":     "../PlugIns/IDEiOSSupportCore.ideplugin/Contents/Resources/Embedded-Shared.xcspec"
    },
]

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

// 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: +\[.*\]", 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():

    def read_spec(spec_path):
        """Read a .xcspec file and return its contents as an XML DOM object."""

        result = subprocess.run(
            [PLIST_BUDDY_PATH, "-x", "-c", "Print", spec_path],
            capture_output=True, encoding="utf-8", check=True,
        )
        return ET.fromstring(result.stdout.strip())

    def find_spec_entry_index(spec, identifier):
        """Given an XML DOM object representing an .xcspec file, look for an
        entry that has a key of "Identifier" and a value equal to the given
        value. If found, return its index in the array of such entries."""

        for index, spec_entry in enumerate(spec.findall("./array/dict")):
            spec_entry_iter = iter(spec_entry)
            for key, value in zip(spec_entry_iter, spec_entry_iter):
                if key.tag == "key" and key.text == "Identifier" and value.tag == "string" and value.text == identifier:
                    return index
        return None

    for spec_info in XCSPEC_INFO:
        identifier = spec_info["id"]
        source_spec_path = xcode_developer_dir() / spec_info["source"]
        dest_spec_path = xcode_developer_dir() / spec_info["dest"]

        for path in [source_spec_path, dest_spec_path]:
            if not path.exists():
                raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), path)

        source_spec_entry_index = find_spec_entry_index(read_spec(source_spec_path), identifier)
        dest_spec_entry_index = find_spec_entry_index(read_spec(dest_spec_path), identifier)

        if source_spec_entry_index is None:
            raise RuntimeError(f"Unable to find xcspec entry for {identifier} in {source_spec_path}")

        if dest_spec_entry_index is not None:
            print(f"xcspec entry for {identifier} already exists in {dest_spec_path}, skipping")
            return

        result = subprocess.run(
            [PLIST_BUDDY_PATH, "-x", "-c", f"Print {source_spec_entry_index}", source_spec_path],
            capture_output=True, encoding="utf-8", check=True,
        )
        spec_as_xml_snippet = result.stdout.strip()

        with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8") as temp:
            temp.write(spec_as_xml_snippet)
            temp.flush() # It's amazing how important this line is.
            if not dest_spec_path.exists():
                print(f"Creating: {dest_spec_path}")
                subprocess.run([PLIST_BUDDY_PATH, "-c", "clear array", dest_spec_path], capture_output=True, check=True)
            print(f"Copying:  {identifier}")
            print(f"From:     {source_spec_path}")
            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()
