/*******************************************************************************
 * Copyright (c) 2014, 2018 Willink Transformations Ltd., University of York and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Adolfo Sanchez-Barbudo Herrera (University of York) - initial API and implementation
 *******************************************************************************/
package org.eclipse.qvtd.cs2as.compiler.tests;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

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.jdt.annotation.NonNull;
import org.eclipse.ocl.pivot.internal.resource.StandaloneProjectMap;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.OCL;
import org.eclipse.ocl.xtext.completeocl.CompleteOCLStandaloneSetup;
import org.eclipse.qvtd.compiler.DefaultCompilerOptions;
import org.eclipse.qvtd.pivot.qvtimperative.ImperativeModel;
import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTransformation;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.BasicQVTiExecutor;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiEnvironmentFactory;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiIncrementalExecutor;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiTransformationExecutor;
import org.eclipse.qvtd.runtime.evaluation.TransformationExecutor;
import org.eclipse.qvtd.runtime.evaluation.Transformer;
import org.eclipse.qvtd.xtext.qvtbase.tests.LoadTestCase;
import org.eclipse.qvtd.xtext.qvtimperative.QVTimperativeStandaloneSetup;
import org.junit.Before;
import org.junit.Test;

/**
 * @author asbh500
 *
 *
 */
public class ExecutionBenchmarks extends LoadTestCase {

	private static URI TESTS_BASE_URI = URI.createPlatformResourceURI("org.eclipse.qvtd.cs2as.compiler.tests/src/org/eclipse/qvtd/cs2as/compiler/tests/models", true);
	private static int NUM_OF_EXECUTIONS = 10;

	protected class MyQVT extends OCL
	{
		public MyQVT(@NonNull QVTiEnvironmentFactory environmentFactory) {
			super(environmentFactory);
		}

		public @NonNull BasicQVTiExecutor createEvaluator(@NonNull ImperativeTransformation transformation) {
			return new QVTiIncrementalExecutor(getEnvironmentFactory(), transformation, QVTiIncrementalExecutor.Mode.LAZY);
		}

		public @NonNull TransformationExecutor createEvaluator(@NonNull Class<? extends Transformer> txClass) throws ReflectiveOperationException {
			return new QVTiTransformationExecutor(getEnvironmentFactory(), txClass);
		}
		@Override
		public @NonNull QVTiEnvironmentFactory getEnvironmentFactory() {
			return (QVTiEnvironmentFactory) super.getEnvironmentFactory();
		}
	}

	@Override
	@Before
	public void setUp() throws Exception {
		super.setUp();
		QVTimperativeStandaloneSetup.doSetup();
		CompleteOCLStandaloneSetup.doSetup(); // To be able to add QVTimperative.ocl validation
	}

	protected @NonNull MyQVT createQVT() throws Exception {
		return new MyQVT(new QVTiEnvironmentFactory(getTestProjectManager(), null));
	}

	@Test
	public void testExample2_Interpreted() throws Exception {


		Map<String, List<Integer>> results =  new LinkedHashMap<String, List<Integer>>();
		for (int i = 0; i < NUM_OF_EXECUTIONS; i++){
			MyQVT myQVT = createQVT();
			ResourceSet resourceSet = myQVT.getResourceSet();
			resourceSet.getResource(URI.createURI(example2.classes.ClassesPackage.eNS_URI, true), true);
			resourceSet.getResource(URI.createURI(example2.classescs.ClassescsPackage.eNS_URI, true), true);
			resourceSet.getResource(URI.createURI(example2.classes.lookup.EnvironmentPackage.eNS_URI, true), true);

			URI baseURI = TESTS_BASE_URI.appendSegment("example2");
			URI txURI = baseURI.appendSegment("classescs2as.qvtias");

			ImperativeTransformation qvtiTransf = getTransformation(myQVT.getMetamodelManager().getASResourceSet(), txURI);
			assert qvtiTransf != null;
			trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model1", results);
			trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model2", results);
			trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model3", results);
			trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model4", results);
			trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model5", results);
			trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model6", results);
			trackExample_Interpreted(myQVT, qvtiTransf, baseURI, "model7", results);
			myQVT.dispose();

		}


		processResults("Example2_Interpreted.csv" ,results);
	}



