#!/usr/bin/perl -w
# vim:sw=4:et:ts=4:tw=72
# rank-output.pl - Print nice HTML file based on talkback database.
# L. David Baron, 2001-08-18

use 5.004;
use strict;
use Getopt::Long;
use HTML::Entities; # for encode_entities

my $logname = "seamonkey-crash-analysis-detailed";

GetOptions("firstdate=i", "lastdate=i", "db=s", "bugdb=s", "o=s");

($::opt_db && $::opt_o) || die qq{
usage: $0
  --db <filename>         The database.  [REQUIRED]
  --bugdb <filename>      Database mapping stack signatures to bugs.
  --o <filename>          Output filename.
  --firstdate YYYYMMDD    Exclude builds before YYYYMMDD.
  --lastdate YYYYMMDD     Exclude builds after YYYYMMDD.
};

require "dbfuncs.pl";
require "bugdb.pl";

my %database;
read_database($::opt_db, \%database);

my %bug_database;
if ($::opt_bugdb) {
    read_bug_database($::opt_bugdb, \%bug_database);
}

my %sigs; # hash from signature (or special TOTAL) to references to 
          # hashes of three members
          #   dates) a hash from dates (as strings) to the crash count
          #   platforms) a hash from platforms (as strings) to the crash count
          #   TOTAL) total crash count

sub fill_sigs() {
    foreach my $bbid (keys(%database)) {
        my $dbentry = $database{$bbid};
        my $buildday = substr($dbentry->{builddate}, 0, 8); 

        next if ((defined $::opt_firstdate && $buildday lt $::opt_firstdate)
              || (defined $::opt_lastdate  && $buildday gt $::opt_lastdate));

        if (!defined $sigs{TOTAL}) {
            $sigs{TOTAL} = { dates => {}, platforms => {} };
        }
        my $totalentry = $sigs{TOTAL};
        if (!defined $sigs{$dbentry->{stacksig}}) {
            $sigs{$dbentry->{stacksig}} = { dates => {}, platforms => {} };
        }
        my $sigentry = $sigs{$dbentry->{stacksig}};

        # increment the entries 

        if (defined($totalentry->{dates}->{$buildday})) {
            ++($totalentry->{dates}->{$buildday});
        } else {
            $totalentry->{dates}->{$buildday} = 1;
        }

        if (defined($totalentry->{platforms}->{$dbentry->{platform}})) {
            ++($totalentry->{platforms}->{$dbentry->{platform}});
        } else {
            $totalentry->{platforms}->{$dbentry->{platform}} = 1;
        }

        if (defined($totalentry->{TOTAL})) {
            ++($totalentry->{TOTAL});
        } else {
            $totalentry->{TOTAL} = 1;
        }

        if (defined($sigentry->{dates}->{$buildday})) {
            ++($sigentry->{dates}->{$buildday});
        } else {
            $sigentry->{dates}->{$buildday} = 1;
        }

        if (defined($sigentry->{platforms}->{$dbentry->{platform}})) {
            ++($sigentry->{platforms}->{$dbentry->{platform}});
        } else {
            $sigentry->{platforms}->{$dbentry->{platform}} = 1;
        }

        if (defined($sigentry->{TOTAL})) {
            ++($sigentry->{TOTAL});
        } else {
            $sigentry->{TOTAL} = 1;
        }

    }
}

sub print_sig_page($) {
    my ($dirname) = $_;
}

sub print_main_page() {
    # my $dirname = "output.$$";
    # mkdir($dirname, 0777);
    # open(INDEX, ">"."$dirname/index.html");
    open(INDEX, ">$::opt_o");

    my $totalentry = $sigs{TOTAL};
    my @dates = sort {$b cmp $a} keys(%{$totalentry->{dates}});
    my @platforms = sort {$a cmp $b} keys(%{$totalentry->{platforms}});

    print INDEX << "EndOfHead";
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <title>Talkback data summary</title>
    <style type="text/css">

    table { border-spacing: 0; border: 2px solid black; }
    td, th { border: 1px solid black; text-align: center; padding: 2px; }

    .sig { text-align: right; background: white; color: black; }
    .date { background: #ffc; color: black; }
    .platform { background: #cff; color: black; }
    .zero { color: #666; } /* only matches when .platform or .date does */
    .total { background: #fcf; color: black; }

    </style>
</head>
<body>
EndOfHead

    print INDEX "<table>\n<tr>"
              . "<th class=\"sig\">Signature</th>"
              . "<th class=\"bugs\">Bugs</th>";
    foreach my $date (@dates) {
        my $chopdate = substr($date, 4, 2) . "-" . substr($date, 6, 2);
        print INDEX "<th class=\"date\">$chopdate</th>"
    }
    foreach my $platform (@platforms) {
        print INDEX "<th class=\"platform\">$platform</th>"
    }
    print INDEX "<th class=\"total\">Total</th></tr>\n";

    my @rankedsigs = sort { $sigs{$b}->{TOTAL} <=> $sigs{$a}->{TOTAL} } keys(%sigs);

    foreach my $sig (@rankedsigs) {
        my $sigentry = $sigs{$sig};
        next if ($sigentry == $totalentry);

        print INDEX "<tr><td class=\"sig\">" . encode_entities($sig) . "</td>"
                  . "<td class=\"bug\">";
        if (defined $bug_database{$sig}) {
            my @bugs = split(" ", $bug_database{$sig});
            foreach my $bug (@bugs) {
                if ($bug =~ /^\d*$/) {
                    print INDEX "<a href=\"http://bugzilla.mozilla.org/show_bug.cgi?id=$bug\">$bug</a> ";
                } else {
                    print INDEX "$bug ";
                }
            }
        }
        print INDEX "</td>";
        foreach my $date (@dates) {
            my $num = $sigentry->{dates}->{$date}; 
            if (defined $num) {
                print INDEX "<td class=\"date nonzero\">" . $num . "</td>";
            } else {
                print INDEX "<td class=\"date zero\">0</td>";
            }
        }
        foreach my $platform (@platforms) {
            my $num = $sigentry->{platforms}->{$platform}; 
            if (defined $num) {
                print INDEX "<td class=\"platform nonzero\">" . $num . "</td>";
            } else {
                print INDEX "<td class=\"platform zero\">0</td>";
            }
        }
        print INDEX "<td class=\"total\">"
                  . $sigentry->{TOTAL}
                  . "</td></tr>\n";
    }

    print INDEX "</table>\n</body>\n</html>";
    close(INDEX);
}

fill_sigs();
print_main_page();
