#!/usr/bin/perl -w

# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
# Copyright (C) 2009 Google Inc. All rights reserved.
# Copyright (C) 2010 moiji-mobile.com All rights reserved.
# Copyright (C) 2011 Research In Motion Limited. All rights reserved.
# Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
#
# 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. 
# 3.  Neither the name of Apple Inc. ("Apple") nor the names of
#     its contributors may be used to endorse or promote products derived
#     from this software without specific prior written permission. 
#
# THIS SOFTWARE IS PROVIDED BY APPLE 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 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.

# Build script wrapper for the WebKit Open Source Project.

use strict;
use File::Basename;
use File::Find;
use File::Spec;
use FindBin;
use Getopt::Long qw(:config pass_through no_auto_abbrev);
use lib $FindBin::Bin;
use webkitdirs;
use List::Util qw(first);
use webkitperl::FeatureList qw(getFeatureOptionList);
use POSIX;

sub cMakeArgsFromFeatures();
sub writeCongrats();

my $originalWorkingDirectory = getcwd();
chdirWebKit();

my $showHelp = 0;
my $clean = 0;
my $minimal = 0;
my $installHeaders;
my $installLibs;
my $prefixPath;
my $makeArgs = "";
my @cmakeArgs;
my $onlyWebKitProject = 0;
my $coverageSupport = 0;
my $shouldRunStaticAnalyzer = 0;
my $startTime = time();

my @features = getFeatureOptionList();

# Additional environment parameters
push @ARGV, split(/ /, $ENV{'BUILD_WEBKIT_ARGS'}) if ($ENV{'BUILD_WEBKIT_ARGS'});

# Initialize values from defaults
foreach (@ARGV) {
    if ($_ eq '--minimal') {
        $minimal = 1;
    }
}

# Initialize values from defaults
foreach (@features) {
    ${$_->{value}} = ($minimal ? 0 : $_->{default});
}

my $programName = basename($0);
my $usage = <<EOF;
Usage: $programName [options] [options to pass to build system]
  --help                            Show this help message
  --clean                           Cleanup the build directory
  --debug                           Compile with Debug configuration
  --release                         Compile with Release configuration
  --sdk=<sdk>                       Use a specific Xcode SDK (iOS and Mac only)
  --device                          Use "iphoneos.internal" SDK if installed, else "iphoneos" SDK (iOS only)
  --ios-simulator                   Use the current iphonesimulator SDK (iOS only)
  --coverage                        Enable code coverage support (Mac only)
  --analyze                         Enable static anaylsis (iOS and Mac only)

  --efl                             Build the EFL port
  --gtk                             Build the GTK+ port
  --wincairo                        Build using Cairo (rather than CoreGraphics) on Windows

  --inspector-frontend              Copy Web Inspector user interface resources to the build directory

  --prefix=<path>                   Set installation prefix to the given path (Gtk/Efl only)
  --makeargs=<arguments>            Optional Makefile flags
  --cmakeargs=<arguments>           One or more optional CMake flags (e.g. --cmakeargs="-DFOO=bar -DCMAKE_PREFIX_PATH=/usr/local")

  --minimal                         No optional features, unless explicitly enabled

  --only-webkit                     Build only the WebKit project

EOF

my %options = (
    'help' => \$showHelp,
    'clean' => \$clean,
    'install-headers=s' => \$installHeaders,
    'install-libs=s' => \$installLibs,
    'prefix=s' => \$prefixPath,
    'makeargs=s' => \$makeArgs,
    'cmakeargs=s' => \@cmakeArgs,
    'minimal' => \$minimal,
    'only-webkit' => \$onlyWebKitProject,
    'coverage' => \$coverageSupport,
    'analyze' => \$shouldRunStaticAnalyzer,
);

# Build usage text and options list from features
foreach (@features) {
    my $opt = sprintf("%-35s", "  --[no-]$_->{option}");
    $usage .= "$opt $_->{desc} (default: $_->{default})\n";
    $options{"$_->{option}!"} = $_->{value};
}

