package scg.tournament;


import java.io.File;
import java.util.Date;
import java.util.Hashtable;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import scg.exception.AddTournamentException;


public class TestTournamentManager {
	private final String USER_STATE_FILE = "TournamentStates.dat";
	
	private final String GOOD_CONFIG = 
		"scg_config[" +
		"domain: hsr.HSRDomain " +
		"protocols: scg.protocol.ForAllExists scg.protocol.ExistsForAll " +
		"tournamentStyle: full round-robin " +
		"turnDuration: 60 " +
		"maxNumAvatars: 20 " +
		"minStrengthening: 0.01 " +
		"initialReputation: 100.0 " +
		"maxReputation: 10000.0 " +
		"reputationFactor: 0.4 " +
		"minProposals: 1 " +
		"maxProposals: 20 " +
		"numRounds: 20 " +
		"proposedClaimMustBeNew: true " +
		"minConfidence: 0.1 ] " +
		"hsr.HSRConfig {{ hsr_config[maxN: 1000000 ] }}";
	
	private final String BAD_CONFIG = 
		"scg_config[" +
		"domain: hsr.HSRDomain " +
		"protocols: scg.protocol.ForAllExists scg.protocol.ExistsForAll " +
		"tournamentStyle: full round-robin " +
		"turnDuration: 60 " +
		"initialReputation: 100.0 " +
		"maxReputation: 10000.0 " +
		"reputationFactor: 0.4 " +
		"minProposals: 1 " +
		"maxProposals: 20 " +
		"numRounds: 20 " +
		"proposedClaimMustBeNew: true " +
		"minConfidence: 0.1 ] " +
		"hsr.HSRConfig {{ hsr_config[maxN: 1000000 ] }}";
	
	@Before
    public void setUp() {
		DeleteTournamentAndUserDataFiles();
    }

    @After
    public void tearDown() {
    	DeleteTournamentAndUserDataFiles();
    }
	
	@Test
	public void AddTournamentTest() throws scg.ParseException, AddTournamentException{
		
		TournamentManager tm = new TournamentManager();
		
		int tournamentId = tm.addTournament("test", GOOD_CONFIG, new Date());
		
		// Make sure the right ID is used
		Assert.assertEquals(tournamentId, 1);
		Assert.assertEquals(tm.getState().size(), 1);
		
		// Make sure the tournament exists
		TournamentSetup ts = tm.getTournament(tournamentId);
		Assert.assertEquals(ts.getName(), "test");
		
		// Make sure the file was saved to disk
		File tournamentFile = new File(USER_STATE_FILE);
		Assert.assertTrue(tournamentFile.exists());
		
	}
	
	@Test
	public void AddAndLoadTournamentTest() throws scg.ParseException, AddTournamentException{
		
		TournamentManager tm = new TournamentManager();
		
		int tournamentId = tm.addTournament("test", GOOD_CONFIG, new Date());
		
		// Make sure the right ID is used
		Assert.assertEquals(tournamentId, 1);
		Assert.assertEquals(tm.getState().size(), 1);
		
		// Make sure the tournament exists
		TournamentSetup ts = tm.getTournament(tournamentId);
		Assert.assertEquals(ts.getName(), "test");
		
		// Make sure the file was saved to disk
		File tournamentFile = new File(USER_STATE_FILE);
		Assert.assertTrue(tournamentFile.exists());
		
		// Now load up a new TM, it should read from disk.
		TournamentManager tm2 = new TournamentManager();
		
		Assert.assertEquals(tm.getState().size(), 1);
		
		// Make sure the tournament exists
		TournamentSetup ts2 = tm.getTournament(tournamentId);
		Assert.assertEquals(ts2.getName(), "test");
	}
	
	@Test
	public void EnrollUserInTournamentTest() throws scg.ParseException, AddTournamentException{
		
		TournamentManager tm = new TournamentManager();
		
		int tournamentId = tm.addTournament("test", GOOD_CONFIG, new Date());
		
		// Make sure if we try to add a user to a tournamnet that doesn't exist, it fails
		boolean result = tm.enrollPlayer(2, "testuser", "password");
		Assert.assertFalse(result);
		
		result = tm.enrollPlayer(1, "testuser", "password");
		Assert.assertTrue(result);
		
		Hashtable<String, String> enrolledPlayers = tm.getTournament(1).getEnrolledPlayers();
		
		Assert.assertEquals(enrolledPlayers.size(), 1);
		Assert.assertTrue(enrolledPlayers.containsKey("testuser"));
	}
	
	private void DeleteTournamentAndUserDataFiles(){
		File file = new File(USER_STATE_FILE);
		if (file.exists()){
			file.delete();
		}
		
		file = new File("UserState.dat");
		if (file.exists()){
			file.delete();
		}
	}
}
