#!/usr/bin/perl -w

# Copyright (C) 2007 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 COMPUTER, 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 COMPUTER, 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. 

use strict;
use Getopt::Long;
use File::Basename;

my $showHelp = 0;
my $jsShellPath;
my $ubench = 0;
my $v8suite = 0;
my $parseonly = 0;

my $programName = basename($0);
my $usage = <<EOF;
Usage: $programName --shell=[path] [options] FILE FILE
  --help        Show this help message
  --shell       Path to javascript shell
  --ubench      Compare microbenchmark results
  --v8-suite    Compare the V8 benchmark results
  --parse-only  Compare the parse-only benchmark results
EOF

GetOptions('shell=s' => \$jsShellPath,
           'ubench' => \$ubench,
           'v8-suite' => \$v8suite,
           'parse-only' => \$parseonly,
           'help' => \$showHelp);

my $resultDirectory = "sunspider-results";
$resultDirectory = "ubench-results" if ($ubench);
$resultDirectory = "v8-results" if ($v8suite);
$resultDirectory = "parse-only-results" if ($parseonly);

if ((scalar @ARGV != 0 && scalar @ARGV != 2) || !$jsShellPath || $showHelp) {
   print STDERR $usage;
   exit 1;
}

sub readResultsFile($)
{
    my ($filename) = @_;
    open FILE, "<", $filename or die;
    my $foundStart = 0;
    my $foundOutput = 0;
    my $foundEnd = 0;
    my $result = "";
    while (<FILE>) {
        if (!$foundStart) {
            if (/^\[\{$/) {
                $foundStart = 1;
                $result .= $_;
            } elsif (/^var \w+ = \[$/) {
                $foundOutput = 1;
            } elsif ($foundOutput && /^\{$/) {
                $foundOutput = 0;
                $foundStart = 1;
                $result = "[{\n";
            }
        } else {
            if (/\];?$/) {
                $foundEnd = 1;
                chomp;
                s/;$//;
                $result .= $_;
                last;
            } else {
                $result .= $_;
            }
        } 
    }
    close FILE;

    die "Cound not find data in ${filename} - needs to start with [{" unless $foundStart;
    die "Cound not find data in ${filename} - needs to end with }]" unless $foundEnd;

    return $result;
}

sub dumpToFile($$)
{
    my ($contents, $path) = @_;
    open FILE, ">", $path or die;
    print FILE $contents;
    close FILE;
}

sub readFile($)
{
    my ($path) = @_;
    open FILE, "<", $path or die;
    my $result = <FILE>;
    close FILE;
    return $result;
}

sub newestFile($$)
{
    my ($dir, $pattern) = @_;

    my $newestAge;
    my $newestFile = "";
    opendir DIR, $dir or die;
    for my $file (readdir DIR) {
        if ($file =~ $pattern) {
            my $age = -M "$dir/$file";
            if (!defined $newestAge || $age < $newestAge) {
                $newestFile = $file;
                $newestAge = $age;
            }
        }
    }
    closedir DIR;

    return "$dir/$newestFile";
}

my $file1;
my $file2;

if (scalar @ARGV == 2) {
    $file1 = $ARGV[0];
    $file2 = $ARGV[1];
} else {
    $file1 = readFile("$resultDirectory/baseline-filename.txt");
    $file2 = newestFile("$resultDirectory", qr/sunspider-results-.+\.js$/);
}

my $output = "var output1 = " . readResultsFile($file1) . ";\n";
$output .= "var output2 = " . readResultsFile($file2) . ";\n";

dumpToFile($output, "$resultDirectory/sunspider-comparison-data.js");

system($jsShellPath, "-f", "$resultDirectory/sunspider-test-prefix.js", "-f", "$resultDirectory/sunspider-comparison-data.js", "-f", "resources/sunspider-compare-results.js", "-f", "resources/sunspider-standalone-compare.js");
