#!/usr/bin/perl -w

# Copyright (C) 2014, 2015 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. AND ITS CONTRIBUTORS ``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 ITS 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.

# Checks if Xcode supports building a command line tool for the iOS Simulator.
# If not, then updates/creates xcspec files in the iOS SDK for a command line
# tool product- and package- type using the definitions in the OS X SDK for the
# same types.

use strict;
use warnings;

use Cwd qw(realpath);
use English;
use File::Basename;
use File::Find;
use File::Spec;
use File::Temp qw(tempfile);
use FindBin;
use lib $FindBin::Bin;
use webkitdirs;

sub copyMissingHeadersToIPhoneOSSDKIfNeeded();
sub copyMissingXSLTHeadersToSDKIfNeeded($);
sub createLegacyXcodeSpecificationFilesForSDKIfNeeded($);
sub mergeXcodeSpecificationWithSpecificationAndId($$$);
sub readXcodeSpecificationById($$);
sub sdkDirectory($);
sub sdkPlatformDirectory($);
sub updateXcode7SpecificationFile($);
sub updateXcodeSpecificationFilesForSDKIfNeeded($);
sub xcodeSDKSpecificationsPath($);

use constant COMMAND_LINE_PACKAGE_TYPE => "com.apple.package-type.mach-o-executable";
use constant COMMAND_LINE_PRODUCT_TYPE => "com.apple.product-type.tool";
use constant SDK_TO_XCSPEC_NAME_MAP => +{ "iphoneos" => "iPhoneOS", "iphonesimulator" => "iPhone Simulator " };
use constant SDK_TO_PLUGIN_XCSPEC_NAME_MAP => +{ "iphoneos" => "Embedded-Device.xcspec", "iphonesimulator" => "Embedded-Simulator.xcspec" };

# FIXME: We should only require running as root if needed. It's not necessary to run as root if
#        Xcode was installed by the user, say via a download from <http://developer.apple.com>.
if ($EFFECTIVE_USER_ID) {
    print STDERR basename($0) . " must be run as root.\n";
    exit 1;
}

for my $sdk (qw(iphoneos iphonesimulator)) {
    updateXcodeSpecificationFilesForSDKIfNeeded($sdk);
    copyMissingXSLTHeadersToSDKIfNeeded($sdk);
}

copyMissingHeadersToIPhoneOSSDKIfNeeded();

exit 0;

sub copyMissingHeadersToIPhoneOSSDKIfNeeded()
{
    my @missingHeaders = qw(
        /usr/include/crt_externs.h
        /usr/include/MacErrors.h
        /usr/include/mach/mach_types.defs
        /usr/include/mach/machine/machine_types.defs
        /usr/include/mach/std_types.defs
        /usr/include/objc/objc-class.h
        /usr/include/objc/objc-runtime.h
        /usr/include/objc/Protocol.h
        /usr/include/readline/history.h
        /usr/include/readline/readline.h
        /usr/include/sqlite3_private.h
    );

    my $iphoneosSDKDirectory = sdkDirectory("iphoneos");
    my $iphonesimulatorSDKDirectory = sdkDirectory("iphonesimulator");

    for my $header (@missingHeaders) {
        my $iphoneosSDKPath = File::Spec->canonpath(File::Spec->catfile($iphoneosSDKDirectory, $header));
        next if (-f $iphoneosSDKPath);

        my $iphonesimulatorSDKPath = File::Spec->canonpath(File::Spec->catfile($iphonesimulatorSDKDirectory, $header));
        system("/usr/bin/ditto", $iphonesimulatorSDKPath, $iphoneosSDKPath);
        die "Could not copy $iphonesimulatorSDKPath to $iphoneosSDKPath: $!" if exitStatus($?);
        print "Successfully copied $iphonesimulatorSDKPath to $iphoneosSDKPath.\n";
    }
}

sub copyMissingXSLTHeadersToSDKIfNeeded($)
{
    my ($sdkName) = @_;
    my $sdkXSLTHeaderDirectory = File::Spec->canonpath(File::Spec->catdir(sdkDirectory($sdkName), "usr", "include", "libxslt"));
    return if -d $sdkXSLTHeaderDirectory;

    my $macosxXSLTHeaderDirectory = File::Spec->canonpath(File::Spec->catdir(sdkDirectory("macosx"), "usr", "include", "libxslt"));
    system("/usr/bin/ditto", $macosxXSLTHeaderDirectory, $sdkXSLTHeaderDirectory);
    die "Could not copy $macosxXSLTHeaderDirectory to $sdkXSLTHeaderDirectory: $!" if exitStatus($?);
    print "Successfully copied $macosxXSLTHeaderDirectory to $sdkXSLTHeaderDirectory.\n";
}

