/**
 * <copyright> Copyright (c) 2008-2009 Jonas Helming, Maximilian Koegel. 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 </copyright>
 */
package org.eclipse.emf.emfstore.performance.test;

import static org.junit.Assert.fail;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.emfstore.bowling.BowlingPackage;
import org.eclipse.emf.emfstore.client.ESLocalProject;
import org.eclipse.emf.emfstore.client.test.common.cases.ESTestWithLoggedInUserMock;
import org.eclipse.emf.emfstore.client.test.common.util.ProjectUtil;
import org.eclipse.emf.emfstore.client.util.ESVoidCallable;
import org.eclipse.emf.emfstore.client.util.RunESCommand;
import org.eclipse.emf.emfstore.fuzzy.emf.junit.ESDefaultModelMutator;
import org.eclipse.emf.emfstore.internal.client.model.ESWorkspaceProviderImpl;
import org.eclipse.emf.emfstore.internal.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.internal.common.model.Project;
import org.eclipse.emf.emfstore.internal.common.model.util.ModelUtil;
import org.eclipse.emf.emfstore.modelmutator.ESModelMutatorConfiguration;
import org.eclipse.emf.emfstore.modelmutator.ESModelMutatorUtil;
import org.eclipse.emf.emfstore.server.exceptions.ESException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * This TestCase tests all methods in the main {@link org.unicase.emfstore.EmfStore} interface.
 *
 * @author Dmitry Litvinov
 */
public class PerformanceTest extends ESTestWithLoggedInUserMock {

	private static final int PROJECTSIZE = 10000;
	private static final int NR_OF_CHANGES = 100;

	@BeforeClass
	public static void beforeClass() {
		startEMFStore();
	}

	@AfterClass
	public static void afterClass() {
		stopEMFStore();
	}

	private final static String MODEL_KEY = "http://org/eclipse/example/bowling";
	private static final int NUM_ITERATIONS = 10;
	private final long seed = 1234567800;

	private static MemoryMeter memoryMeter;

	private long lastSeed = seed + 1;

	private static final double ACCEPTED_VARIANCE = 1.5;
	private double memAfterThreshold;
	double[] times;
	long[] memBefore, memDuring, memAfter;

	/**
	 * Start server and gain session id.
	 *
	 * @throws ESException in case of failure
	 * @throws IOException
	 */
	@Override
	public void before() {
		super.before();
		generateModels(getProjectSpace(), PROJECTSIZE);
		System.out.println("MODEL SIZE: " + getLocalProject().getAllModelElements().size());
		initMeasurments();
	}

	@Override
	public void after() {
		super.after();
		memoryMeter.finish();
	}

	/**
	 * Opens projects of different sizes, shares them with the server and then deletes them. r
	 *
	 * @see org.unicase.emfstore.EmfStore#createProject(org.eclipse.emf.emfstore.server.model.SessionId, String, String,
	 *      org.eclipse.emf.emfstore.server.model.versioning.LogMessage, Project)
	 * @see org.unicase.emfstore.EmfStore#getProjectList(org.eclipse.emf.emfstore.server.model.SessionId)
	 * @throws ESException in case of failure.
	 * @throws IOException
	 */
	@Test
	public void testShareProject() throws ESException, IOException {

		initMeasurments();

		for (int i = 0; i < NUM_ITERATIONS; i++) {
			memoryMeter.startMeasurements();
			memBefore[i] = usedMemory();
			final long time = System.currentTimeMillis();

			ProjectUtil.share(getUsersession(), getLocalProject());

			times[i] = (System.currentTimeMillis() - time) / 1000.0;

			memAfter[i] = usedMemory();
			memDuring[i] = memoryMeter.stopMeasurements();
			ModelUtil.logInfo("share project - iteration #" + (i + 1) + ": time=" + times[i] + ", memory used before: "
				+ memBefore[i] / 1024 / 1024 + "MB, during: " + memDuring[i] / 1024 / 1024 + "MB, after: "
				+ memAfter[i] / 1024 / 1024 + "MB");

			// if (i > 0 && memAfter[i] > memAfterThreshold * ACCEPTED_VARIANCE) {
			// fail();
			// }
			memAfterThreshold = memAfter[i];

			// Configuration.getClientBehavior().flushCommandStack();
			System.out.println(usedMemory() / 1024 / 1024 + " MB");

		} // for loop with iterations

		ModelUtil.logInfo("times=" + Arrays.toString(times));
	}

