import electric.xml.Document;
import electric.xml.Element;
import java.io.*;

class CPS {
	// We have to have all of these global variables because stupid Java
	// is a moron about scope, and I'm not about to write another 30 lines
	// of code to make up for Java's idiocy.
	long _milliseconds = 10000;
	int _count=0;
	boolean _running=true;
	CPS( int time ) {
		_milliseconds = time*1000;
	}

	float time( String name, final MyRunnable p ) {
		System.out.print(name+" for "+(_milliseconds/1000)+" seconds");
		System.out.flush();
		_count = 0;
		_running = true;
		p.init();
		Thread t = new Thread() {
			public void run() {
				while (_running) {
					p.run();
					_count++;
				}
			}
		};
		t.start();
		try{Thread.sleep(_milliseconds);}catch(Exception e){e.printStackTrace();}
		_running = false;
		System.out.print("\t\t");
		System.out.print(" ... "+_count+" calls");
		float cps = (float)_count / (float)(_milliseconds/1000);
		System.out.println(" ("+cps+"/s)");
		return cps;
	}
}

// WTF?!?  This is exactly why I've started writing everything
// in Ruby.  Java Just Plain Sucks.
interface MyRunnable extends Runnable { public void init(); }

public class flatbench {
	public static void main( String[] args ) {
		if (args.length > 0 && args[0].equals( "verify" )) System.exit(0);
		CPS cps = new CPS( 5 );

		try {
		cps.time( "Parsing file", new MyRunnable() {
				File f;
				public void init(){
					f = new File( "project.xml" );
				}
				public void run() {
					try{new Document(f);}catch(Exception e){e.printStackTrace();}
				}
			});

		cps.time( "adding new element", new MyRunnable() {
				Element element;
				public void init(){
					Document document = new Document();
					element = document.addElement( "x" );
				}
				public void run() {
					element.addElement(new Element( "x" ));
				}
			});

		cps.time( "document creation", new MyRunnable() {
				public void init(){}
				public void run() {
					Document doc = new Document();
					Element el = doc.addElement( "tag1" );
					el.setAttribute( "blah", "four" );

					Element tag2 = new Element( "tag2" );
					tag2.setAttribute( "some", "value" );
					doc.getRoot().addElement( tag2 );

					Element tag3 = new Element( "tag3" );
					tag2.addElement( tag3 );
				}
			});

		cps.time( "writing tree", new MyRunnable() {
				Document document;
				public void init() {
					File f = new File( "../docs/tutorial.xml" );
					try{document = new Document( f );}catch(Exception e){e.printStackTrace();}
				}
				public void run() {
					Writer w = new StringWriter();
					try{document.write( w );}catch(Exception e){e.printStackTrace();}
				}
			});

		System.out.println( "detecting children N/A" );

		cps.time( "xpath search", new MyRunnable()  {
				Document document;
				public void init() {
					File f = new File( "../docs/tutorial.xml" );
					try{document = new Document( f );}catch(Exception e){e.printStackTrace();}
				}
				public void run() {
					document.getElement( "overview/general/subsection[@title='Iterating']");
				}
			});

		cps.time( "parse big", new MyRunnable() {
				File f;
				public void init(){
					f = new File( "../documentation.xml" );
				}
				public void run() {
					try{new Document(f);}catch(Exception e){e.printStackTrace();}
				}
			});

			System.out.println( "stream parsing N/A" );
		} catch (Exception ioe) {
			ioe.printStackTrace();
		}
	}
}
