#!/usr/bin/perl -w

use strict;
use DBI;
use FileHandle;

#
# Gaurav S. Kc (c) 2001
# [gskc@cs.columbia.edu]
#
# Created: 16:50, 21-09-2001
# Tournament script for PPS project #1
#

my ($USER, $PASSWORD, $NUM_PLAYERS, $dbh, %deals, %players, $totalPlayers);
my @ROUNDS = (1, 3, 5, 10);
my $NUM_ITERATIONS = 64;

sub uidPassword {
  print "Enter your userid: ";
  $USER = <>; chomp $USER;
  print "Enter your password: ";
  $PASSWORD = <>; chomp $PASSWORD;

  print "Enter #players: ";
  $NUM_PLAYERS = <>; chomp $NUM_PLAYERS;

  print "\n @ for-each-ITERATION    * for-each-HAND    + for-each-SET    . for-each-GAME\n";
}

sub connect {
  my $sth;
  ($dbh = DBI->connect('DBI:mysql:pps:riverside', $USER, $PASSWORD))
    or die("Unable to connect to MySql");

  $sth = $dbh -> prepare("select count(*) from pps.players");
  $sth -> execute();
  $totalPlayers = $sth -> fetchrow();
  $sth -> finish();
}

sub disconnect {
  ($dbh -> disconnect()) or die("Unable to disconnect from MySql");
  print "\n";
}

sub setupDeals {
  my ($sth, $did, $gameState);
  $sth = $dbh -> prepare("select deal_id, gameState from pps.deals where numPl=$NUM_PLAYERS");
  $sth -> execute();
  %deals = ();
  while (($did, $gameState) = $sth -> fetchrow()) {
    $deals{$did} = $gameState;
  }
  $sth -> finish();
}

sub setupSets {
  my ($sth, $pName, $sbm_id, $i);
  %players = ();
  for ($i=0; $i<$NUM_PLAYERS; $i++) {
    $sth = $dbh -> prepare("select sbm_id, name from pps.players where sbm_id=".(1 + int(rand($totalPlayers))));
    $sth -> execute();
    ($sbm_id, $pName) = $sth -> fetchrow();
    $players{$i} = "$sbm_id-$pName";
    $sth -> finish();
  }
}

sub executeJava {
  my ($sth, $result, @result, $i, %seat2PlayerMapping);
  my ($deal_id, $gameState, $numRounds, $iter, $perm) = @_;

  my $execStr = "java -classpath /home/gskc/html/pps/tournament/lib proj1.GPoker -nv nr $numRounds -g $gameState ";
  my $logFile = "logs/error_p$NUM_PLAYERS"."_i$iter"."_r$numRounds"."_p$perm.log";

  $i = 0;
  foreach (keys %players) {
    my ($sbm_id, $pName) = split(/-/, $players{$_});
    $execStr .= "-p $pName ";
    $seat2PlayerMapping{$i} = $sbm_id;
    $i++;
  }

  open(PROC, "$execStr 2> $logFile | tail -1 |");
  $result = <PROC>;
  
  if (defined($result) && $result =~ /(\d:\d\t)+/) {
    chomp $result;
  } else {
    open(LOG, ">>$logFile") and print LOG "\nGame did not succeed normally :(\n\$deal_id: $deal_id, \$gameState: $gameState, \$numRounds: $numRounds, \$logFile: $logFile\n\$execStr: $execStr\n" and close LOG;
    print "\n$logFile: $execStr\n";
    return;
  }

  # print "\$execStr: $execStr\n"; print "\$gameState: $gameState\n"; print "\$result: $result\n";

  @result = split(/\t/, $result);
  $result = "";

  $i = 0;
  foreach (@result) {
    my $sbm_id;
    my ($seat, $score) = split(/:/, $_);
    last unless defined($seat);

    $sbm_id = $seat2PlayerMapping{$seat};
    $sth = $dbh -> prepare("insert into pps.scores values (null, null, $deal_id, $sbm_id, $seat, $score, $numRounds)");
    $sth -> execute();
    $sth -> finish();
  }
}

sub rotatePlayerHash {
  my $key;
  my %tmpHash = ();
  my $size = keys %players;
  foreach $key (keys %players) {
    $tmpHash{($key+1)%$size} = $players{$key};
  }
  %players = %tmpHash;
}

sub main {
  my $n;
  &uidPassword;
  &connect;
  
  &setupDeals;
  for ($n=0; $n<$NUM_ITERATIONS; $n++) {

    print "\n@"; STDOUT -> autoflush();
    foreach (keys %deals) {
      my $numRounds;
      my ($deal_id, $gameState) = ($_, $deals{$_});
    
      print "\n - *"; STDOUT -> autoflush();
      foreach $numRounds (@ROUNDS) {
        my ($i, $MAX);
        &setupSets;
        $MAX = keys(%players);
        
        print "+"; STDOUT -> autoflush();
        for ($i=0; $i<$MAX; $i++) {
    
          print "."; STDOUT -> autoflush();
          &executeJava($deal_id, $gameState, $numRounds, $n, $i);
          &rotatePlayerHash;
        }
      }
    }
  }

  &disconnect;
}

&main;