	/**
	 * Measures average time, spent for the checkout operation. Opens projects of different sizes, shares them with the
	 * server, checkouts and then deletes them.
	 *
	 * @see org.unicase.emfstore.EmfStore#createProject(org.eclipse.emf.emfstore.server.model.SessionId, String, String,
	 *      org.eclipse.emf.emfstore.server.model.versioning.LogMessage, Project)
	 * @see org.unicase.emfstore.EmfStore#getProjectList(org.eclipse.emf.emfstore.server.model.SessionId)
	 * @throws ESException in case of failure.
	 */
	@Test
	public void testCheckoutProject() throws ESException {

		ProjectUtil.share(getUsersession(), getLocalProject());

		long memAfterThreshold = 0;
		for (int i = 0; i < NUM_ITERATIONS; i++) {
			memoryMeter.startMeasurements();
			memBefore[i] = usedMemory();
			final long time = System.currentTimeMillis();

			ProjectUtil.checkout(getLocalProject());
			times[i] = (System.currentTimeMillis() - time) / 1000.0;
			memAfter[i] = usedMemory();
			memDuring[i] = memoryMeter.stopMeasurements();
			ModelUtil.logInfo("checkout project " + getProjectSpace().getProjectName() + " iteration #" + (i + 1)
				+ ": time=" + times[i] + ", memory used before: " + memBefore[i] / 1024 / 1024 + "MB, during: "
				+ memDuring[i] / 1024 / 1024 + "MB, after: " + memAfter[i] / 1024 / 1024 + "MB");

			if (i > 0 && memAfter[i] > memAfterThreshold * 1.2) {
				fail("Memory consumption too high.");
			}
			memAfterThreshold = memAfter[i];
		}

		ModelUtil.logInfo("times=" + Arrays.toString(times));
	}

	/**
	 * Measures average time, spent for the commit and update operations. Opens projects of different sizes, shares them
	 * with the server and checks it out as two different projects. Then the test generates changes in one of the
	 * projects, using the ModelMutator, commits them to the server, and updates the second project. The test performs
	 * model change, commit and update NUM_ITERATIONS times and calculates times for commit and update operations
	 *
	 * @see org.unicase.emfstore.EmfStore#createProject(org.eclipse.emf.emfstore.server.model.SessionId, String, String,
	 *      org.eclipse.emf.emfstore.server.model.versioning.LogMessage, Project)
	 * @see org.unicase.emfstore.EmfStore#getProjectList(org.eclipse.emf.emfstore.server.model.SessionId)
	 * @throws ESException in case of failure.
	 */
	@Test
	public void testCommitAndUpdateProject() throws ESException {

		getLocalProject().shareProject(nullMonitor());

		final ESLocalProject checkout = ProjectUtil.checkout(getLocalProject());

		final double[] modelChangeTimes = new double[NUM_ITERATIONS];
		final double[] commitTimes = new double[NUM_ITERATIONS];
		final double[] updateTimes = new double[NUM_ITERATIONS];
		final long[] memBeforeMut = new long[NUM_ITERATIONS];
		final long[] memDuringMut = new long[NUM_ITERATIONS];
		final long[] memAfterMut = new long[NUM_ITERATIONS];
		final long[] memDuringCommit = new long[NUM_ITERATIONS];
		final long[] memAfterCommit = new long[NUM_ITERATIONS];
		final long[] memDuringUpdate = new long[NUM_ITERATIONS];
		final long[] memAfterUpdate = new long[NUM_ITERATIONS];

		for (int i = 0; i < NUM_ITERATIONS; i++) {
			memoryMeter.startMeasurements();
			memBeforeMut[i] = usedMemory();
			long time = System.currentTimeMillis();
			// TODO: Nr of changes
			changeModel(getProjectSpace(), NR_OF_CHANGES);
			modelChangeTimes[i] = (System.currentTimeMillis() - time) / 1000.0;

			memDuringMut[i] = memoryMeter.stopMeasurements();
			memAfterMut[i] = usedMemory();
			ModelUtil.logInfo("change model-  iteration #" + (i + 1) + ": time=" + modelChangeTimes[i]
				+ " memory used before:" + memBeforeMut[i] / 1024 / 1024 + "MB, during: " + memDuringMut[i] / 1024
					/ 1024
				+ "MB, after: " + memAfterMut[i] / 1024 / 1024 + "MB");

			System.out.println("VERSION BEFORE commit:" + getLocalProject().getBaseVersion().getIdentifier());
			time = System.currentTimeMillis();
			memoryMeter.startMeasurements();
			time = System.currentTimeMillis();

			getLocalProject().commit(null, null, null);
			commitTimes[i] = (System.currentTimeMillis() - time) / 1000.0;

			memDuringCommit[i] = memoryMeter.stopMeasurements();
			memAfterCommit[i] = usedMemory();
			ModelUtil.logInfo("commit project - iteration #" + (i + 1) + ": time=" + commitTimes[i]
				+ ", memory used before: " + memAfterMut[i] / 1024 / 1024 + "MB, during: " + memDuringCommit[i] / 1024
					/ 1024
				+ "MB, after: " + memAfterCommit[i] / 1024 / 1024 + "MB");
			if (i > 0 && memAfter[i] > memAfterThreshold * ACCEPTED_VARIANCE) {
				fail();
			}
			memAfterThreshold = memAfter[i];

			memoryMeter.startMeasurements();
			time = System.currentTimeMillis();

			checkout.update(new NullProgressMonitor());
			updateTimes[i] = (System.currentTimeMillis() - time) / 1000.0;
			// TODO: re-enable clean memory task
			// CleanMemoryTask task = new CleanMemoryTask(ESWorkspaceProviderImpl.getInstance().getCurrentWorkspace()
			// .getResourceSet());
			// task.run();
			memDuringUpdate[i] = memoryMeter.stopMeasurements();
			memAfterUpdate[i] = usedMemory();
			ModelUtil.logInfo("update project - iteration #" + (i + 1) + ": time=" + updateTimes[i]
				+ ", memory used before: " + memAfterCommit[i] / 1024 / 1024 + "MB, during: " + memDuringUpdate[i]
					/ 1024 / 1024
				+ "MB, after: " + memAfterUpdate[i] / 1024 / 1024 + "MB");

			if (i > 0 && memAfter[i] > memAfterThreshold * ACCEPTED_VARIANCE) {
				fail();
			}
			memAfterThreshold = memAfter[i];

		}

		ModelUtil.logInfo("Mutate model - average=" + Calculate.average(modelChangeTimes) + ", min="
			+ Calculate.min(modelChangeTimes) + ", max=" + Calculate.max(modelChangeTimes) + ", mean="
			+ Calculate.mean(modelChangeTimes));

	}

