#! /usr/bin/perl
use strict;
use warnings;
use DBI;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
require 'foosball.pm';
no warnings 'once';

my $dryrun = 0;
if (defined($ARGV[0])) {
	$dryrun = 1;
	$foosball::initial_rd = $ARGV[0];
	$foosball::c = $ARGV[1];
}

my $dbh = foosball::db_connect();
$dbh->{AutoCommit} = 0;

$dbh->do('delete from single_rating') unless $dryrun;

my %ratings = ();
my $q = $dbh->prepare('select *,extract(epoch from gametime) as eptime from single_results order by gametime');
$q->execute;

# Combined log-likelihood
my $cll = 0.0;

while (my $ref = $q->fetchrow_hashref) {
	for my $user (($ref->{'username1'}, $ref->{'username2'})) {
		if (!exists($ratings{$user})) {
			$ratings{$user} = [ $foosball::initial_rating, $foosball::initial_rd, 0 ];
		}
	}
	
	my $rating1 = $ratings{$ref->{'username1'}}->[0];
	my $rd1 = $ratings{$ref->{'username1'}}->[1];
	my $age1 = $ref->{'eptime'} - $ratings{$ref->{'username1'}}->[2];

	my $rating2 = $ratings{$ref->{'username2'}}->[0];
	my $rd2 = $ratings{$ref->{'username2'}}->[1];
	my $age2 = $ref->{'eptime'} - $ratings{$ref->{'username2'}}->[2];

	my $score1 = $ref->{'score1'};
	my $score2 = $ref->{'score2'};

	$rd1 = foosball::apply_aging($rd1, $age1 / 86400.0);
	$rd2 = foosball::apply_aging($rd2, $age2 / 86400.0);

	my ($newr1, $newrd1, $likelihood) = foosball::calc_rating($rating1, $rd1, $rating2, $rd2, $score1, $score2);
	my ($newr2, $newrd2) = foosball::calc_rating($rating2, $rd2, $rating1, $rd1, $score2, $score1);

	$cll += log($likelihood);

	unless ($dryrun) {
		printf("%-10s - %-10s: %u - %u, new ratings %u/%u %u/%u [$likelihood]\n",
			$ref->{'username1'}, $ref->{'username2'}, $ref->{'score1'},
			$ref->{'score2'}, $newr1, $newrd1, $newr2, $newrd2);
		$dbh->do('insert into single_rating values (?,?,?,?,?)', undef,
			$ref->{'username1'}, $ref->{'gametime'}, $newr1, $newrd1, $newr1-$rating1);
		$dbh->do('insert into single_rating values (?,?,?,?,?)', undef,
			$ref->{'username2'}, $ref->{'gametime'}, $newr2, $newrd2, $newr2-$rating2);
	}

	$ratings{$ref->{'username1'}} = [ $newr1, $newrd1, $ref->{'eptime'} ];
	$ratings{$ref->{'username2'}} = [ $newr2, $newrd2, $ref->{'eptime'} ];
}

$dbh->commit unless $dryrun;
$dbh->disconnect;

printf "\nCombined negative log-likelihood (smaller value means a better model): %f\n",
	-$cll;
