package fr.irisa.triskell.kermeta.builder;

import java.io.IOException;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.kermeta.io.KermetaUnit;

import ch.uzh.ifi.rerg.kextra.Event;
import ch.uzh.ifi.rerg.kextra.ExecutionTrace;
import ch.uzh.ifi.rerg.kextra.KExtraFactory;
import ch.uzh.ifi.rerg.kextra.KExtraPackage;
import ch.uzh.ifi.rerg.kextra.OperationCallEvent;
import ch.uzh.ifi.rerg.kextra.PropertyCallEvent;
import fr.irisa.triskell.kermeta.language.structure.Operation;
import fr.irisa.triskell.kermeta.language.structure.Property;
import fr.irisa.triskell.kermeta.launcher.AbstractKInterpreter;

public class TracingRuntimeMemory extends RuntimeMemory {

	// Tracing Events
	private ExecutionTrace trace;
	private KExtraFactory traceFactory;
	
	
	public TracingRuntimeMemory(KermetaUnit unit,
			AbstractKInterpreter interpreter) {
		super(unit, interpreter);
		
        traceFactory = KExtraFactory.eINSTANCE;
        trace = traceFactory.createExecutionTrace();
        
        
		
	}
	
	public void traceEvent(Event e)
	{
		trace.getEvents().add(e);
	}
	
	public ExecutionTrace getExecutionTrace()
	{
		return trace;
	}

	public void traceOperationCallEvent(EObject target, Operation op) {
		OperationCallEvent oce = traceFactory.createOperationCallEvent();
		oce.setTarget(target);
		oce.setOperation(op);
		oce.setFeature(op.getName());
		traceEvent(oce);
	}

	public void tracePropertyCallEvent(EObject target, Property prop) {
		PropertyCallEvent pce = traceFactory.createPropertyCallEvent();
		pce.setTarget(target);
		pce.setProperty(prop);
		pce.setFeature(prop.getName());
		traceEvent(pce);
	}

	public void save(URI traceModelURI) {
		ResourceSet rSet = new ResourceSetImpl();
		rSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", new XMIResourceFactoryImpl());
		rSet.getPackageRegistry().put(KExtraPackage.eNS_URI, KExtraPackage.eINSTANCE);
		
		Resource res = rSet.createResource(traceModelURI);
		res.getContents().add(trace);
		Event evt = trace.getEvents().get(0);
		
		if (evt instanceof OperationCallEvent) {
			OperationCallEvent oce = (OperationCallEvent) evt;
			res.getContents().add(EcoreUtil.getRootContainer(oce.getOperation()));
		}
		else if (evt instanceof PropertyCallEvent) {
			PropertyCallEvent pce = (PropertyCallEvent) evt;
			res.getContents().add(EcoreUtil.getRootContainer(pce.getProperty()));
		}
		
		try {
			res.save(null);
			trace.getEvents().clear();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	

}
