/*******************************************************************************
 * Copyright (c) 2012, 2015 INRIA, and Mia-Software.
 * 
 * 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:
 *    Guillaume Doux (INRIA) - Initial API and implementation
 *    Grégoire Dupé (Mia-Software) - Bug 482672 - Benchmark command line interface
 *    Grégoire Dupé (Mia-Software) - Bug 482857 - Discoverer Benchmark Report : wrong namespaces
 ******************************************************************************/
package org.eclipse.modisco.infra.discovery.benchmark.core.internal.impl;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EPackage.Registry;
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.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.gmt.modisco.infra.common.core.logging.MoDiscoLogger;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.modisco.infra.discovery.benchmark.core.internal.Activator;
import org.eclipse.modisco.infra.discovery.benchmark.core.internal.api.IDiscovererBenchmarkDiscoverer;
import org.eclipse.modisco.infra.discovery.benchmark.core.internal.api.IDiscovererID;
import org.eclipse.modisco.infra.discovery.benchmark.core.internal.api.IEventNotifier;
import org.eclipse.modisco.infra.discovery.benchmark.core.internal.exported.IDiscovererList;
import org.eclipse.modisco.infra.discovery.benchmark.core.internal.exported.IProjectSet;
import org.eclipse.modisco.infra.discovery.benchmark.core.internal.reporting.HtmlReport;
import org.eclipse.modisco.infra.discovery.benchmark.core.internal.reporting.internal.BenchmarkChartGeneration;
import org.eclipse.modisco.infra.discovery.benchmark.metamodel.internal.benchmark.Benchmark;
import org.eclipse.modisco.infra.discovery.benchmark.metamodel.internal.benchmark.BenchmarkFactory;
import org.eclipse.modisco.infra.discovery.benchmark.metamodel.internal.benchmark.BenchmarkPackage;
import org.eclipse.modisco.infra.discovery.benchmark.metamodel.internal.benchmark.Discovery;
import org.eclipse.modisco.infra.discovery.benchmark.metamodel.internal.benchmark.DiscoveryIteration;
import org.eclipse.modisco.infra.discovery.benchmark.metamodel.internal.benchmark.EndEvent;
import org.eclipse.modisco.infra.discovery.benchmark.metamodel.internal.benchmark.Event;
import org.eclipse.modisco.infra.discovery.benchmark.metamodel.internal.benchmark.EventType;
import org.eclipse.modisco.infra.discovery.benchmark.metamodel.internal.benchmark.File;
import org.eclipse.modisco.infra.discovery.benchmark.metamodel.internal.benchmark.MemoryMeasurement;
import org.eclipse.modisco.infra.discovery.benchmark.metamodel.internal.benchmark.Project;
import org.eclipse.modisco.infra.discovery.catalog.CatalogFactory;
import org.eclipse.modisco.infra.discovery.catalog.DiscovererDescription;
import org.eclipse.modisco.infra.discovery.catalog.DiscovererParameter;
import org.eclipse.modisco.infra.discovery.core.AbstractModelDiscoverer;
import org.eclipse.modisco.infra.discovery.core.IDiscoverer;
import org.eclipse.modisco.infra.discovery.core.IDiscoveryManager;
import org.eclipse.modisco.infra.discovery.core.annotations.Parameter;
import org.eclipse.modisco.infra.discovery.core.exception.DiscoveryException;
import org.eclipse.modisco.infra.discovery.launch.LaunchConfiguration;
import org.eclipse.modisco.infra.discovery.launch.LaunchFactory;
import org.eclipse.modisco.infra.discovery.launch.ParameterValue;
import org.eclipse.modisco.utils.core.internal.exported.SystemInfo;

/**
 * Main entry point for the discoverer of benchmark
 * @author Guillaume Doux
 *
 */