	@Test
	public void testExample2_CG() throws Exception {

		Map<String, List<Integer>> results =  new LinkedHashMap<String, List<Integer>>();
		for (int i = 0; i < NUM_OF_EXECUTIONS; i++){
			MyQVT myQVT = createQVT();

			URI baseURI = TESTS_BASE_URI.appendSegment("example2");
			@SuppressWarnings("unchecked")
			Class<? extends Transformer> txClass = (Class<? extends Transformer>) Class.forName("cg._classescs2as_qvtm_qvtcas.classescs2as_qvtm_qvtcas");
			assert txClass != null;
			trackExample_CG(myQVT, txClass, baseURI, "model1", results);
			trackExample_CG(myQVT, txClass, baseURI, "model2", results);
			trackExample_CG(myQVT, txClass, baseURI, "model3", results);
			trackExample_CG(myQVT, txClass, baseURI, "model4", results);
			trackExample_CG(myQVT, txClass, baseURI, "model5", results);
			trackExample_CG(myQVT, txClass, baseURI, "model6", results);
			trackExample_CG(myQVT, txClass, baseURI, "model7", results);

			myQVT.dispose();

		}

		processResults("Example2_CG.csv" ,results);
	}

	//	@Test
	//	public void testExample2_CG_withLookupVisitor() throws Exception {
	//
	//		Map<String, List<Integer>> results =  new LinkedHashMap<String, List<Integer>>();
	//
	//		for (int i = 0; i < NUM_OF_EXECUTIONS; i++){
	//			MyQVT myQVT = createQVT();
	//
	//			URI baseURI = TESTS_BASE_URI.appendSegment("example2");
	//
	//			Class<? extends TransformationExecutor> txClass = classescs2as_qvtm_qvtias_Manual.class;
	//			Constructor<? extends TransformationExecutor> txConstructor = ClassUtil.nonNullState(txClass.getConstructor(Evaluator.class));
	//
	//			trackExample_CG(myQVT, txConstructor, baseURI, "model1", results);
	//			trackExample_CG(myQVT, txConstructor, baseURI, "model2", results);
	//			trackExample_CG(myQVT, txConstructor, baseURI, "model3", results);
	//			trackExample_CG(myQVT, txConstructor, baseURI, "model4", results);
	//			trackExample_CG(myQVT, txConstructor, baseURI, "model5", results);
	//			trackExample_CG(myQVT, txConstructor, baseURI, "model6", results);
	//			trackExample_CG(myQVT, txConstructor, baseURI, "model7", results);
	//
	//			myQVT.dispose();
	//
	//		}
	//
	//		processResults("Example2_CG_withLookupVisitor.csv" ,results);
	//	}


	private void trackExample_CG(MyQVT qvt, @NonNull Class<? extends Transformer> txClass, URI baseURI, String modelName,
			Map<String, List<Integer>> results)  throws Exception  {

		long initStamp = System.currentTimeMillis();
		executeModelsTX_CG(qvt, txClass, baseURI, modelName);
		long finalStamp = System.currentTimeMillis();
		trackResults(results, modelName, initStamp, finalStamp);
		System.out.println("Iteration on " +modelName+": " + (finalStamp - initStamp) + " ms");
	}

	private void trackExample_Interpreted(MyQVT qvt, @NonNull ImperativeTransformation tx, URI baseURI, String modelName,
			Map<String, List<Integer>> results)  throws Exception  {
		long initStamp = System.currentTimeMillis();
		executeModelsTX_Interpreted(qvt, tx, baseURI, modelName);
		long finalStamp = System.currentTimeMillis();
		trackResults(results, modelName, initStamp, finalStamp);
		System.out.println("Iteration on " +modelName+": " + (finalStamp - initStamp) + " ms");
	}