GetOptions(%options);

if ($showHelp) {
   print STDERR $usage;
   exit 1;
}

checkRequiredSystemConfig();
setConfiguration();

my $productDir = productDir();

# Check that all the project directories are there.
my @projects = ("Source/JavaScriptCore", "Source/WebCore", "Source/WebKit");

# Build WTF as a separate static library on ports which support it.
splice @projects, 0, 0, "Source/WTF" if isAppleWebKit() or isWinCairo();

splice @projects, 0, 0, "Source/bmalloc" if isAppleMacWebKit();

# Ports using CMake will check if directories exist in the CMake configuration.
if (!isCMakeBuild()) {
    for my $dir (@projects) {
        if (! -d $dir) {
            die "Error: No $dir directory found. Please do a fresh checkout.\n";
        }
    }
}

if ((isAppleWebKit() || isWinCairo()) && !-d "WebKitLibraries") {
    die "Error: No WebKitLibraries directory found. Please do a fresh checkout.\n";
}

my @options = ();

if (isAppleMacWebKit()) {
    push @options, XcodeOptions();
    sub option($$$)
    {
        my ($feature, $isEnabled, $defaultValue) = @_;
        return "" if $defaultValue == $isEnabled;
        return $feature . "=" . ($isEnabled ? $feature : "");
    }

    foreach (@features) {
        my $option = option($_->{define}, ${$_->{value}}, $_->{default});
        push @options, $option unless $option eq "";
    }

    # ANGLE must come before WebCore
    splice @projects, 0, 0, "Source/ThirdParty/ANGLE";

    push @projects, ("Source/WebKit2");

    if (!isIOSWebKit()) {
        push @projects, ("Tools/MiniBrowser");

        # WebInspectorUI must come after JavaScriptCore and WebCore but before WebKit and WebKit2
        my $webKitIndex = first { $projects[$_] eq "Source/WebKit" } 0..$#projects;
        splice(@projects, $webKitIndex, 0, "Source/WebInspectorUI");

        # Copy library and header from WebKitLibraries to a findable place in the product directory.
        my @copyLibrariesArgs = ("perl", "Tools/Scripts/copy-webkitlibraries-to-product-directory", "--wksi",  productDir());
        print(join(" ", @copyLibrariesArgs) . "\n");
        (system(@copyLibrariesArgs) == 0) or die;
    } else {
        my @copyLibrariesArgs = ("perl", "Tools/Scripts/copy-webkitlibraries-to-product-directory", "--sdk", xcodeSDK(), "--wksi");
        push @copyLibrariesArgs, productDir();
        print(join(" ", @copyLibrariesArgs) . "\n");
        (system(@copyLibrariesArgs) == 0) or die;

        if (willUseIOSSimulatorSDK()) {
            (system("perl", "Tools/Scripts/build-layouttestrelay", argumentsForConfiguration()) == 0) or die;
        }
    }

    # Build Tools needed for Apple ports
    push @projects, ("Tools/DumpRenderTree", "Tools/WebKitTestRunner", "Source/ThirdParty/gtest", "Tools/TestWebKitAPI");

} elsif (isWinCairo()) {
    (system("perl Tools/Scripts/update-webkit-wincairo-libs") == 0) or die;
} elsif (isAppleWinWebKit()) {
    # Copy WebKitSupportLibrary to the correct location in WebKitLibraries so it can be found.
    # Will fail if WebKitSupportLibrary.zip is not in source root.
    (system("perl Tools/Scripts/update-webkit-support-libs") == 0) or die;
}

# If asked to build just the WebKit project, overwrite the projects
# list after all of the port specific tweaks have been made to
# build options, etc.
@projects = ("Source/WebKit") if $onlyWebKitProject;

my $result = 0;

if (isInspectorFrontend()) {
    die "The --inspector-frontend option is not supported for CMake-based builds." if isCMakeBuild();
    @projects = ("Source/WebInspectorUI");
}