public class DiscovererBenchmarkDiscoverer extends AbstractModelDiscoverer<IProjectSet>
implements IDiscovererBenchmarkDiscoverer {

	/**
	 * Private integer constants
	 */
	private static final int ZERO = 0;
	
	private static final int TWO = 2;
	
	private static final int SIX = 6;

	private static final int EIGHT = 8;

	private static final int TEN = 10;

	
	private static final String SAVE_OPERATION = "SaveOperation";

	private static final int INTERVAL = 1000;

	private static final int MSINSEC = 1000;

	private static final String CODE_EXTENSION = "java";

	public static final String ID = "org.eclipse.modisco.infra.discovery.benchmark.core.api.benchmarkdiscoverer";

	private static final long BYTEPERMB = 1024 * 1024;

	private IDiscovererID discovererID;
	private int iterations;
	private boolean measureMemoryUse;
	private int memoryPollingInterval;
	private boolean generateHtmlReport;
	private URI htmlReportLocation;

	private EventAndMemoryRecorder recorder;
	private List<MemoryMeasurement> memoryMeasurements;
	private List<Event> events;

	private ResourceSet rSet;


	public DiscovererBenchmarkDiscoverer() {
		super();
		this.discovererID = new DiscovererID(ID);
		this.memoryPollingInterval = 0;
		this.memoryMeasurements = new LinkedList<MemoryMeasurement>();
		this.events = new LinkedList<Event>();
		this.rSet = new ResourceSetImpl();
		this.rSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmi", 
				new XMIResourceFactoryImpl());
		this.iterations = 1;
	}

	/**
	 * Parameter for getting the dicoverers
	 */
	private IDiscovererList discoverers;


	protected IDiscovererList getDiscoverers() {
		return this.discoverers;
	}

	/**
	 * Setter for the list of discoverers, annotated with @Parameter set by the UI
	 * @param discos: the list of discoverers
	 */
	@Parameter(name = "DISCOVERER_LIST", description = "The list of discoverers.", requiresInputValue = true)
	public void setDiscoverers(final IDiscovererList discos) {
		this.discoverers = discos;
	}


	/**
	 * Method launching the discovery process on all the discoverers X all the projects
	 * @param projects the set of projects to discover
	 * @param progressMonitor
	 * @return The benchmark model conforms to http://www.eclipse.org/modisco/infra/discovery/0.1.incubation/benchmark
	 * @throws DiscoveryException
	 */
	public Resource discoverBenchmark(final IProjectSet projects, final IProgressMonitor progressMonitor) throws DiscoveryException {
		progressMonitor.beginTask("Benchmark Discovery", TEN);
		progressMonitor.subTask("Benchmark initialization");
		Benchmark benchmark;
		benchmark = benchmarkInit();
		progressMonitor.worked(TWO);
		this.recorder =  new EventAndMemoryRecorder(this.measureMemoryUse, this.memoryPollingInterval);

		for (IProject project : projects.sortBySize().getProjects()) {
			progressMonitor.subTask("project initialization");
			Project proj = createBenchmarkProjectAndFiles(project);
			benchmark.getProjects().add(proj);

			for (Discovery discoTemp : this.discoverers) {
				progressMonitor.subTask("Discovery initialization");
				Discovery disco = BenchmarkFactory.eINSTANCE.createDiscovery();
				String discovererId = discoTemp.getDiscovererId();
				AbstractModelDiscoverer<IProject> discoverer = (AbstractModelDiscoverer<IProject>) IDiscoveryManager.INSTANCE.createDiscovererImpl(discovererId);
				benchmark.getDiscoveries().add(disco);
				preDiscoveryDiscoInit(proj, disco, discoTemp, (AbstractModelDiscoverer<IProject>) discoverer, discovererId);
				setLaunchParameter(disco, discoverer);
				String serializationLocation;
				if (discoverer.getTargetURI() != null) {
					serializationLocation = discoverer.getTargetURI().trimFileExtension().toString();
				} else {
					serializationLocation = this.getTargetURI().trimFileExtension().toString();
				}
				for (int i = 1; i <= this.iterations;  i++) {
					URI resultSerializationLocation =  URI.createURI(serializationLocation);
					discoverer.setTargetURI(resultSerializationLocation.appendSegment(disco.getDiscovererId() + "_" + proj.getName() + "_iteration_" + String.valueOf(i) + ".xmi"));
					boolean failure = false;
					StringBuilder discoveryErrors = new StringBuilder();
					this.recorder.reset();
					if (IEventNotifier.class.isInstance(discoverer)) {
						((IEventNotifier) discoverer).addListener(this.recorder);
					}
					progressMonitor.subTask("Project discovery: iteration " + String.valueOf(getIterations()));
					this.recorder.start();
					try {
						if (discoverer.isApplicableTo(project)) {
							IProgressMonitor subProgressMonitor = new SubProgressMonitor(progressMonitor, EIGHT);
							discoverer.discoverElement(project, subProgressMonitor);
						} else {
							final String message = String.format(
									"Discoverer '%s' is not applicable on project '%s'", //$NON-NLS-1$
									discovererId,
									project.getName()
									);
							MoDiscoLogger.logWarning(
									message, Activator.getDefault());
						}
					} catch (Exception e) {
						failure = true;
						discoveryErrors.append(e.getStackTrace().toString());
						final String message = String.format(
								"Benchmark of discoverer '%s' fails on project '%s'", //$NON-NLS-1$
								discovererId,
								project.getName()
								);
						MoDiscoLogger.logError(e,
								message, Activator.getDefault());
					}
					this.recorder.stop();
					this.events.addAll(this.recorder.getEvents());
					this.events.addAll(this.recorder.getMemoryMeasurements());
					this.memoryMeasurements.addAll(this.recorder.getMemoryMeasurements());
					if (IEventNotifier.class.isInstance(discoverer)) {
						((IEventNotifier) discoverer).removeListener(this.recorder);
					}
					DiscoveryIteration discoveryIteration = createDiscoveryIteration(this.recorder);
					if (failure) {
						discoveryIteration.setDiscoveryErrors(discoveryErrors.toString());
					}
					disco.getIterations().add(discoveryIteration);
				}
				postDiscoveryDiscoInit(disco, discoverer);
				if (this.isTargetSerializationChosen()) {
					try {
						saveTargetModel(benchmark);
					} catch (IOException e) {
						MoDiscoLogger.logError(e,
								"Intermediate model save fail", org.eclipse.modisco.infra.discovery.benchmark.core.internal.Activator.getDefault()); //$NON-NLS-1$
					}
				}
			}
		}
		benchmark.setJvmMaxHeapInMiB(computeMaxMemoryUsage());
		try {
			if (this.isTargetSerializationChosen()) {
				progressMonitor.subTask("Save benchmark model");
				saveTargetModel(benchmark);
				progressMonitor.worked(getIterations() * projects.getProjects().size() * this.discoverers.getDiscoverers().size()); //1*iteration*discoveries*projects for disco init on 20*iteration*discoveries*projects
			}
			if (isGenerateHtmlReport()) {
				progressMonitor.subTask("Generate benchmark report");
				IProgressMonitor subProgressM = new SubProgressMonitor(progressMonitor, SIX);
				generateHtmlReport(subProgressM, benchmark);
				progressMonitor.worked(2 * getIterations() * projects.getProjects().size() * this.discoverers.getDiscoverers().size()); //2*iteration*discoveries*projects for disco init on 20*iteration*discoveries*projects
			}
		} catch (IOException e) {
			MoDiscoLogger.logError(e,
					"Report generation fail", org.eclipse.modisco.infra.discovery.benchmark.core.internal.Activator.getDefault()); //$NON-NLS-1$
		} catch (CoreException e) {
			MoDiscoLogger.logError(e,
					"Report generation fail", org.eclipse.modisco.infra.discovery.benchmark.core.internal.Activator.getDefault()); //$NON-NLS-1$
		} catch (Exception e) {
			MoDiscoLogger.logError(e,
					"Report generation fail", org.eclipse.modisco.infra.discovery.benchmark.core.internal.Activator.getDefault()); //$NON-NLS-1$
		}


		progressMonitor.done();
		return benchmark.eResource();
	}

	/**
	 * Compute the size of the model in parameter (in number of model elements)
	 * @param targetModel
	 * @return the number of model elements
	 */
	private long computeSize(final Resource targetModel) {
		long size = 0;
		if (targetModel != null) {
			for (TreeIterator<EObject> iterator = targetModel.getAllContents(); iterator.hasNext();) {
				iterator.next();
				size++;
			}
		} else {
			MoDiscoLogger.logWarning("Unable to compute the number of element of an unexisting model: "+targetModel.getURI().toString(), Activator.getDefault());
		}
		return size;
	}

	/**
	 * launch the generation of the HTML report and the charts for the benchmark model in parameter
	 * @param progressMonitor
	 * @param benchmark
	 * @throws Exception
	 */
	private void generateHtmlReport(final IProgressMonitor progressMonitor,
			final Benchmark benchmark) throws Exception {
		//Get the output folder
		URI targetURI = null;
		if (this.getHtmlReportLocation() != null) {
			targetURI = this.getHtmlReportLocation();
		} else {
			targetURI = this.getTargetURI();
		}
		if (targetURI == null) {
			MoDiscoLogger.logWarning(
					"The HTML_REPORT_LOCATION or the TARGET_URI parameter should not be null", //$NON-NLS-1$
					Activator.getDefault());
			return;
		}
		final IWorkspace workspace = ResourcesPlugin.getWorkspace();
		final IWorkspaceRoot wsRoot = workspace.getRoot();
		java.io.File file = null;
		IFile iFile = null;
		String targetUriStr = targetURI.toString();
		if (targetURI.isPlatformResource()) {
			final String pathStr = 
					targetUriStr.replaceAll("platform:/resource", ""); //$NON-NLS-1$//$NON-NLS-2$
			iFile = wsRoot.getFile(new Path(pathStr));
			iFile.getLocation().toFile();
		} else if (targetURI.isFile()) {
			file = new java.io.File(java.net.URI.create(targetUriStr));
		} else {
			final String message = String.format(
					"The following target URI '%s' is not managed. 'platform:/resource' or 'file:/' are expected.", //$NON-NLS-1$
					targetURI.toString());
			throw new IllegalArgumentException(message);
		}
		final ArrayList<Object> arguments = new ArrayList<Object>();
		//Generation of the HTML report
		try {
			HtmlReport report = new HtmlReport(benchmark, file, arguments);
			report.doGenerate(null);
		} catch (Exception e) {
			MoDiscoLogger.logWarning(e,
					"Acceleo exception", //$NON-NLS-1$
					Activator.getDefault());
		}
		//Generation of the charts
		final BenchmarkChartGeneration chartGenerator = 
				new BenchmarkChartGeneration(file, this.measureMemoryUse);
		chartGenerator.generateAll(benchmark);

		if (iFile != null) {
			final IContainer location = iFile.getParent();
			location.refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
		}
	}

	/**
	 * Set the launch parameters of the {@link AbstractModelDiscoverer} in parameter with the content of the {@link Discovery} element
	 * @param disco {@link Discovery}
	 * @param discoverer {@link AbstractModelDiscoverer} (AbstractModelDiscoverer<IProject>)
	 */
	private void setLaunchParameter(final Discovery disco, 
			final AbstractModelDiscoverer<IProject> discoverer) {
		if (disco.getDiscovererLaunchConfiguration() != null) {
			for (ParameterValue pv : disco.getDiscovererLaunchConfiguration().getParameterValues()) {
				DiscovererParameter parameter = pv.getParameter();
				Object value = pv.getValue();
				if (value != null) {
					try {
						if (parameter.getSetter() == null) {
							parameter.setSetter(findSetter(discoverer.getClass(), parameter.getId()));
						}
						this.setValue(parameter, discoverer, value);
					} catch (DiscoveryException e) {
						MoDiscoLogger.logWarning(e, e.getMessage(), Activator.getDefault());
					}

				}
			}
		}
	}

	/**
	 * Find the setter of identifier id in the class clazz
	 * use java reflexion
	 * @param clazz
	 * @param id
	 * @return the setter
	 */
	private Method findSetter(final Class<? extends AbstractModelDiscoverer> clazz,
			final String id) {
		for (Method method : clazz.getMethods()) {
			if (method.isAnnotationPresent(Parameter.class)) {
				Parameter p = method.getAnnotation(Parameter.class);
				if (p.name().equals(id)) {
					if (method.getReturnType().equals(void.class)) {
						return method;
					}
				}
			}
		}
		return null;
	}


	/**
	 * method to set the values of parameters: extracted from DiscoveryManager (org.eclipse.modisco.infra.discovery.core.internal)
	 * @param parameter
	 * @param discoverer
	 * @param parameterValue
	 * @throws DiscoveryException
	 */
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#setValue
	 * (org.eclipse.modisco.infra.discovery.catalog.DiscovererParameter,
	 * org.eclipse.modisco.infra.discovery.core.IDiscoverer, java.lang.Object)
	 */
	private void setValue(final DiscovererParameter parameter, final IDiscoverer<?> discoverer,
			final Object parameterValue) throws DiscoveryException {
		try {
			if (parameter.getField() != null
					&& Modifier.isPublic(parameter.getField().getModifiers())) {
				parameter.getField().set(discoverer, parameterValue);
			} else if (parameter.getSetter() != null
					&& Modifier.isPublic(parameter.getSetter().getModifiers())) {
				parameter.getSetter().invoke(discoverer, parameterValue);
			} else {
				throw new DiscoveryException(discoverer.getClass()
						+ " discoverer does not implement public write access to the parameter " //$NON-NLS-1$
						+ parameter.getId());
			}
		} catch (IllegalArgumentException e) {
			throw new DiscoveryException("Illegal parameter value for " //$NON-NLS-1$
					+ parameter.getId() + " : " + parameterValue, e); //$NON-NLS-1$
		} catch (IllegalAccessException e) {
			throw new DiscoveryException("Illegal parameter value for " //$NON-NLS-1$
					+ parameter.getId() + " : " + parameterValue, e); //$NON-NLS-1$
		} catch (InvocationTargetException e) {
			throw new DiscoveryException("Illegal parameter value for " //$NON-NLS-1$
					+ parameter.getId() + " : " + parameterValue, e); //$NON-NLS-1$
		}

	}

	/**
	 * Save the benchmark model in an XMI file
	 * @param benchmark
	 * @throws IOException
	 */
	private void saveTargetModel(final Benchmark benchmark) throws IOException {
		if ((this.getTargetURI() == null) && (this.getTargetModel() == null)) {
			MoDiscoLogger.logWarning("The parameter TARGET_URI should not be empty", Activator.getDefault());
			return;
		}		
		if (benchmark.eResource() == null) {

			Resource res = null;
			if (getTargetModel() == null) {
				res = this.rSet.createResource(getTargetURI());
			} else {
				res = this.rSet.createResource(getTargetModel().getURI());
			}
			res.getContents().add(benchmark);
			List<Event> eventsList = new ArrayList<Event>();
			List<EventType> eventTypeList = new ArrayList<EventType>();
			for (Discovery d : benchmark.getDiscoveries()) {
				for (DiscoveryIteration i : d.getIterations()) {
					for (Event event : i.getEvents()) {
						eventsList.add(event);
						eventTypeList.add(event.getEventType());
					}
				}
			}
//			res.getContents().addAll(eventsList);
			res.getContents().addAll(eventTypeList);
			this.setTargetModel(res);
		}

		this.saveTargetModel();
	}

	/**
	 * Compute the maximum amount of memory used in the discovery
	 * @return max memory used
	 */
	private long computeMaxMemoryUsage() {
		long max = 0;
		for (MemoryMeasurement measure : this.memoryMeasurements) {
			if (max < measure.getMemoryUsed()) {
				max = measure.getMemoryUsed();
			}
		}
		return max;
	}

	/**
	 * Initialize the benchmark model element with system information
	 * @return the model element
	 */
	private Benchmark benchmarkInit() {

		Benchmark benchmark = BenchmarkFactory.eINSTANCE.createBenchmark();
		try {
			SystemInfo sysInfo = SystemInfo.getInstance();
			benchmark.setJvmMaxHeapInMiB(Runtime.getRuntime().maxMemory() / BYTEPERMB);
			benchmark.setProcessorName(sysInfo.getProcName());
			benchmark.setProcessorDescription(sysInfo.getProcDescription());
			benchmark.setProcessorCount(sysInfo.getnProcessors());
			benchmark.setProcessorCacheSize(sysInfo.getProcCacheSize());
			benchmark.setSystemMemory(sysInfo.getMemory());
			benchmark.setOsName(sysInfo.getOsName());
			benchmark.setOsVersion(sysInfo.getOsVersion());
			benchmark.setOsArchitecture(sysInfo.getArch());
		} catch (IOException e) {
			MoDiscoLogger.logError(e,
					"Could not get system information for benchmark", org.eclipse.modisco.infra.discovery.benchmark.core.internal.Activator.getDefault()); //$NON-NLS-1$
		}
		return benchmark;
	}

	/**
	 * Initialize the discovery model element before launchin the associated discoverer
	 * @param proj the model element for project that will be discovered
	 * @param disco the model element to initialize
	 * @param discoT the model element representing the information concerning the discovery in the launch configuration
	 * @param discoverer the real discoverer {@link AbstractModelDiscoverer}
	 * @param discovererId the discoverer id
	 */
	private void preDiscoveryDiscoInit(final Project proj, final Discovery disco, final Discovery discoT, final AbstractModelDiscoverer<IProject> discoverer, final String discovererId) {
		disco.setProject(proj);
		disco.setName(discoverer.toString());
		disco.setDiscovererClassName(discoverer.getClass().getName());
		disco.setDiscovererId(discovererId);
		DiscovererDescription dd = CatalogFactory.eINSTANCE.createDiscovererDescription();		
		if (discoT.getDiscovererLaunchConfiguration() != null) {
			LaunchConfiguration lc = LaunchFactory.eINSTANCE.createLaunchConfiguration();
			lc.setSource(proj.getName());
			lc.setDiscoverer(dd);
			lc.setOpenModelAfterDiscovery(discoT.getDiscovererLaunchConfiguration().isOpenModelAfterDiscovery());
			for (ParameterValue pv : discoT.getDiscovererLaunchConfiguration().getParameterValues()) {
				ParameterValue newPv = LaunchFactory.eINSTANCE.createParameterValue();
				newPv.setValue(pv.getValue());

				DiscovererParameter param = CatalogFactory.eINSTANCE.createDiscovererParameter();
				param.setDescription(pv.getParameter().getDescription());
				param.setDirection(pv.getParameter().getDirection());
				param.setDiscoverer(dd);
				param.setField(pv.getParameter().getField());
				param.setGetter(pv.getParameter().getGetter());
				param.setId(pv.getParameter().getId());
				param.setInitializer(pv.getParameter().getInitializer());
				param.setRequiredInput(pv.getParameter().isRequiredInput());
				param.setSetter(pv.getParameter().getSetter());
				param.setType(pv.getParameter().getType());

				newPv.setParameter(param);
				lc.getParameterValues().add(newPv);
			}
			disco.setDiscovererLaunchConfiguration(lc);
		}
		if (discoT.getCopyOfDiscovererDescription() == null) {
			dd.setId(disco.getDiscovererId());
			dd.setSourceType(proj.getClass());
			dd.setImplementationType(discoverer.getClass());
		} else {
			dd.setId(discoT.getCopyOfDiscovererDescription().getId());
			dd.setImplementationBundle(discoT.getCopyOfDiscovererDescription().getImplementationBundle());
			dd.setImplementationType(discoT.getCopyOfDiscovererDescription().getImplementationType());
			dd.setSourceType(discoT.getCopyOfDiscovererDescription().getSourceType());
		}
		disco.setCopyOfDiscovererDescription(dd);
	}

	/**
	 * Finalization of the initialization of the discovery model element after the effective discovery
	 * @param disco
	 * @param discoverer
	 */
	private void postDiscoveryDiscoInit(final Discovery disco, final AbstractModelDiscoverer<IProject> discoverer) {
		double totalDiscoveryTime = 0;
		double totalSaveTime = 0;
		if (this.iterations > 0) {
			double maxDisco = 0;
			double maxSave = 0;
			double minDisco = disco.getIterations().get(0).getDiscoveryTimeInSeconds();
			double minSave = disco.getIterations().get(0).getSaveTimeInSeconds();
			for (DiscoveryIteration iter : disco.getIterations()) {
				totalSaveTime += iter.getSaveTimeInSeconds();
				totalDiscoveryTime += iter.getDiscoveryTimeInSeconds();
				if (iter.getDiscoveryTimeInSeconds() > maxDisco) {
					maxDisco = iter.getDiscoveryTimeInSeconds();
				}
				if (iter.getSaveTimeInSeconds() > maxSave) {
					maxSave = iter.getSaveTimeInSeconds();
				}
				if (iter.getDiscoveryTimeInSeconds() < minDisco) {
					minDisco = iter.getDiscoveryTimeInSeconds();
				}
				if (iter.getSaveTimeInSeconds() < minSave) {
					minSave = iter.getSaveTimeInSeconds();
				}
			}
			disco.setDiscoveryTimeAverageInSeconds(totalDiscoveryTime / this.iterations);
			disco.setSaveTimeAverageInSeconds(totalSaveTime / this.iterations);
			disco.setExecutionTimeStandardDeviation(maxDisco - minDisco);
			disco.setSaveTimeStandardDeviation(maxSave - minSave);

			disco.setNumberOfModelElements(computeSize(discoverer.getTargetModel()));

			IFileStore fileStore;
			try {
				URI targetURI = discoverer.getTargetURI();
				String locationString = "file://" + ResourcesPlugin.getWorkspace().getRoot().getLocation().toString() + targetURI.toString();
				java.net.URI uri = java.net.URI.create(locationString);
				fileStore = EFS.getStore(uri);
				disco.setXmiSizeInBytes(fileStore.fetchInfo().getLength());
			} catch (Exception e) {
				MoDiscoLogger.logError(e,
						"Could not get output model size.", org.eclipse.modisco.infra.discovery.benchmark.core.internal.Activator.getDefault()); //$NON-NLS-1$
			}

		}
	}

	/**
	 * Initialize a {@link DiscoveryIteration} after the discovery using the event and memory recorder
	 * @param rec {@link EventAndMemoryRecorder}
	 * @return the initialized discovery iteration
	 */
	private DiscoveryIteration createDiscoveryIteration(final EventAndMemoryRecorder rec) {
		DiscoveryIteration discoIter = BenchmarkFactory.eINSTANCE.createDiscoveryIteration();
		discoIter.setDiscoveryDate(new Date());
		discoIter.setMaxUsedMemoryInBytes(rec.getMaxMemoryUsed());
		discoIter.getEvents().addAll(rec.getEvents());
		discoIter.setDiscoveryTimeInSeconds((rec.getStopTime() - rec.getStartTime()) / MSINSEC);
		for (Event event : rec.getEvents()) {
			if (event instanceof EndEvent) {
				if (event.getEventType().getName().equals(SAVE_OPERATION)) {
					double saveTime = event.getTime() - ((EndEvent) event).getBeginning().getTime();
					discoIter.setSaveTimeInSeconds(saveTime / MSINSEC);
					discoIter.setDiscoveryTimeInSeconds(discoIter.getDiscoveryTimeInSeconds() - discoIter.getSaveTimeInSeconds());
				}
			}
		}
		discoIter.getMemoryMeasurements().addAll(rec.getMemoryMeasurements());			
		return discoIter;
	}

	/**
	 * Create the model elements for the projects and conaitned files to discover
	 * @param project the real project {@link IProject}
	 * @return the project model element {@link Project}
	 */
	private Project createBenchmarkProjectAndFiles(final IProject project) {
		Project proj = BenchmarkFactory.eINSTANCE.createProject();
		proj.setName(project.getName());
		try {
			for (IResource res : project.members()) {
				if (res instanceof IFolder) {
					proj.getFiles().addAll(createFiles((IFolder) res, new LinkedList<File>()));
				} else {
					if (res instanceof IFile) {
						File f = createFile(res);
						proj.getFiles().add(f);
					}
				}
			}
			if (proj.getFiles().isEmpty()) {
				proj.setAverageFileSizeInBytes(0);
				proj.setTotalSizeInBytes(0);
				proj.setAverageLinesPerFile(0);
				proj.setTotalLines(0);
			} else {
				long totalLineSize = 0;
				long totalByteSize = 0;
				for (File f : proj.getFiles()) {
					totalLineSize += f.getLines();
					totalByteSize += f.getSizeInBytes();
				}
				proj.setAverageFileSizeInBytes(totalByteSize / proj.getFiles().size());
				proj.setTotalSizeInBytes(totalByteSize);
				proj.setAverageLinesPerFile(totalLineSize / getNumberOfSourceCodeFiles(proj));
				proj.setTotalLines(totalLineSize);
			}
		} catch (CoreException e) {
			MoDiscoLogger.logError(e,
					"Could not get members of project", org.eclipse.modisco.infra.discovery.benchmark.core.internal.Activator.getDefault()); //$NON-NLS-1$
		}
		return proj;
	}

	/**
	 * Count the number of lines is source files.
	 * The source files are identified as having the value of the CODE_EXTENSION constant as extension
	 * @param proj the project to compute the number of lines
	 * @return the number of lines
	 */
	private long getNumberOfSourceCodeFiles(final Project proj) {
		int number = 0;
		for (File file : proj.getFiles()) {
			//only files having CODE_EXTENSION as extension are measured
			if (file.getLines() == 0) {
				number++;
			}
		}
		return number;
	}

	/**
	 * Initialize the files model elements {@link File} contained in a folder {@link IFolder} to discover.
	 * Recursive method, should be called initially on the project to discover
	 * @param folder 
	 * @param files
	 * @return the list of initialized files {@link File}
	 * @throws CoreException
	 */
	private List<File> createFiles(final IFolder folder, final List<File> files) throws CoreException {
		for (IResource res : folder.members()) {
			if (res instanceof IFolder) {
				files.addAll(createFiles((IFolder) res, new LinkedList<File>()));
			} else {
				if (res instanceof IFile) {
					File f = createFile(res);
					files.add(f);
				}
			}
		}
		return files;
	}

	/**
	 * Initialize a file model element {@link File} from an eclipse resource {@link IResource}
	 * @param res the resource
	 * @return the initialized file
	 * @throws CoreException
	 */
	private File createFile(final IResource res) throws CoreException {
		IFileStore fileStore = EFS.getStore(res.getLocationURI());
		File f = BenchmarkFactory.eINSTANCE.createFile();
		f.setSizeInBytes(fileStore.fetchInfo().getLength());
		f.setFilepath(res.getFullPath().toString());
		f.setLines(getLineNumber(res));
		return f;
	}

	/**
	 * Compute the number of lines in a file having as extension the value of the CODE_EXTENSION constant.
	 * @param res the file to compute the number of lines
	 * @return the number of line if source file 0 otherwise
	 */
	private long getLineNumber(final IResource res) {
		int lines = 0;
		if (res == null) {
			MoDiscoLogger.logWarning("Unable to compute the number of lines of an unexisting file", Activator.getDefault());
		} else {
			if (res.getFileExtension() != null) {
				if (res.getFileExtension().endsWith(CODE_EXTENSION)) {
					try {
						java.io.File f = new java.io.File(ResourcesPlugin.getWorkspace().getRoot().getLocation().toString() + res.getFullPath().toString());
						BufferedReader br = new BufferedReader(new FileReader(f));
						for (lines = 0; br.readLine() != null; lines++);
						br.close();
					} catch (IOException e) {
						MoDiscoLogger.logWarning(e, "unable to count the number of lines of " + res.getName(), Activator.getDefault()); 
					} catch (NullPointerException e) {
						MoDiscoLogger.logWarning(e, "unable to count the number of lines of " + res.getName(), Activator.getDefault());
					}
				}
			}
		}
		return lines;
	}

	/**
	 * @see AbstractModelDiscoverer#isApplicableTo(Object)
	 */
	public boolean isApplicableTo(final IProjectSet sources) {
		boolean result = true;
		for (IProject source : sources.getProjects()) {
			result = result && source.getProject().isAccessible();
		}
		return result;
	}

	/**
	 * Launch the discovery by calling {@link DiscovererBenchmarkDiscoverer#discoverBenchmark(IProjectSet, IProgressMonitor)}
	 * @see AbstractModelDiscoverer#discoverElement(Object, IProgressMonitor)
	 */
	@Override
	protected void basicDiscoverElement(final IProjectSet sources, final IProgressMonitor monitor)
			throws DiscoveryException {
		this.discoverBenchmark(sources, monitor);
	}

	public EventAndMemoryRecorder getRecorder() {
		return this.recorder;
	}


	public void setRecorders(final EventAndMemoryRecorder rec) {
		this.recorder = rec;
	}

	public void setDiscovererID(final IDiscovererID discoId) {
		this.discovererID = discoId;
	}

	/**
	 * Setter for the number of iterations, annotated with @Parameter set by the UI
	 * @param it number of iterations
	 */
	@Parameter(name = "NUMBER_OF_ITERATIONS", description = "The number of iterations to do.", requiresInputValue = true)
	public void setIterations(final int it) {
		this.iterations = it;
	}

	/**
	 * Setter for memory usage measure, annotated with @Parameter set by the UI
	 * @param measure true if the memory need to be measured
	 */
	@Parameter(name = "MEASURE_MEMORY_USAGE", description = "Tells if the memory usage should be measured or not.", requiresInputValue = true)
	public void setMeasureMemoryUse(final boolean measure) {
		this.measureMemoryUse = measure;
		if (this.measureMemoryUse) { //putting a default value in case of bad initialization
			if (this.memoryPollingInterval == ZERO) {
				this.memoryPollingInterval = INTERVAL;
			}
		}
	}

	/**
	 * Setter for the memory polling interval, annotated with @Parameter set by the UI
	 * @param memoryInterval memory polling interval in milliseconds
	 */
	@Parameter(name = "MEMORY_POLLING_INTERVAL", description = "The time interval between to memory measurement (default value is 1 sec)", requiresInputValue = false)
	public void setMemoryPollingInterval(final int memoryInterval) {
		this.memoryPollingInterval = memoryInterval;
	}

	/**
	 * Setter for the generation of an HTML report, annotated with @Parameter set by the UI
	 * @param generate true if an HTML report is wanted
	 */
	@Parameter(name = "GENERATE_HTML_REPORT", description = "Tells if a html report should be generated.", requiresInputValue = true)
	public void setGenerateHtmlReport(final boolean generate) {
		this.generateHtmlReport = generate;
	}

	/**
	 * Setter for the output model URI, annotated set by the UI
	 * @param the output model URI
	 */
	public void setTargetURI(final org.eclipse.emf.common.util.URI targetURI) {
		super.setTargetURI(targetURI);
		super.setTargetModel(this.rSet.createResource(targetURI));
	}

	@Parameter(name = "TARGET_URI")
	public org.eclipse.emf.common.util.URI getTargetURI() {
		return super.getTargetURI();
	}

	public IDiscovererID getDiscovererID() {
		return this.discovererID;
	}


	public int getIterations() {
		return this.iterations;
	}

	public boolean isMeasureMemoryUse() {
		return this.measureMemoryUse;
	}

	public int getMemoryPollingInterval() {
		return this.memoryPollingInterval;
	}

	public boolean isGenerateHtmlReport() {
		return this.generateHtmlReport;
	}

	/**
	 * @return the htmlReportLocation
	 */
	public URI getHtmlReportLocation() {
		return this.htmlReportLocation;
	}

	/**
	 * Allow the selection of the HTML report location
	 * @param htmlReportLocation the htmlReportLocation to set
	 */
	@Parameter(name = "HTML_REPORT_LOCATION", description = "Tells the location of the HTML report, should be set if GENERATE_HTML_REPORT is true", requiresInputValue = false)
	public void setHtmlReportLocation(final URI htmlReportLocationParam) {
		this.htmlReportLocation = htmlReportLocationParam;
	}

}
