#!/usr/bin/perl
# -*- Mode: Perl; tab-width: 4; indent-tabs-mode: nil; -*-
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Automated Testing Code
#
# The Initial Developer of the Original Code is
# Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2005
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): Bob Clary <bob@bclary.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****

# make unbuffered
select STDERR; $| = 1;
select STDOUT; $| = 1;

 
use File::Temp qw/ tempfile tempdir /;
use File::Basename;
use Getopt::Mixed "nextOption";
use URI::Escape;
use Time::HiRes qw(sleep);
use lib "/work/mozilla/mozilla.com/test.mozilla.com/www/bin/";

require "edit-talkback.pl";

my $debug = 1;
my $product;
my $bindir;
my $timeout;
my $pagetimeout;
my $browserexe;
my $profile;
my $hook;
my $urllist;
my $depth;
my $id;
my $valgrind;

parse_options();

my $runtime = dirname($browserexe);

if ($debug)
{
    print "spider.pl product=$product bin=$bindir timeout=$timeout pagetimeout=$pagetimeout exe=$browserexe profile=$profile hook=$hook urls=$urllist depth=$depth id=$id valgrind=$valgrind runtime=$runtime\n";
}

open URLS, "<$urllist" || die "unable to open $urllist\n";

my @urls = <URLS>;

close URLS;

chdir $runtime or 
    die "spider.pl: unable to change directory to runtime $runtime";


my $server = $ENV{TEST_HTTP} || "test.mozilla.com";
my $hookon = "on";
my $url;
my $chromeurl;
my $testUrl;

if ($hook eq "none")
{
    $hookon = "off";
}

foreach $url (@urls)
{
    chomp $url;

    if ($debug)
    {
        print "spider.pl $url\n";
    }

    my $spider = "chrome://spider/content/spider.xul?" .
        "depth=$depth&" .
        "hooksignal=$hookon&" .
        "timeout=$pagetimeout&waittime=5&" .
        "autostart=on&autoquit=on&javascripterrors=on&" .
        "javascriptwarnings=on&chromeerrors=on&xblerrors=on&csserrors=on&" .
        "scripturl=" . 
        uri_escape("http://" . 
                   $server . 
                   $hook) . 
                   "&" .
                   "url=" . uri_escape(uri_escape($url));

    my @args;
    my $rc;
    my $signal;
    my $dumped;
    my $valgrind_file;

    editTalkback($browserexe, "$id:$url");

    if ($product eq "firefox" || $product eq "thunderbird")
    {
        if ($valgrind)
        {
            (undef, $valgrind_file) = tempfile("valgrind.XXXXX", DIR=> "/tmp");
            @args = ("$bindir/timed_run",
                     $timeout,
                     $url,
                     "/usr/local/bin/valgrind",
                     "--tool=memcheck",
                     "--trace-children=yes",
                     #"--leak-check=yes",
                     "--error-limit=no",
                     "--num-callers=20",
                     "--leak-resolution=high",
                     #"--show-reachable=yes",
                     "--log-file-exactly=$valgrind_file",
                     $browserexe,
                     "-P",
                     $profile,
                     "-chrome",
                     $spider);
        }
        else
        {
            if ($product eq "firefox")
            {
                # chrome url works for thunderbird 1.5.0.4 and later
                @args = ("$bindir/timed_run",
                         $timeout,
                         $url,
                         $browserexe,
                         "-P",
                         $profile,
                         "-chrome",
                         $spider);
            }
            else
            {
                @args = ("$bindir/timed_run",
                         $timeout,
                         $url,
                         $browserexe,
                         "-P",
                         $profile,
                         $spider);
            }
        }
    }
    else
    {
        if ($valgrind)
        {
            (undef, $valgrind_file) = tempfile("valgrind.XXXXX", DIR=> "/tmp");
            @args = ("$bindir/timed_run",
                     $timeout,
                     $url,
                     "/usr/local/bin/valgrind",
                     "--tool=memcheck",
                     "--trace-children=yes",
                     "--leak-check=yes",
                     "--error-limit=no",
                     "--num-callers=20",
                     "--leak-resolution=high",
                     "--show-reachable=yes",
                     "--log-file-exactly=$valgrind_file",
                     $browserexe,
                     "-P",
                     $profile,
                     $spider);
        }
        else
        {
            @args = ("$bindir/timed_run",
                     $timeout,
                     $url,
                     $browserexe,
                     "-P",
                     $profile,
                     $spider);
        }
    }

    system @args;
    $rc = $? >> 8;

    if ($valgrind)
    {
        open VALGRIND, "<$valgrind_file" || die "unable to open $valgrind_file\n";
        while (<VALGRIND>)
        {
            print $_;
        }
        close VALGRIND;
        unlink "$valgrind_file";
    }

    if ($rc == 99)
    {
        exit $rc;
    }
}

sub usage
{
    my $arg = shift @_;
    my $value = shift @_;

    print <<USAGE;

Error in $arg: $value

Usage: spider.pl [-p|--product]=product [-b|--bin]=bindir [-t|--timeout]=timeout [-T|--pagetimeout]=pagetimeout [-e|--exe]=browserexe [-P|--profile]=profile [-h|--hook]=hook [-u|--urls]=urllist [-d|--depth]=depth [-i|--id]=id

Invoke Spider a set of urls.

product    - firefox|thunderbird
bindir     - path to automated test bin directory
timeout    - time in seconds before Spider times out
pagetimeout - time in seconds before Spider times out loading a page
browserexe - path to browser executable
profile    - profile name
hook       - path to Spider userhook script relative to the web server
             where it is located.
             "none" if no userhook is specified.
urlist     - path to text file containing list of urls to be loaded,
             one url per line.
depth      - depth each url is to be spidered
id         - mozqa id for the test.
USAGE
    exit(2);
}

sub parse_options {
    my ($option_data, $option, $value, $lastop);

    $option_data = 'p=s product>p b=s bin>b t=i timeout>t T=i pagetimeout>T e=s exe>e P=s profile>P h=s hook>h u=s urls>u d=i depth>d i=s id>i v valgrind>v';

    Getopt::Mixed::init ($option_data);
    $Getopt::Mixed::order = $Getopt::Mixed::RETURN_IN_ORDER;

    $valgrind = 0;

    while (($option, $value) = nextOption()) 
    {
        if ($option eq "p")
        {
            $product = $value;
        }
        elsif ($option eq "b")
        {
            $bindir = $value;
        }
        elsif ($option eq "t")
        {
            $timeout = $value;
        }
        elsif ($option eq "T")
        {
            $pagetimeout = $value;
        }
        elsif ($option eq "e")
        {
            $browserexe = $value;
        }
        elsif ($option eq "P")
        {
            $profile = $value;
        }
        elsif ($option eq "h")
        {
            $hook = $value;
        }
        elsif ($option eq "u")
        {
            $urllist = $value;
        }
        elsif ($option eq "d")
        {
            $depth = $value;
        }
        elsif ($option eq "i")
        {
          $id = $value;
        }
        elsif ($option eq "v")
        {
            $valgrind = 1;
        }
        $lastopt = $option;
    }

    Getopt::Mixed::cleanup();

    if ($product ne "firefox" && $product ne "thunderbird")
    {
        usage("product", $product);
    }

    if (!defined $depth)
    {
        usage("depth", $depth);
    }

}
1;