sub updateXcodeSpecificationFilesForSDKIfNeeded($)
{
    my ($sdkName) = @_;
    my $xcode7SpecificationFile = realpath(File::Spec->catfile(sdkPlatformDirectory($sdkName), "..", "..", "..", "PlugIns", "IDEiOSSupportCore.ideplugin", "Contents", "Resources", SDK_TO_PLUGIN_XCSPEC_NAME_MAP->{$sdkName}));
    if (-f $xcode7SpecificationFile) {
        updateXcode7SpecificationFile($xcode7SpecificationFile);
    } else {
        createLegacyXcodeSpecificationFilesForSDKIfNeeded($sdkName);
    }
}

sub updateXcode7SpecificationFile($)
{
    my ($specificationFile) = @_;

    my $hasPackageTypeForCommandLineTool = !!readXcodeSpecificationById($specificationFile, COMMAND_LINE_PACKAGE_TYPE);
    my $hasProductTypeForCommandLineTool = !!readXcodeSpecificationById($specificationFile, COMMAND_LINE_PRODUCT_TYPE);
    if ($hasPackageTypeForCommandLineTool && $hasProductTypeForCommandLineTool) {
        return; # Xcode knows how to build a command line tool for $sdkName.
    }

    my $macosxSDKSpecificationsPath = xcodeSDKSpecificationsPath("macosx");
    if (!$hasPackageTypeForCommandLineTool) {
        my $packageTypesForMacOSXPath = File::Spec->catfile($macosxSDKSpecificationsPath, "MacOSX Package Types.xcspec");
        mergeXcodeSpecificationWithSpecificationAndId($specificationFile, $packageTypesForMacOSXPath, COMMAND_LINE_PACKAGE_TYPE);
    }

    if (!$hasProductTypeForCommandLineTool) {
        my $productTypesForMacOSXPath = File::Spec->catfile($macosxSDKSpecificationsPath, "MacOSX Product Types.xcspec");
        mergeXcodeSpecificationWithSpecificationAndId($specificationFile, $productTypesForMacOSXPath, COMMAND_LINE_PRODUCT_TYPE);
    }
    print "Successfully updated '$specificationFile'.\n";
}

sub createLegacyXcodeSpecificationFilesForSDKIfNeeded($)
{
    my ($sdk) = @_;
    my $sdkSpecificationsPath = xcodeSDKSpecificationsPath($sdk);

    local @::xcodeSpecificationFiles;
    sub wanted
    {
        my $file = $_;

        # Ignore hidden files/directories.
        if ($file =~ /^\../) {
            $File::Find::prune = 1;
            return;
        }

        if (!-f $file || $file !~ /\.xcspec$/) {
            return;
        }

        push @::xcodeSpecificationFiles, $File::Find::name;
    }

    find(\&wanted, $sdkSpecificationsPath);

    my $hasPackageTypeForCommandLineTool;
    my $hasProductTypeForCommandLineTool;
    foreach my $specificationFile (@::xcodeSpecificationFiles) {
        last if $hasPackageTypeForCommandLineTool && $hasProductTypeForCommandLineTool;
        if (!$hasPackageTypeForCommandLineTool && readXcodeSpecificationById($specificationFile, COMMAND_LINE_PACKAGE_TYPE)) {
            $hasPackageTypeForCommandLineTool = 1;
            next;
        }
        if (!$hasProductTypeForCommandLineTool && readXcodeSpecificationById($specificationFile, COMMAND_LINE_PRODUCT_TYPE)) {
            $hasProductTypeForCommandLineTool = 1;
            next;
        }
    }

    if ($hasPackageTypeForCommandLineTool && $hasProductTypeForCommandLineTool) {
        return; # Xcode knows how to build a command line tool for $sdk.
    }

    my $fileNamePrefix = SDK_TO_XCSPEC_NAME_MAP->{$sdk};

    my $macosxSDKSpecificationsPath = xcodeSDKSpecificationsPath("macosx");
    if (!$hasPackageTypeForCommandLineTool) {
        my $packageTypesForMacOSXPath = File::Spec->catfile($macosxSDKSpecificationsPath, "MacOSX Package Types.xcspec");
        my $packageTypesForWebKitDevelopmentPath = File::Spec->catfile($sdkSpecificationsPath, "${fileNamePrefix}PackageTypes For WebKit Development.xcspec");
        mergeXcodeSpecificationWithSpecificationAndId($packageTypesForWebKitDevelopmentPath, $packageTypesForMacOSXPath, COMMAND_LINE_PACKAGE_TYPE);
        print "Successfully created '$packageTypesForWebKitDevelopmentPath'.\n";
    }

    if (!$hasProductTypeForCommandLineTool) {
        my $productTypesForMacOSXPath = File::Spec->catfile($macosxSDKSpecificationsPath, "MacOSX Product Types.xcspec");
        my $productTypesForWebKitDevelopmentPath = File::Spec->catfile($sdkSpecificationsPath, "${fileNamePrefix}ProductTypes For WebKit Development.xcspec");
        mergeXcodeSpecificationWithSpecificationAndId($productTypesForWebKitDevelopmentPath, $productTypesForMacOSXPath, COMMAND_LINE_PRODUCT_TYPE);
        print "Successfully created '$productTypesForWebKitDevelopmentPath'.\n";
    }
}

