package combo;


public class CombinationLockTestManual {
	
	private int success, failure;
	
	private CombinationLock lock00;
	private CombinationLock lock01;
	private CombinationLock lock12;
	private CombinationLock lock99;
	
	public static void main(String[] args) {
		CombinationLockTestManual tester = new CombinationLockTestManual();
		
		tester.runTests();
	}
	
	public CombinationLockTestManual() {
		success = 0;
		failure = 0;
	}
	
	private void verify(boolean test, String message) {
		if (!test) {
			System.out.println("Verification failed: " + message);
			failure++;
		} else {
			success++;
		}
	}
	
	private void setUp() {
		lock00 = new CombinationLock(0);
		lock01 = new CombinationLock(1);
		lock12 = new CombinationLock(12);
		lock99 = new CombinationLock(99);
	}

	private void testInitialState() {
		setUp();
		verify(!lock12.isOpen(), "Initially closed: lock 12");
	}
	
	private void testOpenLock() {
		setUp();
		lock12.enter(1);
		lock12.enter(2);
		verify(lock12.isOpen(), "Open lock: lock 12");
	}
	
	private void testCorrectCombination() {
		setUp();
		
		verify(!lock00.isOpen(), "Lock closed: lock 00");
		lock00.enter(0);
		lock00.enter(0);
		verify(lock00.isOpen(), "Correct comb: lock 00");
		
		verify(!lock01.isOpen(), "Lock closed: lock 01");
		lock01.enter(0);
		lock01.enter(1);
		verify(lock01.isOpen(), "Correct comb: lock 01");
		
		verify(!lock12.isOpen(), "Lock closed: lock 12");
		lock12.enter(1);
		lock12.enter(2);
		verify(lock12.isOpen(), "Correct comb: lock 12");
		
		verify(!lock99.isOpen(), "Lock closed: lock 99");
		lock99.enter(9);
		lock99.enter(9);
		verify(lock99.isOpen(), "Correct comb: lock 99");
	
	}
		
	private void testIncorrectCombination() {
		setUp();
		
		lock00.enter(1);
		lock00.enter(0);
		verify(!lock00.isOpen(), "Incorrect comb: lock 00");
		
		lock01.enter(1);
		lock01.enter(1);
		verify(!lock01.isOpen(), "Incorrect comb: lock 01");
		
		// Backwards.
		lock12.enter(2);
		lock12.enter(1);
		verify(!lock12.isOpen(), "Incorrect comb: lock 12");
		
		lock99.enter(0);
		lock99.enter(9);
		verify(!lock99.isOpen(), "Incorrect comb: lock 99");
	}
	
	private void testFirstDigitTwice() {
		setUp();
		
		lock01.enter(0);
		lock01.enter(0);
		verify(!lock01.isOpen(), "1st, 1st: lock 01");
		lock01.enter(1);
		verify(lock01.isOpen(), "1st, 1st, 2nd: lock 01");
		
		lock12.enter(1);
		lock12.enter(1);
		verify(!lock12.isOpen(), "1st, 1st: lock 12");
		lock12.enter(2);
		verify(lock12.isOpen(), "1st, 1st, 2nd: lock 12");
	}
	
	private void testCorrectFirstDigit() {
		setUp();
		
		lock01.enter(0);
		lock01.enter(2);
		lock01.enter(1);
		verify(!lock01.isOpen(), "1st, X, 2nd: lock 01");
		
		lock12.enter(1);
		lock12.enter(0);
		lock12.enter(2);
		verify(!lock12.isOpen(), "1st, X, 2nd: lock 12");
	}
	
	private void testCloseOpenedLock() {
		setUp();
		lock12.enter(1);
		lock12.close();
		verify(!lock12.isOpen(), "close opened: lock 12");
		lock12.enter(2);
		verify(!lock12.isOpen(), "reset opened: lock 12");
	}
	
	private void testCloseResetLock() {
		setUp();
		lock12.close();
		verify(!lock12.isOpen(), "close reset: lock 12");
	}
	
	private void testCloseAlmostOpenLock() {
		setUp();
		
		lock00.enter(0);
		lock00.close();
		lock00.enter(0);
		verify(!lock00.isOpen(), "reset almost open: lock 00");
		
		lock12.enter(1);
		lock12.close();
		lock12.enter(2);
		verify(!lock12.isOpen(), "reset almost open: lock 12");

		lock01.enter(0);
		lock01.close();
		lock01.enter(1);
		verify(!lock01.isOpen(), "reset almost open: lock 01");
	}
	
	private void runTests() {
		testInitialState();
		testOpenLock();
		testCorrectCombination();
		testIncorrectCombination();
		testFirstDigitTwice();
		testCorrectFirstDigit();
		testCloseOpenedLock();
		testCloseResetLock();
		testCloseAlmostOpenLock();
		
		System.out.println("All tests completed.  " 
				+ success + " tests passed.  " 
				+ failure + " tests failed.");
	}
}

