#!/usr/bin/perl
# takes a properly formatted file, finds the update content for each build
# and compares two update content servers to make sure they match
# the file must be in the following format, seperated by the pipe | character
# Header
# %Product%|%Version%|%Platform%|%BuildID%|%Locale%|%Channel%
use strict;
use warnings;
use LWP::UserAgent;

sub HTTPResponse;

if (!defined($ARGV[0])) {
    print "USEAGE : perl $0 filename\n";
    exit 1;
}

open FILEHANDLE, "<$ARGV[0]";

# first line is a header. Discard it
<FILEHANDLE>;

$| = 1; # force a flush after each write

while (<FILEHANDLE>) {
    my $response_main;  #aus2
    my $response_test;  #aus2-test
    my $line = $_;
    my @params = split /\|/;
    
    $response_main = HTTPResponse(@params,
            'https://aus3.mozilla.org/update/');
    $response_test = HTTPResponse(@params,
            'https://aus03.zlb.phx.mozilla.net/update/');

    # build up a union of all headers
    my @all_headers = ();
    my %count = ();
    foreach my $element (keys(%{$response_main->headers()}), 
                         keys(%{$response_test->headers()})) { 
        $count{$element}++;
    }
    @all_headers = keys(%count);

    # ensure that headers only differ in the ways we expect
    my @allowed_undefined = ('cache-control', 'keep-alive', 'expires');
    my @allowed_mismatch = ('connection', 'set-cookie', 'client-peer', 
                            'date', 'client-date',
                            'keep-alive','x-backend-server');
    foreach my $name (@all_headers) {
        if (! defined($response_main->header($name))) {
            if (grep( { $_ eq $name } @allowed_undefined)) {
                next;
            }
            print STDERR "FAIL Header check failed for main $name: NOT DEFINED\n";
            next;
        }
        if (! defined($response_test->header($name))) {
            if (grep( { $_ eq $name } @allowed_undefined)) {
                next;
            }
            print STDERR "FAIL Header check failed for test $name: NOT DEFINED\n";
            next;
        }
        if ($response_main->header($name) ne $response_test->header($name)) {
            if (grep( { $_ eq $name } @allowed_mismatch)) {
                next;
            }
            print STDERR "FAIL Header check failed for $name NO MATCH, " .
                "main $name: " . $response_main->header($name) . " " .
                "test $name: " . $response_test->header($name) . "\n";
        }
    }
    chomp($line);
    if (!defined($response_main) || !defined($response_test)) {
        # don't show anything.
    } elsif ($response_main->content_type ne $response_test->content_type) {
        print STDERR "FAIL Content type check failed for $line (main=" .
             $response_main->content_type . " test=" .
             $response_test->content_type . "\n";
    } elsif ($response_main->content_length ne
             $response_test->content_length) {
        print STDERR "FAIL Content length check failed for $line (main=" .
             $response_main->content_length . " test=" .
             $response_test->content_length . "\n";
    } elsif ($response_main->content ne $response_test->content) {
        print STDERR "FAIL Content check failed for $line (main:" .
             $response_main->content . " test:" .
             $response_test->content . "\n";
    } elsif ($response_test->content_length <= 42) {
        print STDERR "FAIL Content length check failed (too short) for $line (test:" .
             $response_test->content . "\n";
    } else {
        print 'PASS ' . $line . ' ' . $response_main->header('x-backend-server') . ' ' . $response_test->header('x-backend-server') . "\n";
    }

    #sleep 1;
}

# This returns an instance of HTTP::Response
# Reference : http://search.cpan.org/~gaas/libwww-perl-5.803/lib/HTTP/Response.pm
sub HTTPResponse() {
    my ($product, $version, $platform,
        $build, $locale, $channel, $major_version, $server) = @_;
    # example url
    #https://aus2.mozilla.org/update/1/Firefox/1.5.0.3/2006042618/Linux_x86-gcc3/en-US/release/update.xml
    my $url;        # the full url
    my $response;
    my $lwp = LWP::UserAgent->new;
    chomp $major_version;     # removes newline characer
    $url = $server . "$major_version/" .
           "$product/" . "$version/" . "$build/" . "$platform/" .
           "$locale/" . "$channel/";
    
    # fake out %OS_VERSION%
    if ($major_version >= 2) {
        $url = $url . "AUS_Checker/";
    }
    # fake out %DISTRIBUTION%/%DISTRIBUTION_VERSION%/
    if ($major_version >= 3) {
        $url = $url . "default/default/";
    }
    $url = $url . "update.xml";

    my $req = HTTP::Request->new(GET => $url);
    $req->header(Hostname => "aus3.mozilla.org");

    $response = $lwp->request($req);

    unless ($response->is_success) {
        print STDERR "FAIL " . $response->status_line ."\n";
        return;
    }

    $response;
}
