#!/usr/bin/perl -- # -*- Perl -*-

use LWP::UserAgent;
use English;

my $file = shift @ARGV;
my $uri = shift @ARGV;

#print STDERR "Comparing $file to $uri\n";

my ($actual, $expected);

open (F, $file);
read (F, $actual, -s $file);
close (F);

$actual = finesseWhitespace($actual);
$actual = finesseNumCharRef($actual);
$actual = finesseAttrOrder($actual);

my $ua = new LWP::UserAgent;
my $req = new HTTP::Request GET => $uri;
my $res = $ua->request($req);

$expected = $res->content();

$expected = finesseWhitespace($expected);
$expected = finesseNumCharRef($expected);
$expected = finesseAttrOrder($expected);

#print STDERR "E: $expected\n";
#print STDERR "A: $actual\n";

if ($expected eq $actual) {
    exit 0;
} else {
    exit 1;
}

sub finesseWhitespace {
    my $text = shift;
    $text = $1 . $2 if $text =~ /^(<\?xml.*?\?>)\s*(.*)$/s;
    $text =~ s/\s*$//;
    return $text;
}

sub finesseNumCharRef {
    my $text = shift;
    my $patch = "";
    while ($text =~ /&#([0-9]+);/s) {
        $patch .= sprintf("%s&#x%x;", $PREMATCH, $1);
        $text = $POSTMATCH;
    }
    return $patch . $text;
}

sub finesseAttrOrder {
    my $text = shift;
    my $patch = "";
    my $match = "";

    while ($text =~ /<([^\/].*?)(\/?>)/) {
        $patch .= $PREMATCH;
        $text = $POSTMATCH;
        $match = $MATCH;

        my $etag = $2;
        my $tag = $1;

        if ($tag =~ /^(\S+)\s+(\S.*)$/) {
            $tag = $1;
            my $attrs = $2;

            my %attr = ();
            while ($attrs =~ /\s*\S+\s*=\s*([\'\"])/) {
                my $q = $1;
                $attrs =~ /(\S+)\s*=\s*$q(.*?)$q/ || die;
                $attrs = $POSTMATCH;
                $attr{$1} = $q . $2 . $q;
            }

            $match = "<$tag";
            foreach my $key (sort { $a cmp $b } keys %attr) {
                $match .= " $key=" . $attr{$key};
            }
            $patch .= $match . $etag;
        } else {
            $patch .= $match;
        }
    }

    return $patch . $text;
}
