#!/usr/bin/perl -w

# Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
# Copyright (C) 2006 Mark Rowe <opendarwin.org@bdash.net.nz>.  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. 
# 3.  Neither the name of Apple Computer, 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.

# Creates the launcher WebKit.app with bundled frameworks.

use strict;

use FindBin;
use lib "$FindBin::Bin/../Scripts";
use webkitdirs;

my @xcodeBuildArguments = XcodeOptions();
my $nightlyLauncherTemplatePath = "$FindBin::Bin/../WebKitLauncher";
my $nightlyLauncherStagingPath = productDir() . "/WebKit.app";

sub buildNightlyLauncher
{
    chdir($nightlyLauncherTemplatePath);
    system("xcodebuild", "clean", "-alltargets", @xcodeBuildArguments, @ARGV) == 0 or die "Failed cleaning WebKitLauncher project";
    system("xcodebuild", @xcodeBuildArguments, @ARGV) == 0 or die "Failed building WebKitLauncher project";
    chdirWebKit();
}

sub currentRevision
{
    my $sourceDir = sourceDir();
    if (isSVNDirectory($sourceDir)) {
        return currentSVNRevision();
    } elsif (isGitDirectory($sourceDir)) {
        my $gitLog = `cd $sourceDir && LC_ALL=C git log --grep='git-svn-id: ' -n 1 | grep git-svn-id:`;
        (my $revision) = ($gitLog =~ m/ +git-svn-id: .+@(\d+) /g);
        return $revision;
    }
}

sub currentBranch
{
    my $sourceDir = sourceDir();
    my ($url, $branch);
    if (isSVNDirectory($sourceDir)) {
        my $svnInfo = `LC_ALL=C svn info $sourceDir | grep URL:`;
        ($url) = ($svnInfo =~ m/URL: (.+)/g);
    } elsif (isGitDirectory($sourceDir)) {
        my $gitLog = `cd $sourceDir && LC_ALL=C git log --grep='git-svn-id: ' -n 1 | grep git-svn-id:`;
        ($url) = ($gitLog =~ m/ +git-svn-id: (.+)@\d+ /g);
    }
    ($branch) = ($url =~ m/\/webkit\/(trunk|branches\/[^\/]+)/);
    die "Unable to determine current SVN branch in $sourceDir" unless (defined $branch);
    $branch =~ s/^branches\///;
    return $branch;
}

sub copyNightlyLauncher
{
    my $revision = currentRevision();
    my $branch = currentBranch();

    my $infoPlist = "$nightlyLauncherStagingPath/Contents/Info.plist";
    my $versionFile = "$nightlyLauncherStagingPath/Contents/Resources/VERSION";
    my $branchFile = "$nightlyLauncherStagingPath/Contents/Resources/BRANCH";
    my $data;
    open(IN, $infoPlist) or die "Couldn't open Info.plist in built application for reading";
    {
        undef $/;
        $data = <IN>;
    }
    close(IN);
    open(OUT, ">$infoPlist") or die "Couldn't open Info.plist in built application for writing";
    $data =~ s/VERSION/$revision/g;
    print OUT $data;
    close(OUT);

    open(OUT, ">$versionFile") or die "Couldn't open VERSION in built application for writing";
    print OUT "$revision\n";
    close(OUT);

    open(OUT, ">$branchFile") or die "Couldn't open BRANCH in built application for writing";
    print OUT "$branch\n";
    close(OUT);

    my @frameworks = ("JavaScriptCore", "JavaScriptGlue", "WebCore", "WebKit");
    for my $framework (@frameworks) {
        system("ditto", productDir() . "/$framework.framework", "$nightlyLauncherStagingPath/Contents/Resources/$framework.framework") == 0 or die "Failed copying $framework.framework into $nightlyLauncherStagingPath";
    }
}

my $b = currentBranch();
my $r = currentRevision();
print "Branch: ", $b, "\n";
print "Revision: ", $r, "\n";

chdirWebKit();
buildNightlyLauncher();
copyNightlyLauncher();
