package geiger;

public class StandaloneTests {
	public static void main(String[] args) throws Exception {
		// Integer.MAX_VALUE = 2147483647
		System.err.println("Max. integer value = " + Integer.MAX_VALUE);

		long max = 0;
		int i = 0;

		Simulation.div3(8487297);

		//Testing the 'div3()' function
		//Q - 1611006049: -537002017 not equal to pre-computed 537002016 (max=1611006048)
		//PASSED - tested up to 1611006048
		System.err.println("Testing the 'div3()' function");
		max = 0;
		i = 0;
		while (true) {
			int result = Simulation.div3(i);
			int computedQ = i / 3;
			if (computedQ != result) {
				System.err.println("Q - " + i + ": " + result + " not equal to pre-computed " + computedQ + " (max=" + max + ")");
				break;
			} else {
				max = i;
			}
			if (max == Integer.MAX_VALUE)
				break;
			i++;
		}
		System.err.println("PASSED - tested up to " + max);

		//Testing the 'div5()' function
		//Q - 1431655766: -286331153 not equal to pre-computed 286331153 (max=1431655765)
		//PASSED - tested up to 1431655765
		System.err.println("Testing the 'div5()' function");
		max = 0;
		i = 0;
		while (true) {
			int result = Simulation.div5(i);
			int computedQ = i / 5;
			if (computedQ != result) {
				System.err.println("Q - " + i + ": " + result + " not equal to pre-computed " + computedQ + " (max=" + max + ")");
				break;
			} else {
				max = i;
			}
			if (max == Integer.MAX_VALUE)
				break;
			i++;
		}
		System.err.println("PASSED - tested up to " + max);

		//Testing the 'div7()' function
		//Q - 1908874354: -272696337 not equal to pre-computed 272696336 (max=1908874353)
		//PASSED - tested up to 1908874353
		System.err.println("Testing the 'div7()' function");
		max = 0;
		i = 0;
		while (true) {
			int result = Simulation.div7(i);
			int computedQ = i / 7;
			if (computedQ != result) {
				System.err.println("Q - " + i + ": " + result + " not equal to pre-computed " + computedQ + " (max=" + max + ")");
				break;
			} else {
				max = i;
			}
			if (max == Integer.MAX_VALUE)
				break;
			i++;
		}
		System.err.println("PASSED - tested up to " + max);

		//Testing the 'div11()' function
		//Q - 1184818565: 40536315 not equal to pre-computed 107710778 (max=1184818564)
		//PASSED - tested up to 1184818564
		System.err.println("Testing the 'div11()' function");
		max = 0;
		i = 0;
		while (true) {
			int result = Simulation.div11(i);
			int computedQ = i / 11;
			if (computedQ != result) {
				System.err.println("Q - " + i + ": " + result + " not equal to pre-computed " + computedQ + " (max=" + max + ")");
				break;
			} else {
				max = i;
			}
			if (max == Integer.MAX_VALUE)
				break;
			i++;
		}
		System.err.println("PASSED - tested up to " + max);

		//Testing the 'div10()' function
		//PASSED - tested up to 756
		System.err.println("Testing the 'div10()' function");
		max = 0;
		for (i = 0; i < 512; i++) { // 512 because 'hasCarry'
			for (int toAdd = 0; toAdd < 246; toAdd++) { // <247 will fail
				char[] result = Simulation.div10AndMod10((char) (i > 255 ? i - 256 : i), (i > 255 ? true : false), (char) toAdd);
				int computedQ = (i + toAdd) / 10;
				int computedR = (i + toAdd) % 10;
				if (computedQ != result[0]) {
					throw new Exception("Q - " + i + "/" + toAdd + ": " + ((int) result[0]) + " not equal to pre-computed " + computedQ + " (max=" + max + ")");
				}
				if (computedR != result[1]) {
					throw new Exception("R - " + i + "/" + toAdd + ": " + ((int) result[1]) + " not equal to pre-computed " + computedR + " (max=" + max + ")");
				}
				if (i + toAdd > max)
					max = i + toAdd;
			}
		}
		System.err.println("PASSED - tested up to " + max);

		//Testing the 'decode20approx()' function, NOT clean one
		//PASSED - tested up to 1048576
		System.err.println("Testing the 'decode20approx()' function, NOT clean one");
		max = 0;
		// 1048576 = 2^20 => should display 0
		for (i = 0; i < 1048577; i++) { //2850
			long[] result = Simulation.decode20approx(i);
			long computed = result[5] * 100000 + result[4] * 10000 + result[3] * 1000 + result[2] * 100 + result[1] * 10 + result[0];
			if (i < 1048576) {
				if (i != computed) {
					throw new Exception(result[5] + "." + result[4] + "." + result[3] + "." + result[2] + "." + result[1] + "." + result[0] + " not equal to pre-computed " + i + " (max=" + max + ")");
				}
			} else {
				if (i == computed) {
					throw new Exception("i == computed");
				}
			}
			if (i > max)
				max = i;
		}
		System.err.println("PASSED - tested up to " + max);

		new Thread() {
			@Override
			public void run() {
				try {
					Simulation.run();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}.start();

		new Thread() {
			@Override
			public void run() {
				// Natural radioactivity
				try {
					//Simulation.impulseGenerator(27); // --> 0.18@10s, no I
					//Simulation.impulseGenerator(45); // --> 0.27@10s, no I
					//Simulation.impulseGenerator(100); // --> 0.64@10s, no I
					//Simulation.impulseGenerator(200); // --> 1.32@10s, no I
					//Simulation.impulseGenerator(300); // --> 1.96@10s, 1.9@I
					Simulation.impulseGenerator(1000); // --> 6.64@10s, 6.6@I
					//Simulation.impulseGenerator(2000); // --> 13.32@10s, 13@I
					//Simulation.impulseGenerator(20000); // --> 117s@10s, 116@I
					//Simulation.impulseGenerator(50000); // --> no 10s, 370@I
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();

		// Dumb ass Eclipse :)
		boolean condition = true;
		while (condition) {
			Thread.sleep(1000);
		}
	}
}
