package Tools;
import java.io.*;
import java.util.StringTokenizer;

/**
 * We use this subclass so it's easier to catch these in the debugger
 * without seeing every other RuntimeException.
 */
class AssertionFailedException
	extends RuntimeException {
	AssertionFailedException(String s) {
		super(s);
	}
}

/**
 * A simple assertion-checking call that throws a RuntimeException if
 * the check fails. Java provides no way to ``compile these out,'' so
 * you'll always be doing whatever work you do to generate the boolean
 * condition you're testing. But by using a consistent method call, you
 * can later mechanically remove the checks for performance. Using this
 * method is just a way of indicating ``this is an optional test to
 * make debugging easier.''
 */
public class Assert {
	static boolean enabled = true;

	public static boolean getEnabled() {
		return enabled;
	}

	public static void assert(boolean premise) {
		if (premise) {
			return;	// Don't trace the stack for true premises!
		}

		// Use the exception stack trace mechanism to figure out
		// what code made the assertion that failed. This would be
		// a bunch easier if Java would return the stack in some more
		// useful form.
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		PrintWriter pw = new PrintWriter(baos);
		Throwable t = new Throwable();
		t.printStackTrace(pw);
		pw.close();
		StringTokenizer st = new StringTokenizer(baos.toString(), "\n");
		st.nextToken();	// discard exception name
		st.nextToken();	// discard this stack frame (want parent)
		String failure = st.nextToken().substring(1);
			// skip initial tab
			
		assert(premise, "Assertion failed "+failure);
	}

	public static void assert(boolean premise, String s) {
		if (enabled && !premise) {
			// take a stack trace of this to find out which one...
			throw new AssertionFailedException(s);
		}
	}
}
