package boxpusher.tests;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;

import gdi.ws0809.test.SokobanTest;
import gdi.ws0809.test.SokobanTestAdapter;

import java.io.File;
import java.io.IOException;

import org.junit.Test;

import boxpusher.exceptions.LevelSyntaxIsIncorrectException;
import boxpusher.game.Direction;
import boxpusher.game.LevelDeadlockChecker;
import boxpusher.game.Levelsolver;

public class LevelsolverTest {
	Levelsolver solver = null;
	String pathLevel = "data" + File.separator + "levels" + File.separator;
	String pathGdILab = "data" + File.separator + "levelsets" + File.separator
			+ "GdI Lab" + File.separator;
	String pathDillmann = "data" + File.separator + "levelsets"
			+ File.separator + "GdI Portal dillmann" + File.separator;
	String pathShaggath = "data" + File.separator + "levelsets"
			+ File.separator + "Shaggath V2009" + File.separator;

	private boolean testThis = false;
	SokobanTest game = new SokobanTestAdapter();

	private Levelsolver setupSolver(String level, boolean fixme) {
		LevelDeadlockChecker.longToString = true;
		/*
		 * Switch this flag to true to try all levels, but levels which are
		 * marked as fixme are very likly case a stack or heapspace overflow
		 */
		if (false || !fixme) {
			try {
				game = new SokobanTestAdapter();
				game.loadLevel(new File(level));
				testThis = true;
			} catch (Exception e) {
				e.printStackTrace();
				fail();
			}
		} else {
			fail();
			assertTrue(true);
		}
		return solver;
	}

	private boolean startSolver() {
		if (testThis) {
			try {
				testThis = false;
				String moves = game.solveLevel(Integer.MAX_VALUE);
				if (moves == null) {
					return false;
				} else {
					return true;
				}
			} catch (Exception e) {
				e.printStackTrace();
				fail();
			}
		} else {
			fail();
		}
		return false;
	}

	@Test
	public void testSolveBoxPusher() {
		// FIXME
		setupSolver(pathLevel + "boxpusher.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testExtendedDeadlock() {
		setupSolver(pathLevel + "deadlocked.txt", false);
		assertFalse(game.isDeadlock());
		game.moveWorker('R');
		assertTrue(game.isDeadlock());
	}

	@Test
	public void testSolveGdILevel01() {
		setupSolver(pathGdILab + "level_01.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel02() {
		setupSolver(pathGdILab + "level_02.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel03() {
		setupSolver(pathGdILab + "level_03.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel04() {
		setupSolver(pathGdILab + "level_04.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel05() {
		setupSolver(pathGdILab + "level_05.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel06() {
		setupSolver(pathGdILab + "level_06.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel07() {
		setupSolver(pathGdILab + "level_07.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel08() {
		setupSolver(pathGdILab + "level_08.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel09() {
		setupSolver(pathGdILab + "level_09.txt", false);
		assertFalse(startSolver());
	}

	@Test
	public void testSolveGdILevel10() {
		setupSolver(pathGdILab + "level_10.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel11() {
		// FIXME
		setupSolver(pathGdILab + "level_11.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel12() {
		// FIXME
		setupSolver(pathGdILab + "level_12.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel13() {
		// FIXME
		setupSolver(pathGdILab + "level_13.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel14() {
		setupSolver(pathGdILab + "level_14.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel15() {
		// FIXME
		setupSolver(pathGdILab + "level_15.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel16() {
		setupSolver(pathGdILab + "level_16.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel17() {
		setupSolver(pathGdILab + "level_17.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel18() {
		setupSolver(pathGdILab + "level_18.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel19() {
		// FIXME
		setupSolver(pathGdILab + "level_19.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel20() {
		// FIXME
		setupSolver(pathGdILab + "level_20.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel21() {
		// FIXME
		setupSolver(pathGdILab + "level_21.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel22() {
		// FIXME
		setupSolver(pathGdILab + "level_21.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel23() {
		// FIXME
		setupSolver(pathGdILab + "level_23.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel24() {
		// FIXME
		setupSolver(pathGdILab + "level_24.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel25() {
		// FIXME
		setupSolver(pathGdILab + "level_25.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel26() {
		// FIXME
		setupSolver(pathGdILab + "level_26.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel27() {
		// FIXME
		setupSolver(pathGdILab + "level_27.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveGdILevel28() {
		// FIXME
		setupSolver(pathGdILab + "level_28.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath01() {
		setupSolver(pathShaggath + "level_01.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath02() {
		setupSolver(pathShaggath + "level_02.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath03() {
		setupSolver(pathShaggath + "level_03.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath04() {
		setupSolver(pathShaggath + "level_04.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath05() {
		setupSolver(pathShaggath + "level_05.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath06() {
		setupSolver(pathShaggath + "level_06.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath07() {
		setupSolver(pathShaggath + "level_07.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath08() {
		setupSolver(pathShaggath + "level_08.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath09() {
		// FIXME
		setupSolver(pathShaggath + "level_09.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath10() {
		setupSolver(pathShaggath + "level_10.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath11() {
		// FIXME
		setupSolver(pathShaggath + "level_11.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath12() {
		setupSolver(pathShaggath + "level_12.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath13() {
		setupSolver(pathShaggath + "level_13.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath14() {
		// FIXME
		setupSolver(pathShaggath + "level_14.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath15() {
		setupSolver(pathShaggath + "level_15.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath16() {
		setupSolver(pathShaggath + "level_16.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath17() {
		// FIXME
		setupSolver(pathShaggath + "level_17.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath18() {
		setupSolver(pathShaggath + "level_18.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath19() {
		setupSolver(pathShaggath + "level_19.txt", false);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveShaggath20() {
		// FIXME
		setupSolver(pathShaggath + "level_20.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveDillmann01() {
		// FIXME
		setupSolver(pathDillmann + "level_01.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveDillmann02() {
		// FIXME
		setupSolver(pathDillmann + "level_02.txt", true);
		assertTrue(startSolver());
	}

	@Test
	public void testSolveDillmann03() {
		// FIXME
		setupSolver(pathDillmann + "level_03.txt", true);
		assertTrue(startSolver());
	}

	/**
	 * This testcase can be run standalone from the console with
	 * <p>
	 * Additional possible parameters:<br />
	 * <ul>
	 * <li>-Xms256M -Xmx512M <em>allocate more memory</em></li>
	 * </ul>
	 * <pre>
	 * java -classpath /home/david/Projekte/Java/Praktikum/bin:/usr/share/java/junit4.jar boxpusher.tests.LevelsolverTest
	 * </pre>
	 * 
	 * </p>
	 */
	public static void main(String args[]) {
		org.junit.runner.JUnitCore.main(LevelsolverTest.class.getName());
	}
}
