#!/usr/bin/perl -w

use strict;
use config;
use IPC::Open2;
use IO::Select;
use IO::Handle;

my $dbh = DBI->connect($::dsn, $::db_user_name, $::db_password);

my $errors = 1;
my $run = 0;

if (shift)
{
	score_all($dbh);
}

while (($errors gt 0) and ($run lt 9))
{
	$run++;
	print "\n*** Run " . $run . " ***\n";
	$errors = train_wrong($dbh);
	if ($errors gt 0)
	{
		print "\n*** Found " . $errors . " errors... rescoring ***\n";
		score_all($dbh);
	}
}

print "\n*** Performed $run runs ***\n";

sub train_wrong {
	my($dbh) = @_;

	my $sth = $dbh->prepare("SELECT msgid, body, flag FROM mail 
			WHERE ((flag = 'H') AND (score <= 0)) OR ((flag = 'S') AND (score >= 0)) AND body IS NOT NULL");

	$sth->execute();

	my @row;
	while ( @row = $sth->fetchrow_array ) {
		print $row[0] . "\n";
		my $as;
		if ($row[2] eq "ham") 
		{
			$as = "nonspam";
		}
		else
		{
			$as = "spam";
		}
		train($row[0], $row[1], $as, $dbh);
	}

	return $sth->rows;
}

sub score_all {
	my($dbh) = @_;
	my $sth = $dbh->prepare("SELECT msgid, body, flag FROM mail WHERE body IS NOT NULL");

	$sth->execute();

	my @row;
	while ( @row = $sth->fetchrow_array ) {
		#print $row[0] . "\n";
		my $score = 0;

		my $pid = open2(\*R, \*W, "/usr/share/crm114/mailfilter.crm -u $::path 2> /dev/null");
		$pid || die "did not work as expected:$!";
		
		my $io = IO::Select->new();
		$io->add(\*R);

		my $message = $row[1];
		my $msgid   = $row[0];
		
		print W "$message";
		close(W);

		while (<R>) 
		{
			if (/^X-CRM114-Status: .* \( pR: (.*) \)/)
			{	
				$score = $1;
			}
		}

		my $sth = $dbh->prepare("UPDATE mail SET score=? WHERE msgid=?");
		$sth->execute($score, $msgid);

	}
}

sub train {
	my($msgid, $message, $as, $dbh) = @_;

	open FH, "| /usr/share/crm114/mailfilter.crm -u $::path --learn$as > /dev/null";

	print FH "$message";
	close(FH);
}