if (isCMakeBuild() && !isAnyWindows()) {

    # By default we build using all of the available CPUs.
    $makeArgs .= ($makeArgs ? " " : "") . "-j" . numberOfCPUs() if $makeArgs !~ /-j\s*\d+/;
    my $maxCPULoad = maxCPULoad() if $makeArgs !~ /-l\s*\d+\.?\d*/;
    $makeArgs .= " -l" . maxCPULoad() if defined $maxCPULoad;

    # We remove CMakeCache to avoid the bots to reuse cached flags when
    # we enable new features. This forces a reconfiguration.
    my @featureArgs = cMakeArgsFromFeatures();
    removeCMakeCache(@featureArgs);

    buildCMakeProjectOrExit($clean, $prefixPath, $makeArgs, (cmakeBasedPortArguments(), @featureArgs), @cmakeArgs);
}

my $baseProductDir = baseProductDir();
if (isAppleWinWebKit() || isWinCairo()) {
    my @featureArgs = cMakeArgsFromFeatures();
    removeCMakeCache(@featureArgs);

    chdirWebKit();
    if (exitStatus(generateBuildSystemFromCMakeProject())) {
        die "Run \"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/vcvarsall.bat\" before build-webkit when using ninja";
    }
    chdirWebKit();
    if (canUseNinja()) {
        chdir File::Spec->catdir($baseProductDir, configuration());
        $result = system("ninja");
    } else {
        $result = buildVisualStudioProject(File::Spec->catfile("WebKitBuild", configuration(), "WebKit.sln"), $clean);
    }
    if (exitStatus($result)) {
        my $scriptDir = relativeScriptsDir();
        if (isAppleWinWebKit() || isWinCairo()) {
            print "\n\n===== BUILD FAILED ======\n\n";
            print "Please ensure you have run $scriptDir/update-webkit to install dependencies.\n\n";
            print "You can view build errors by checking the BuildLog.htm files located at:\n$baseProductDir/obj/<project>/<config>.\n";
        }
        exit exitStatus($result);
    }
} elsif (isAppleMacWebKit() && !isCMakeBuild()) {
    # Build, and abort if the build fails.
    for my $dir (@projects) {
        chdir $dir or die;
        $result = 0;

        my $project = basename($dir);
        
        my @local_options = @options;
        push @local_options, XcodeCoverageSupportOptions() if $coverageSupport;
        push @local_options, XcodeStaticAnalyzerOption() if $shouldRunStaticAnalyzer;
        my $projectPath = $project =~ /gtest/ ? "xcode/gtest" : $project;
        $result = buildXCodeProject($projectPath, $clean, @local_options, @ARGV);

        # Various build* calls above may change the CWD.
        chdirWebKit();

        if (exitStatus($result)) {
            exit exitStatus($result);
        }
    }
}

# Don't report the "WebKit is now built" message after a clean operation.
exit if $clean;

# Don't report congrats message if build was interrupted by the user.
exit if ($result & 127) == SIGINT;

# Explicitly chdir back to where exit will take us anyway, since the following "launcher"
# message is relative to that directory.
chdir $originalWorkingDirectory;

# Write out congratulations message.
writeCongrats();

exit 0;

sub cMakeArgsFromFeatures()
{
    my @args;
    foreach (@features) {
        my $featureName = $_->{define};
        if ($featureName) {
            my $featureEnabled = ${$_->{value}} ? "ON" : "OFF";
            push @args, "-D$featureName=$featureEnabled";
        }
    }
    return @args;
}

sub writeCongrats()
{
    my $launcherPath = launcherPath();
    my $launcherName = launcherName();
    my $endTime = time();
    my $buildTime = formatBuildTime($endTime - $startTime);

    print "\n";
    print "====================================================================\n";
    print " WebKit is now built ($buildTime). \n";
    if ($launcherPath && $launcherName) {
        print " To run $launcherName with this newly-built code, use the\n";
        print " \"$launcherPath\" script.\n";
    }
    print "====================================================================\n";
}
