#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
my @ignore_test_arg;
my $debug = 0;
GetOptions(
    'ignore=s' => \@ignore_test_arg,
    'debug=i'  => \$debug,
);
@ignore_test_arg = map { split /\s*,\s*/ } @ignore_test_arg;
my @ignore_test;
foreach my $ita (@ignore_test_arg) {
    my @sub_re = split /\s*:\s*/,$ita;
    die "syntax error: $ita" if ($#sub_re > 2);
    my @this_it;
    for (my $i=0;$i<3;$i++) {
        push @this_it,(((defined $sub_re[$i]) and ($sub_re[$i] ne '')) ? qr/^$sub_re[$i]$/ : qr/^.*$/);
    }
    push @ignore_test,\@this_it;
    print "will ignore: " . join(':',@this_it) . "\n" if ($debug > 1);
}

my ($test_script,@planned,@ok,@test_msg,@tidx);
my %failed_test_summary;
my %architectures;
sub eval_test {
    my @failed_tests;
    my @failed_msgs;
    for (my $i=0;$i<=$#ok;$i++) {
        unless ($ok[$i]) {
            push @failed_tests,$planned[$i];
            push @failed_msgs,$test_msg[$i];
        }
    }
    my $arch = $1 if ($ARGV =~ /_([^_\.]+)\.testsuite$/);

    for (my $i=0; $i<=$#failed_tests; $i++) {
        my @val_tuple = ($test_script,$failed_tests[$i],$arch);
        my $ignore = 0;
        foreach my $it (@ignore_test) {
            my $this_ignore = 1;
            for (my $i=0;$i<3;$i++) {
                $this_ignore &= ($val_tuple[$i] =~ $it->[$i]);
            }
            if ($this_ignore) {
                $ignore = 1;
                print STDERR "ignored '" . join(':',@val_tuple) . "' due to '" . join(':',@{$it}) . "\n" if ($debug > 0);
                last;
            }
        }
        next if ($ignore);
#        printf "%-20s %3d %s %s\n",$test_script,$failed_tests[$i],$failed_msgs[$i],$arch;
        $architectures{$arch}=1 if ($#failed_tests>=0);
        $failed_test_summary{$test_script}->{$failed_tests[$i]}->{$arch}=1;
    }
}

while (<>) {
    if (/^(t\/.*\.t) \.+\s*skipped:/) {
        eval_test() if ((defined $test_script) and ($#planned >= 0));
        $test_script=undef;
        @planned=();
        @test_msg=();
        @ok=();
        @tidx=();
        next;
    }
    if (/^(t\/.*\.t) \.+\s*$/) {
        eval_test() if ((defined $test_script) and ($#planned >= 0));
        $test_script=$1;
        @planned=();
        @test_msg=();
        @ok=();
        @tidx=();
        next;
    }
    if (/^(\d+)\.\.(\d+)/) {
        warn "planned was not empty" if ($#planned>=0);
        @planned=$1 .. $2;
        @ok = (0) x ($#planned+1);
        @test_msg=('') x ($#planned+1);
        for (my $i=0;$i<=$#planned;$i++) {
            $tidx[$planned[$i]]=$i;
        }
        next;
    }
    next unless ((defined $test_script) and ($#planned >= 0));
    if (/^ok\s*(\d+)\s*(.*)/) {
        my $tidx=$tidx[$1];
        $ok[$tidx]=1;
        $test_msg[$tidx]=$2 unless ($2 =~ /^\s*$/);
    }
}
eval_test() if ((defined $test_script) and ($#planned >= 0));
my @architectures   = sort keys %architectures;
my $summary_fstring = '%-20s %3d';
foreach (@architectures) {
    $summary_fstring .= ' %' . length($_) . 's';
}
$summary_fstring.="\n";
foreach my $tst (sort keys %failed_test_summary) {
    foreach my $stst (sort { $a <=> $b } keys %{$failed_test_summary{$tst}}) {
        my @farchitectures= map { ($failed_test_summary{$tst}->{$stst}->{$_} ? $_ : '') } @architectures;
        printf $summary_fstring,$tst,$stst,@farchitectures;
    }
}
