#!/usr/bin/perl -w 
use strict;

use parselog;
use Data::Dumper;
use Getopt::Long;
use File::Path;

my $template = 'out/<r>.html';
GetOptions("template=s" => \$template);

for (@ARGV) {
    parse(\&save, $_);
}

my @h;

# Content of the files:
# Key is the recipient's address (as stored in $s->{rcpts}{*}{xrcpts},
# i.e., without <>). 
#
# Second level contains two keys:
#   t for transactions,
#   s for statistics.
#
# For transactions the key is the start date (Hmm, that means if a
# recipient gets two mails in the same second, one of them will not be
# shown - FIXME)
#
# For stats there are various keys.
my %f;

for my $f (keys %f) {
    my ($local, $domain) = split(/@/, $f);
    my $ff = $template;
    $ff =~ s/<l>/$local/g;
    $ff =~ s/<d>/$domain/g;
    $ff =~ s/<r>/$f/g;
    my $d = $ff;
    $d =~ s/[^\/]*$//;
    if ($d) {
	mkpath $d;
    }
    open(F, '>:utf8', $ff);
    print F "<html><head>\n";
    print F "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />\n";
    print F "<title>", $f, "</title>\n";
    print F "<link rel='up' href='./' />\n";
    print F "<style type='text/css'>\n";
    print F ".active { font-style: italic; background-color: #FFF }\n";
    print F ".recipient { text-align: left; }\n";
    print F ".command { font-family: monospace; white-space: nowrap; text-align: left; }\n";
    print F ".meta { text-align: left; }\n";
    print F ".num { text-align: right; }\n";
    print F "</style>\n";
    print F "</head>\n";
    print F "<body><h1>", $f, "</h1>\n";
    print F "<p>&rarr;<a href='../../../maillogdoc.html'>Erläuterungen</a></p>\n";
    print F "<table border='1'>\n";
    for (sort keys %{ $f{$f}{t} }) {
	print F $f{$f}{t}{$_};
    }
    print F "</table>\n";
    print F "<h2>Stats</h2>\n";
    my %m = ();
    my $t = 0;
    for my $r (sort keys %{ $f{$f}{s} }) {
	my $res = $f{$f}{s}{$r};
	for my $c (sort keys %$res) {
	    for my $k (sort keys %{$res->{$c}}) {
		$m{$c}{$k} += $res->{$c}{$k};
		$t += $res->{$c}{$k};
	    }
	}
    }

    print F "<table border='1'>\n";
    print F "<tr>";
    print F "<th rowspan='2'></th>";
    for my $c (sort keys %m) {
	print F "<th colspan='", scalar keys %{$m{$c}}, "'>$c</th>";
    }
    print F "</tr>\n";

    print F "<tr>";
    for my $c (sort keys %m) {
	for my $k (sort keys %{$m{$c}}) {
	    print F "<th>", escape($k), "</th>";
	}
    }
    print F "</tr>\n";

    for my $r (sort keys %{ $f{$f}{s} }) {
	print F "<tr>";
	print F "<th class='recipient'>", escape($r), "</th>";
	my $res = $f{$f}{s}{$r};
	my $s = 0;
	for my $c (sort keys %m) {
	    for my $k (sort keys %{$m{$c}}) {
		no warnings 'uninitialized';
		print F "<td class='num'>", $res->{$c}{$k}, "</td>";
		$s +=  $res->{$c}{$k};
	    }
	}
	print F "<td class='num'>", $s, "</td>";
	print F "</tr>\n";

    }
    print F "<tr>";
    print F "<th></th>";
    for my $c (sort keys %m) {
	for my $k (sort keys %{$m{$c}}) {
	    print F "<td class='num'>", $m{$c}{$k}, "</td>";
	}
    }
    print F "<td class='num'>", $t, "</td>";
    print F "</tr>\n";
    print F "</table>\n";
    print F "</body>\n";
    print F "</html>\n";
    close(F);
}

sub save {
    my ($s) = @_;
    for my $r (keys %{$s->{rcpts}}) {
	my $rv = $s->{rcpts}{$r};
	#print STDERR "$r\n";
	for my $xr ( @{$rv->{xrcpts}}) {
	    #print "\t$xr\n";
	    my $f = $xr;
	    $f =~ s/\+.*\@/\@/;
	    $f =~ tr/-+a-zA-Z0-9@./_/c;
	    $f{$f}{t}{$s->{start}} .= dump_transaction($s, $r);
	    #$f{$f}{s}{substr($rv->{finalresult}, 0, 1)}++;
	    #$f{$f}{s}{msg2key($rv->{finalresult})}++;
	    $f{$f}{s}{$r}{substr($rv->{finalresult}, 0, 1)}{msg2key($rv->{finalresult})}++;
	}
    }
    #print "\n";
}

sub dump_transaction {
    my ($s, $ra) = @_;
    my $t = "<tbody>\n";
    $t .= "<tr bgcolor='#CCCCCC'><th>time</th><td colspan='2'>" . escape($s->{start}) . " ... " . escape($s->{end}) . "</td></tr>\n";
    $t .= "<tr><th class='meta'>server</th><td colspan='2'>" . escape($s->{server}) . "</td></tr>\n";
    $t .= "<tr><th class='meta'>client</th><td colspan='2'>" . escape($s->{hostname}) . " [" . escape($s->{ipaddr}) . "]</td></tr>\n";
    $t .= "<tr><th class='command'>HELO</th><td>" . escape($s->{helo}) . "</td></tr>\n" if ($s->{helo});
    $t .= "<tr><th class='command'>EHLO</th><td>" . escape($s->{ehlo}) . "</td></tr>\n" if ($s->{ehlo});
    $t .= "<tr><th class='command'>MAIL FROM</th><td><strong>" . escape($s->{mail}) . "</strong></td>" . result($s->{mailresult}) . "</tr>\n";
    for my $r (keys %{$s->{rcpts}}) {
	my $class = $r eq $ra ? "active recipient" : "recipient";
	$t .= "<tr><th class='command'>RCPT TO</th><td class='$class'> " . escape($r) . "</td>" . result($s->{rcpts}{$r}{rcptresult}) . "</tr>\n";
    }
    $t .= "<tr><th class='command'>DATA</th><td></td>" . result($s->{dataresult}) . "</tr>\n";
    if ($s->{spamassassin}) {
	$t .= "<tr><th class='plugin'>spamassassin</th><td></td><td>"
	      .  join('<br/>', map { s/,/, /g; escape($_) } @{$s->{spamassassin}})
	      . "</td></tr>\n";
    }
    $t .= "</tbody>\n";
    $t .= "\n";
}

sub result {
    my ($msg) = @_;
    $msg = '' unless (defined $msg);
    my $color = '#FFFFFF';
    $color = '#00FF00' if (substr($msg, 0, 1) eq '2');
    $color = '#FFFF00' if (substr($msg, 0, 1) eq '4');
    $color = '#FF0000' if (substr($msg, 0, 1) eq '5');
    return "<td bgcolor='$color'>" . escape($msg) . "</td>";
}

sub escape {
    my ($s) = @_;

    $s = '' unless (defined $s);
    $s =~ s/\&/\&amp;/g;
    $s =~ s/\</\&lt;/g;
    $s =~ s/\>/\&gt;/g;
    return $s;
}

