#!/usr/bin/env perl

# Copyright (C) 2006 Apple 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 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 warnings;

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", "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();
