import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.*;
import java.io.*;

import org.javabip.spec.*;

import org.javabip.api.BIPActor;
import org.javabip.api.BIPEngine;
import org.javabip.api.BIPGlue;
import org.javabip.engine.factory.EngineFactory;
import org.javabip.exceptions.*;
import org.javabip.glue.GlueBuilder;
import org.javabip.glue.TwoSynchronGlueBuilder;
import org.junit.*;
import org.javabip.executor.JSONLogger;

import akka.actor.ActorSystem;

public class <%-className%> {

	  ActorSystem system;
		EngineFactory engineFactory;
		JSONLogger loggerJSON = JSONLogger.getLogger();

		@Before
		public void initialize() {
			system = ActorSystem.create("MySystem");
			engineFactory = new EngineFactory(system);
		}

		@After
		public void cleanup() {
			system.shutdown();
		}

		private BIPGlue createGlue(String bipGlueFilename) {
					BIPGlue bipGlue = null;

					InputStream inputStream;
					try {
						inputStream = new FileInputStream(bipGlueFilename);

						bipGlue = GlueBuilder.fromXML(inputStream);

					} catch (FileNotFoundException e) {

						e.printStackTrace();
			}
			return bipGlue;
}

		@Test
	  public void bipTest() throws BIPException, BIPEngineException {
				int noOfTransitions = 0;
				Map<String, String> componentIDsToNames = new HashMap<String, String>();
				Map<String, String> componentIDsToCardinalities = new HashMap<String, String>();
				Map<String, String> componentIDsToInstanceIDs = new HashMap<String, String>();

				<%for (var i=componentType.length; i>0;i--) {%>
					componentIDsToCardinalities.put("<%-componentType[i-1].path%>","<%-componentType[i-1].cardinalityValue%>");
					componentIDsToNames.put("<%-componentType[i-1].path%>","<%-componentType[i-1].name%>");
				<%}%>

				BIPGlue bipGlue = createGlue("<%-path%>/Glue.xml");

				BIPEngine engine = engineFactory.create("myEngine", bipGlue);

				<%var total = 0,
							ids = 0;%>
				<%for (var i = 0; i < componentType.length; i++) {
					for (var j = 0; j < componentType[i].cardinalityValue; j++) {%>
						<%-componentType[i].name%> component<%-componentType[i].name%><%-(total+j)%> = new <%-componentType[i].name%>("<%-(total+j)%>");
	          BIPActor actor<%-componentType[i].name%><%-(total+j)%> = engine.register(component<%-componentType[i].name%><%-(total+j)%>, "<%-(total+j)%>", true);
						<%ids+=total+j;%>
							<% if (j !== componentType[i].cardinalityValue-1) {%>
								<%ids+=',';%>
							<%}%>
					<%}%>
					componentIDsToInstanceIDs.put("<%-componentType[i].path%>","<%-ids%>");
					<%ids='';%>
					<%total=total+componentType[i].cardinalityValue;%>
				<%}%>

					loggerJSON.beginFirstCycle(componentIDsToNames, componentIDsToCardinalities, componentIDsToInstanceIDs);
					engine.start();
          engine.execute();

				  while(noOfTransitions < <%-noOfRequiredTransitions%> && engine.isEngineExecuting()) {
					try{
						Thread.sleep(2000);
					} catch (InterruptedException e) {
					 e.printStackTrace();
					}

					noOfTransitions = 0;
					<%total = 0;%>
					<%for (var i = 0; i < componentType.length; i++) {
						for (var j = 0; j < componentType[i].cardinalityValue; j++) {%>
							noOfTransitions += component<%-componentType[i].name%><%-total+j%>.noOfTransitions;
						<%}%>
						<%total=total+componentType[i].cardinalityValue;%>
					<%}%>
				}

				engine.stop();
				try {
				loggerJSON.printCycles("<%-path%>");
			} catch (FileNotFoundException e){
				e.printStackTrace();
			}
				engineFactory.destroy(engine);

		}
}
