#!/usr/local/bin/perl -s

# Command-line args: -syslog, -tally.

$; = "\n";

@groups = ("talk.politics.macedonia", "soc.culture.makedonija");
for (@groups) {
    $groups{$_}++;
}

if ($syslog) {
    $prefix = "good vote ";
}
else {
    $prefix = "";
}

while (<>) {
    if (m,$prefix(.*) // (.*) (yes|no|abstain) *$,i) {
	$address = $1;
	$group = $2;
	$vote = $3;
	$group =~ tr/A-Z/a-z/;
	$vote =~ tr/A-Z/a-z/;
	next if (! $groups{$group});

	$votes{$address,$group} = &parse_vote($vote);
	$voters{$address}++;
    }
}

$= = ((keys %voters) + 100);
$: = " ";

format STDOUT =
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<
$voter,                                                                      $vote_string
~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$voter
.

&print_headers(78, @groups);

foreach $voter (&address_sort(keys %voters)) {
    if ($vote_string = &vote_string($voter)) {
	write;
    }
}

if ($tally) {
    local($groupcollen);

    foreach $voter (keys %voters) {
	foreach $group (@groups) {
	    $vote_count{$group,$votes{$voter,$group}}++;
	}
    }

    for (@groups) {
	$groupcollen = length($_) if (length($_) > $groupcollen);
    }

    print "\n";
    printf("%-${groupcollen}s  %5s  %5s  %8s  %5s  %-7s\n", "Group",
	   "Yes", "No", "Yes - No", "% Yes", "Passes?");
    print "\n";

    foreach $group (@groups) {
	$yes_votes = $vote_count{$group,1};
	$no_votes = $vote_count{$group,-1};
	$difference = $yes_votes - $no_votes;
	$percent = 100 * $yes_votes / ($yes_votes + $no_votes);
	$passes = ($difference >= 100) && ($percent >= 2 / 3);
	printf("%-${groupcollen}s  %5d  %5d  %8d  %5.1f  %-7s\n", $group,
	       $yes_votes, $no_votes, $difference, $percent, 
	       $passes ? "PASS" : "FAIL");
    }
}
	
sub vote_string {
    local($str) = "";
    local($voter) = @_;

    foreach $group (@groups) {
	if ($votes{$voter,$group} == 1) {
	    $str .= "Y";
	}
	elsif ($votes{$voter,$group} == -1) {
	    $str .= "N";
	}
	else {
	    $str .= " ";
	}
    }

    if (! $tally) {
	$str =~ s/[YN]/./g;
    }

    if ($str eq "      ") {
	undef;
    }
    else {
	$str;
    }
}

sub parse_vote {
    local($vote) = @_;

    if ($vote =~ /yes/i) {
	1;
    }
    elsif ($vote =~ /no/i) {
	-1;
    }
    elsif ($vote =~ /abstain/i) {
	0;
    }
    else {
	die "Unknown vote $vote";
    }
}

sub address_sort {
    local(@sorted_votes);
    local($name, $address, $i);
    foreach $name (@_) {
	$address = &address_of($name);
	$address =~ tr/A-Z/a-z/;
	push(@sorted_votes, sprintf("%s\n%s", $address, $name));
    }
    @sorted_votes = sort @sorted_votes;
    foreach $i (0..$#sorted_votes) {
	$sorted_votes[$i] =~ s/.*\n//;
    }
    @sorted_votes;
}

sub address_of {
    local($_) = @_;
    
    if (/^.*\<(.*@.*)\>$/) {
	&rotate($1);
    }
    elsif (/^(.*[^ \t])[ \t]*\(.*\)$/) {
	&rotate($1);
    }
    else {
	$_;
    }
}

sub rotate {
    local($_) = $_[0];

    while (s/(.*!|^)([A-Za-z_]+)!([A-Za-z_]+)/$1$3%$2/) {}

    $_;
}

sub print_headers {
    local($last_column, @headers) = @_;
    local($max_length);
    local($start_column);
    local($vlines);
    local($i);
    local($_);

    for (@headers) {
	$max_length = length($_) if (length($_) > $max_length);
    }

    $start_column = $last_column - @headers - $max_length;

    while ($_ = pop @headers) {
	for (1..($start_column - 1)) {
	    print " ";
	}
	print $_;
	for ($i = $start_column + length($_); $i < $last_column - $vlines;
	     $i++) {
	    print "-";
	}
	print "+";
	for ($i = 0; $i < $vlines; $i++) {
	    print "|";
	}
	$vlines++;
	print "\n";
    }

    for ($i = 0; $i < $last_column - $vlines; $i++) {
	print " ";
    }

    for ($i = 0; $i < $vlines; $i++) {
	print "|";
    }

    print "\n";

    for ($i = 0; $i < $last_column - $vlines; $i++) {
	print " ";
    }

    for ($i = 0; $i < $vlines; $i++) {
	print "v";
    }

    print "\n";
}