	private void initMeasurments() {
		memoryMeter = new MemoryMeter();
		memoryMeter.start();
		times = new double[NUM_ITERATIONS];
		memBefore = new long[NUM_ITERATIONS];
		memDuring = new long[NUM_ITERATIONS];
		memAfter = new long[NUM_ITERATIONS];
	}

	public static long usedMemory() {
		Runtime.getRuntime().gc();
		return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
	}

	private static IProgressMonitor nullMonitor() {
		return new NullProgressMonitor();
	}

	public void generateModels(final ProjectSpace projectSpace, int numberOfModleElements) {
		lastSeed = lastSeed == seed ? seed + 1 : seed;
		final ESModelMutatorConfiguration mmc = new ESModelMutatorConfiguration(
			ESModelMutatorUtil.getEPackage(MODEL_KEY),
			projectSpace.getProject(), lastSeed);

		mmc.setMaxDeleteCount(1);
		mmc.setUseEcoreUtilDelete(false);
		mmc.setMinObjectsCount(numberOfModleElements);
		mmc.setEditingDomain(ESWorkspaceProviderImpl.getInstance().getInternalWorkspace().getEditingDomain());
		final Collection<EStructuralFeature> features = new ArrayList<EStructuralFeature>();
		features.add(org.eclipse.emf.emfstore.internal.common.model.ModelPackage.eINSTANCE.getProject_CutElements());
		mmc.seteStructuralFeaturesToIgnore(features);

		RunESCommand.run(new ESVoidCallable() {
			@Override
			public void run() {
				ESDefaultModelMutator.generateModel(mmc);
			}
		});

		// System.out.println("Number of changes: " + projectSpace.getOperations().size());
	}

	public void changeModel(final ProjectSpace prjSpace, final int nrOfChanges) {
		lastSeed = lastSeed == seed ? seed + 1 : seed;
		final ESModelMutatorConfiguration mmc = new ESModelMutatorConfiguration(
			ESModelMutatorUtil.getEPackage(MODEL_KEY),
			prjSpace.getProject(), lastSeed);
		mmc.setMaxDeleteCount(1);
		mmc.setUseEcoreUtilDelete(false);
		mmc.setMinObjectsCount(1);
		mmc.setEditingDomain(ESWorkspaceProviderImpl.getInstance().getInternalWorkspace().getEditingDomain());
		final Collection<EStructuralFeature> features = new ArrayList<EStructuralFeature>();
		features.add(org.eclipse.emf.emfstore.internal.common.model.ModelPackage.eINSTANCE.getProject_CutElements());
		mmc.seteStructuralFeaturesToIgnore(features);
		final List<EPackage> packages = new ArrayList<EPackage>();
		packages.add(BowlingPackage.eINSTANCE);
		mmc.setModelPackages(packages);

		final long time = System.currentTimeMillis();
		RunESCommand.run(new ESVoidCallable() {
			@Override
			public void run() {
				mmc.setMinObjectsCount(nrOfChanges);
				ESDefaultModelMutator.changeModel(mmc);
			}
		});
		System.out.println("Changed model: " + (System.currentTimeMillis() - time) / 1000.0 + "sec");
		// System.out.println("Number of changes: " + prjSpace.getOperations().size());
	}
}
