#!/usr/bin/env perl

use strict;
use warnings;

# CONFIGURE

# The location of the TestSwarm that you're going to run against.

my $SWARM = "http://dev01.sf.archive.org:8080";
my $SWARM_INJECT = "/js/inject.js";

# Your TestSwarm username.

my $USER = "testflip";

# Your authorization token.

# my $AUTH_TOKEN = "";
open(AUTHFILE, "/home/testflip/.testswarm");
my $AUTH_TOKEN = <AUTHFILE>;
chomp($AUTH_TOKEN);

# The maximum number of times you want the tests to be run.

my $MAX_RUNS = 5;

# The type of revision control system being used.
# Currently "svn" or "git" are supported.

my $RCS_TYPE = "git";

# The URL from which a copy will be checked out.

my $RCS_URL = "/home/testflip/bookreader/.git";

# The directory in which the checkouts will occur.

my $BASE_DIR = "/home/testflip/public_html/changeset";

# A script tag loading in the TestSwarm injection script will
# be added at the bottom of the <head> in the following file.

my $INJECT_FILE = "BookReaderIA/test/index.html";

# Any build commands that need to happen.

my $BUILD = "(cd BookReaderIA; make test)";

# The name of the job that will be submitted
# (pick a descriptive, but short, name to make it easy to search)

# Note: The string {REV} will be replaced with the current
#       commit number/hash.

my $JOB_NAME = "BookReader www-testflip #{REV}";

# The browsers you wish to run against. Options include:
#  - "all" all available browsers.
#  - "popular" the most popular browser (99%+ of all browsers in use)
#  - "current" the current release of all the major browsers
#  - "gbs" the browsers currently supported in Yahoo's Graded Browser Support
#  - "beta" upcoming alpha/beta of popular browsers
#  - "popularbeta" the most popular browser and their upcoming releases

my $BROWSERS = "popularbeta";

# All the suites that you wish to run within this job
# (can be any number of suites)

#my %SUITES = ('first' => 'http://test.archive.org/changeset/{REV}/test/index.html');
my %SUITES = ();

# Comment these out if you wish to define a custom set of SUITES above
#my $SUITE = "http://dev.jquery.com/~john/changeset/{REV}";
my $SUITE = "http://home.us.archive.org/~testflip/changeset/{REV}/BookReaderIA";
sub BUILD_SUITES {
	%SUITES = map { /(\w+).js$/; $1 => "$SUITE/test/?$1%20module"; } glob("BookReaderIA/test/unit/*.js");
}

########### NO NEED TO CONFIGURE BELOW HERE ############

my $DEBUG = 1;
my $curdate = time;
my $co_dir = "tmp-$curdate";

print "chdir $BASE_DIR\n" if ( $DEBUG );
chdir( $BASE_DIR );

# Check out a specific revision
if ( $RCS_TYPE eq "svn" ) {
	print "svn co $RCS_URL $co_dir\n" if ( $DEBUG );
	`svn co $RCS_URL $co_dir`;
} elsif ( $RCS_TYPE eq "git" ) {
	print "git clone $RCS_URL $co_dir\n" if ( $DEBUG );
	`git clone $RCS_URL $co_dir`;
}

if ( ! -e $co_dir ) {
	die "Problem checking out source.";
}

print "chdir $co_dir\n" if ( $DEBUG );
chdir( $co_dir );

my $rev;

# Figure out the revision of the checkout
if ( $RCS_TYPE eq "svn" ) {
	print "svn info | grep Revision\n" if ( $DEBUG );
	$rev = `svn info | grep Revision`;
	$rev =~ s/Revision: //;
} elsif ( $RCS_TYPE eq "git" ) {
    my $cmd = "git rev-parse --short HEAD";
    print "$cmd\n" if ( $DEBUG );
    $rev = `$cmd`;
}

$rev =~ s/\s*//g;

print "Revision: $rev\n" if ( $DEBUG );

if ( ! $rev ) {
	remove_tmp();
	die "Revision information not found.";

} elsif ( ! -e "../$rev" ) {
	print "chdir $BASE_DIR\n" if ( $DEBUG );
	chdir( $BASE_DIR );

	print "rename $co_dir $rev\n" if ( $DEBUG );
	rename( $co_dir, $rev );

	print "chdir $rev\n" if ( $DEBUG );
	chdir ( $rev );

	if ( $BUILD ) {
		print "$BUILD\n" if ( $DEBUG );
		`$BUILD`;
	}

	if ( exists &BUILD_SUITES ) {
		&BUILD_SUITES();
	}

	foreach my $file ( glob($INJECT_FILE) ) {
		my $inject_file = `cat $file`;

		# Inject the TestSwarm injection script into the test suite
		$inject_file =~ s/<\/head>/<script>document.write("<scr" + "ipt src='$SWARM$SWARM_INJECT?" + (new Date).getTime() + "'><\/scr" + "ipt>");<\/script><\/head>/;

		open( my $fh, '>', $file ) or die "$file : $!";
		print $fh $inject_file;
		close( $fh );
	}

	my %props = (
		"state" => "addjob",
		"output" => "dump",
		"user" => $USER,
		"max" => $MAX_RUNS,
		"job_name" => $JOB_NAME,
		"browsers" => $BROWSERS,
		"auth" => $AUTH_TOKEN
	);

	my $query = "";

	foreach my $prop ( keys %props ) {
		$query .= ($query ? "&" : "") . $prop . "=" . clean($props{$prop});
	}

	foreach my $suite ( sort keys %SUITES ) {
		$query .= "&suites[]=" . clean($suite) .
		          "&urls[]=" . clean($SUITES{$suite});
	}

	print "curl -d \"$query\" $SWARM\n" if ( $DEBUG );
	my $results = `curl -d "$query" $SWARM`;

	print "Results: $results\n" if ( $DEBUG );

	if ( $results ) {
		open( my $fh, '>', "results.txt" ) or die "$rev/results.txt : $!";
		print $fh "$SWARM$results";
		close( $fh );

	} else {
		die "Job not submitted properly.";
	}

# Otherwise, give up and clean up
} else {
	remove_tmp();
}

sub remove_tmp {
	chdir( $BASE_DIR );
	`rm -rf $co_dir`;
}

sub clean {
  my $str = shift;
	$str =~ s/{REV}/$rev/g;
	$str =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;
	$str;
}