sub sdkDirectory($)
{
    my ($sdkName) = @_;
    chomp(my $sdkDirectory = `xcrun --sdk '$sdkName' --show-sdk-path`);
    die "Failed to get SDK path from xcrun: $!" if exitStatus($?);
    return $sdkDirectory;
}

sub sdkPlatformDirectory($)
{
    my ($sdkName) = @_;
    chomp(my $sdkPlatformDirectory = `xcrun --sdk '$sdkName' --show-sdk-platform-path`);
    die "Failed to get SDK platform path from xcrun: $!" if exitStatus($?);
    return $sdkPlatformDirectory;
}

sub writeXcodeSpecification($$)
{
    my ($xcodeSpecificationFile, $specification) = @_;
    my ($tempFileHandle, $tempFilename) = tempfile("webkit-xcspecXXXXXXX", UNLINK => 1);
    print $tempFileHandle $specification;
    close($tempFileHandle);
    if (!-f $xcodeSpecificationFile) {
        system("/usr/libexec/PlistBuddy -x -c 'clear array' '$xcodeSpecificationFile' > /dev/null") == 0 or die "PlistBuddy exited with $?: $!";
    }
    system("/usr/libexec/PlistBuddy -x -c 'add 0 dict' '$xcodeSpecificationFile' > /dev/null") == 0 or die "PlistBuddy exited with $?: $!";
    system("/usr/libexec/PlistBuddy -x -c 'merge $tempFilename 0' '$xcodeSpecificationFile' > /dev/null") == 0 or die "PlistBuddy exited with $?: $!";
}

sub readXcodeSpecificationById($$)
{
    my ($xcodeSpecificationFile, $id) = @_;
    open(PLIST_BUDDY, "-|", "/usr/libexec/PlistBuddy", "-x", "-c", "Print", $xcodeSpecificationFile) or die "Failed to run PlistBuddy: $!";
    my $foundStartOfSpecificationsArray;
    while (<PLIST_BUDDY>) {
        if (/^<array>$/) {
            $foundStartOfSpecificationsArray = 1;
            last;
        }
    }
    if (!$foundStartOfSpecificationsArray) {
       return ""; # Not a Xcode specification file.
    }
    my $position = -1;
    my $foundIdentfierKey = 0;
    my $foundSpecification = 0;
    while (<PLIST_BUDDY>) {
        if (/^\s<dict>$/) {
            ++$position;
            next;
        }
        if (!$foundIdentfierKey && /^\s\s<key>Identifier<\/key>$/) {
            $foundIdentfierKey = 1;
            next;
        }
        if ($foundIdentfierKey && /^\s\s<string>([^<]+)<\/string>$/) {
            if ($1 eq $id) {
                $foundSpecification = 1;
                last;
            }
            $foundIdentfierKey = 0;
            next;
        }
    }
    close(PLIST_BUDDY);
    if ($foundSpecification && $position >= 0) {
        chomp(my $result = `/usr/libexec/PlistBuddy -x -c 'Print $position' '$xcodeSpecificationFile'`);
        die "Failed to run PlistBuddy" if $?;
        return $result;
    }
    return ""; # Did not find id.
}

sub xcodeSDKSpecificationsPath($)
{
    my ($sdkName) = @_;

    return File::Spec->catdir(sdkPlatformDirectory($sdkName), "Developer", "Library", "Xcode", "Specifications");
}

sub mergeXcodeSpecificationWithSpecificationAndId($$$)
{
    my ($targetXcodeSpecificationFile, $sourceXcodeSpecificationFile, $id) = @_;
    my $specification = readXcodeSpecificationById($sourceXcodeSpecificationFile, $id);
    if (!$specification) {
        die "Failed to find '$id' in '$sourceXcodeSpecificationFile'.\n";
    }
    writeXcodeSpecification($targetXcodeSpecificationFile, $specification);
}