	private void trackResults(Map<String, List<Integer>> allResults, String modelName, long initStamp, long finalStamp) {

		List<Integer> modelResults = allResults.get(modelName);
		if (modelResults == null) {
			modelResults = new ArrayList<Integer>();
			allResults.put(modelName, modelResults);
		}
		modelResults.add((int)(finalStamp - initStamp));
	}


	private void processResults(String fileName, Map<String, List<Integer>> allResults) throws Exception {

		File file = new File( fileName);
		FileWriter fWriter = new FileWriter(file);
		fWriter.write("Model Name,Execution Time,Model Mean\n");

		for (String modelName : allResults.keySet()) {
			List<Integer> modelResults = allResults.get(modelName);
			if (modelResults != null) {
				modelResults.remove(0);	// We eliminate the first result with the warm-up
				for (Integer time : modelResults) {
					fWriter.write(modelName+","+time.toString()+",\n");
				}
			}
		}

		fWriter.close();
	}


	@SuppressWarnings("unused")
	private static float mean(List<Integer> list) {
		int result = 0;
		for (Integer value : list) {
			result += value;
		}
		return result / list.size();
	}

	//
	// Execute the transformation with the interpreter
	//
	protected void executeModelsTX_CG(MyQVT qvt, @NonNull Class<? extends Transformer> txClass, URI baseURI, String modelName) throws Exception {

		TransformationExecutor evaluator = qvt.createEvaluator(txClass);
		Transformer tx = evaluator.getTransformer();
		URI samplesBaseUri = baseURI.appendSegment("samples");
		URI csModelURI = samplesBaseUri.appendSegment(String.format("%s_input.xmi", modelName));
		URI asModelURI = samplesBaseUri.appendSegment(String.format("%s_output_CG.xmi", modelName));

		ResourceSet rSet = qvt.getResourceSet();
		Resource inputResource = rSet.getResource(csModelURI, true);
		tx.addRootObjects("leftCS", ClassUtil.nonNullState(inputResource.getContents()));
		boolean success = tx.run();
		Resource outputResource = rSet.createResource(asModelURI);
		outputResource.getContents().addAll(tx.getRootEObjects("rightAS"));
		outputResource.save(DefaultCompilerOptions.defaultSavingOptions);
		assertTrue(success);
	}

	//
	// Execute the transformation with the CGed transformation
	//

	protected void executeModelsTX_Interpreted(MyQVT qvt, @NonNull ImperativeTransformation tx, URI baseURI, String modelName) throws Exception {

		URI samplesBaseUri = baseURI.appendSegment("samples");
		URI csModelURI = samplesBaseUri.appendSegment(String.format("%s_input.xmi", modelName));
		URI asModelURI = samplesBaseUri.appendSegment(String.format("%s_output_Interpreted.xmi", modelName));

		BasicQVTiExecutor testEvaluator = qvt.createEvaluator(tx);
		testEvaluator.saveTransformation(null, null);
		testEvaluator.loadModel("leftCS", csModelURI);
		testEvaluator.createModel("rightAS", asModelURI, null);
		boolean success = testEvaluator.execute();
		testEvaluator.saveModels(DefaultCompilerOptions.defaultSavingOptions);
		testEvaluator.dispose();
		assertTrue(success);
	}

	protected void saveEmptyModel( URI modelURI) throws IOException {

		ResourceSet rSet = new ResourceSetImpl();
		StandaloneProjectMap.getAdapter(rSet);
		Resource r = rSet.createResource(modelURI);
		r.save(DefaultCompilerOptions.defaultSavingOptions);
	}

	protected ImperativeTransformation getTransformation(ResourceSet rSet, URI qvtiURI) {

		Resource resource = rSet.getResource(qvtiURI, true);
		for (EObject eObject : resource.getContents()) {
			if (eObject instanceof ImperativeModel) {
				for (org.eclipse.ocl.pivot.Package pPackage : ((ImperativeModel)eObject).getOwnedPackages()) {
					for (org.eclipse.ocl.pivot.Class pClass : pPackage.getOwnedClasses()) {
						if (pClass instanceof ImperativeTransformation) {
							return  (ImperativeTransformation) pClass;
						}
					}
				}
			}
		}
		return null;
	}


}
