/*******************************************************************************
 * Copyright (c) 2009, 2019 Mia-Software and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Gregoire DUPE (Mia-Software)
 *    Nicolas Bros (Mia-Software) - Bug 335003 - [Discoverer] : Existing Discoverers Refactoring based on new framework
 *    Nicolas Bros (Mia-Software) - Bug 346207 - Memory behaviour benchmark report charts are empty
 *******************************************************************************/
package org.eclipse.modisco.java.discoverer.benchmark;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.eclipse.birt.chart.device.IDeviceRenderer;
import org.eclipse.birt.chart.factory.GeneratedChartState;
import org.eclipse.birt.chart.factory.Generator;
import org.eclipse.birt.chart.model.ChartWithAxes;
import org.eclipse.birt.chart.model.attribute.Bounds;
import org.eclipse.birt.chart.model.attribute.ChartDimension;
import org.eclipse.birt.chart.model.attribute.ColorDefinition;
import org.eclipse.birt.chart.model.attribute.LegendItemType;
import org.eclipse.birt.chart.model.attribute.LineAttributes;
import org.eclipse.birt.chart.model.attribute.LineStyle;
import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;
import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl;
import org.eclipse.birt.chart.model.attribute.impl.LineAttributesImpl;
import org.eclipse.birt.chart.model.attribute.impl.TextImpl;
import org.eclipse.birt.chart.model.component.Axis;
import org.eclipse.birt.chart.model.component.ComponentFactory;
import org.eclipse.birt.chart.model.component.Label;
import org.eclipse.birt.chart.model.component.Scale;
import org.eclipse.birt.chart.model.component.Series;
import org.eclipse.birt.chart.model.component.impl.LabelImpl;
import org.eclipse.birt.chart.model.component.impl.SeriesImpl;
import org.eclipse.birt.chart.model.data.NumberDataElement;
import org.eclipse.birt.chart.model.data.NumberDataSet;
import org.eclipse.birt.chart.model.data.SeriesDefinition;
import org.eclipse.birt.chart.model.data.impl.NumberDataSetImpl;
import org.eclipse.birt.chart.model.data.impl.SeriesDefinitionImpl;
import org.eclipse.birt.chart.model.impl.ChartWithAxesImpl;
import org.eclipse.birt.chart.model.type.LineSeries;
import org.eclipse.birt.chart.model.type.impl.LineSeriesImpl;
import org.eclipse.birt.chart.util.PluginSettings;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
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.modisco.infra.common.core.logging.MoDiscoLogger;
import org.eclipse.modisco.infra.discovery.benchmark.Benchmark;
import org.eclipse.modisco.infra.discovery.benchmark.BenchmarkFactory;
import org.eclipse.modisco.infra.discovery.benchmark.Discovery;
import org.eclipse.modisco.infra.discovery.benchmark.MultiProjectBenchmark;
import org.eclipse.modisco.java.discoverer.benchmark.emfstat.DiscoverJavaModelFromJavaProjectEMFStat;
import org.eclipse.modisco.java.discoverer.benchmark.emfstat.Statistics;
import org.eclipse.modisco.java.discoverer.benchmark.javaBenchmark.CDODiscovery;
import org.eclipse.modisco.java.discoverer.benchmark.javaBenchmark.JavaBenchmarkFactory;
import org.eclipse.modisco.java.discoverer.benchmark.javaBenchmark.JavaDiscoveredProject;
import org.eclipse.modisco.java.discoverer.benchmark.template.html.HtmlReport;
import org.eclipse.modisco.java.discoverer.cdo.JavaDiscovererCDO;
import org.eclipse.swt.graphics.Point;

/**
 * @author Gregoire DUPE (Mia-Software)
 *
 */
public class Report {
	private static final int MINUTE_MS_RANGE = 60000;
	private static final int CHART_SIZE = 1000;
	private static final int RESCALE_COEF = 10;
	private static final double BOUNDS_SCALE_CONST = 72d;
	public static final String HTMLREPORT_FILE_NAME = "report.html"; //$NON-NLS-1$
	private final IProject statProject;
	private final Map<Integer, ArrayList<Float>> map = new HashMap<Integer, ArrayList<Float>>();
	private final Map<String, Integer> titleMap = new HashMap<String, Integer>();
	private int index = 0;

	public Report(final IProject statProject) {
		this.statProject = statProject;
	}

	public MultiProjectBenchmark generate() throws CoreException, IOException {
		MultiProjectBenchmark benchmark = buildReportModelAndDiagrams();
		generateHTML(benchmark, this.statProject.getLocation().toFile());
		return benchmark;
	}

	private MultiProjectBenchmark buildReportModelAndDiagrams() throws CoreException, IOException {
		ResourceSet resourceSet = new ResourceSetImpl();
		URI uri = URI.createURI("platform:/resource/" //$NON-NLS-1$
				+ this.statProject.getName() + "/report.xmi"); //$NON-NLS-1$
		Resource modelResource = resourceSet.createResource(uri);
		MultiProjectBenchmark benchmark = BenchmarkFactory.eINSTANCE.createMultiProjectBenchmark();
		modelResource.getContents().add(benchmark);
		List<IStatus> errors = new ArrayList<IStatus>();
		this.statProject.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
		for (IResource resource : this.statProject.members()) {
			try {
				if (resource instanceof IFile) {
					IFile file = (IFile) resource;
					if (file.getLocation().getFileExtension().equals(Statistics.TSV_FILE_EXT)) {
						String lastLine1 = ""; //$NON-NLS-1$
						String lastLine2 = ""; //$NON-NLS-1$
						BufferedReader bufferReader = new BufferedReader(new FileReader(file
								.getLocation().toFile()));
						String line = bufferReader.readLine();
						titleLine(line);
						line = bufferReader.readLine();
						int maxUsedMemory = 0;
						while (line != null) {
							addToSeries(line);
							lastLine2 = lastLine1;
							lastLine1 = line;
							int usedMemory = new Integer(getValue(line, Statistics.USED_MEMORY));
							maxUsedMemory = Math.max(maxUsedMemory, usedMemory);
							line = bufferReader.readLine();
						}
						IResource txtResource = resource
								.getParent()
								.findMember(
										resource.getName()
												.replaceAll(
														"(.*)" + Statistics.TSV_FILE_EXT, "$1" + Statistics.PROPERTIES_FILE_EXT)); //$NON-NLS-1$ //$NON-NLS-2$
						Properties properties = new Properties();
						properties.load(txtResource.getLocationURI().toURL().openStream());
						Discovery discovery;
						JavaDiscoveredProject benchmarkedProject = JavaBenchmarkFactory.eINSTANCE
								.createJavaDiscoveredProject();
						String storageKind = properties
								.getProperty(DiscoverJavaModelFromJavaProjectEMFStat.STORAGE_KIND);
						if (storageKind != null && storageKind.equals("CDO")) { //$NON-NLS-1$
							CDODiscovery cdoDiscovery = JavaBenchmarkFactory.eINSTANCE
									.createCDODiscovery();
							discovery = cdoDiscovery;
							cdoDiscovery.setVersion(properties
									.getProperty(JavaDiscovererCDO.CDO_VERSION));
							cdoDiscovery.setServerDescription(properties
									.getProperty(JavaDiscovererCDO.CDO_SERVER_DESCRIPTION));
							cdoDiscovery.setRevisedLruCapacity(new Integer(properties
									.getProperty(JavaDiscovererCDO.REVISED_LRU_CAPACITY)));

							cdoDiscovery.setCacheType(properties
									.getProperty(JavaDiscovererCDO.CDO_CACHE_TYPE));
							cdoDiscovery.setCurrentLruCapacity(new Integer(properties
									.getProperty(JavaDiscovererCDO.CURRENT_LRU_CAPACITY)));
							try {
								cdoDiscovery.setInitTimeInSeconds(new Double(properties
										.getProperty(Statistics.INIT_TIME))
										/ Report.MINUTE_MS_RANGE);
							} catch (Exception e) {
								MoDiscoLogger.logError(e, Activator.getDefault());
								IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
										e.getMessage(), e);
								errors.add(status);
							}
						} else {
							discovery = BenchmarkFactory.eINSTANCE.createDiscovery();
						}

						benchmark.getProjects().add(benchmarkedProject);
						benchmarkedProject.getDiscoveries().add(discovery);
						benchmarkedProject
								.setName(properties
										.getProperty(DiscoverJavaModelFromJavaProjectEMFStat.JAVA_PROJECT_NAME));

						discovery.setName(resource.getName().replaceAll(
								"(.*)\\." + Statistics.TSV_FILE_EXT, "$1")); //$NON-NLS-1$ //$NON-NLS-2$
						discovery.setMaxUsedMemoryInBytes(maxUsedMemory);
						discovery.setMetaModelVariant(properties
								.getProperty(DiscoverJavaModelFromJavaProjectEMFStat.MM_VARIANT));
						discovery.setAlgorithmVariant(properties
								.getProperty(DiscoverJavaModelFromJavaProjectEMFStat.ALGO_VARIANT));
						discovery.setSaveTimeInSeconds(new Double(getValue(lastLine2,
								Statistics.SAVE)) / Report.MINUTE_MS_RANGE);
						discovery.setTotalExecutionTimeInSeconds(new Double(getValue(lastLine2,
								Statistics.SINCEBEGIN)) / Report.MINUTE_MS_RANGE);
						discovery
								.setDiscovererClassName(properties
										.getProperty(DiscoverJavaModelFromJavaProjectEMFStat.DISCOVERER_CLASS_NAME));
						// configuration
						// .setDicoveryDate(new Date(
						// properties
						// .getProperty(DiscoverJavaModelFromJavaProjectEMFStat.DISCOVERY_DATE)));
						benchmark.setJvmMaxHeapInMiB(new Integer(properties.getProperty(
								DiscoverJavaModelFromJavaProjectEMFStat.XMX).replaceAll(
								"^([0-9]+).*", "$1"))); //$NON-NLS-1$//$NON-NLS-2$

						rescaleDebugCode(discovery.getMaxUsedMemoryInBytes());

						birt(file, benchmark, discovery);
					}
				}

				this.statProject.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
			} catch (Exception e) {
				MoDiscoLogger.logError(e, Activator.getDefault());
				IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e);
				errors.add(status);
			}
		}
		modelResource.save(Collections.EMPTY_MAP);
		if (errors.size() > 0) {
			CoreException e = new CoreException(new MultiStatus(Activator.PLUGIN_ID, IStatus.ERROR,
					errors.toArray(new IStatus[] {}), "", //$NON-NLS-1$
					new Exception()));
			MoDiscoLogger.logError(e, Activator.getDefault());
			// throw e;
		}
		return benchmark;
	}

	private void birt(final IFile file, final Benchmark benchmark, final Discovery discovery) {
		String diagramTitle = ""; //$NON-NLS-1$
		if (discovery instanceof CDODiscovery) {
			diagramTitle += "CDO "; //$NON-NLS-1$
		}
		if (discovery.getAlgorithmVariant() != null) {
			diagramTitle += discovery.getAlgorithmVariant() + " "; //$NON-NLS-1$
		}
		if (discovery.getMetaModelVariant() != null) {
			diagramTitle += discovery.getMetaModelVariant() + " "; //$NON-NLS-1$
		}
		if (discovery instanceof CDODiscovery) {
			CDODiscovery cdoConfiguration = (CDODiscovery) discovery;
			diagramTitle += "(" //$NON-NLS-1$
					+ cdoConfiguration.getServerDescription() + ")"; //$NON-NLS-1$
		}
		ChartWithAxes chart = ChartWithAxesImpl.create();
		chart.setDimension(ChartDimension.TWO_DIMENSIONAL_WITH_DEPTH_LITERAL);
		chart.getPlot().setBackground(ColorDefinitionImpl.WHITE());
		chart.getPlot().getClientArea().setBackground(ColorDefinitionImpl.WHITE());

		chart.getLegend().setItemType(LegendItemType.SERIES_LITERAL);
		chart.getLegend().setVisible(true);

		chart.getTitle().getLabel().getCaption().setValue(diagramTitle);
		// chart.getTitle().getLabel().getCaption().getFont().setSize(14);
		// chart.getTitle().getLabel().getCaption().getFont().setName(FONT_NAME);

		Axis xAxis = chart.getPrimaryBaseAxes()[0];
		xAxis.getTitle().setCaption(TextImpl.create(Messages.Report_0));
		xAxis.getTitle().setVisible(true);

		// xAxis.getTitle().getCaption().setValue("xTitle");

		NumberDataSet categoryValues = NumberDataSetImpl.create(this.map.get(-1));

		Series xAxisSerie = SeriesImpl.create();
		xAxisSerie.setDataSet(categoryValues);
		SeriesDefinition xSeriesDefinition = SeriesDefinitionImpl.create();
		xSeriesDefinition.getSeriesPalette().shift(1);
		xAxis.getSeriesDefinitions().add(xSeriesDefinition);
		xSeriesDefinition.getSeries().add(xAxisSerie);

		Axis yAxis = chart.getPrimaryOrthogonalAxis(xAxis);
		yAxis.getTitle().setVisible(true);
		yAxis.getTitle().getCaption().setValue("MB"); //$NON-NLS-1$
		// yAxis.getScale().setStep(1.0);
		createYAxis(yAxis, "USED_MEMORY", ColorDefinitionImpl.BLACK()); //$NON-NLS-1$
		createYAxis(yAxis, "DEBUG_CODE", ColorDefinitionImpl.BLUE()); //$NON-NLS-1$
		Scale scale = ComponentFactory.eINSTANCE.createScale();
		NumberDataElement dataElement = org.eclipse.birt.chart.model.data.DataFactory.eINSTANCE
				.createNumberDataElement();
		dataElement.setValue(discovery.getMaxUsedMemoryInBytes());
		scale.setMax(dataElement);
		NumberDataElement dataElement2 = org.eclipse.birt.chart.model.data.DataFactory.eINSTANCE
				.createNumberDataElement();
		dataElement2.setValue(0);
		scale.setMin(dataElement2);
		yAxis.setScale(scale);

		// createYAxis(yAxis, "SINCEBEGIN (ms)", ColorDefinitionImpl.GREEN());

		ResourceSet resourceSet = new ResourceSetImpl();
		Resource resource = resourceSet.createResource(URI.createFileURI(file.getLocation()
				.toString().replaceAll("(.*)" + Statistics.TSV_FILE_EXT, "$1xmi"))); //$NON-NLS-1$ //$NON-NLS-2$
		resource.getContents().add(chart);

		try {
			resource.save(Collections.EMPTY_MAP);
			PluginSettings ps = PluginSettings.instance();
			IDeviceRenderer render = ps.getDevice("dv.PNG"); //$NON-NLS-1$
			render.setProperty(IDeviceRenderer.FILE_IDENTIFIER, file.getLocation().toString()
					.replaceAll("(.*)" + Statistics.TSV_FILE_EXT, "$1png")); //$NON-NLS-1$ //$NON-NLS-2$
			Point size = new Point(Report.CHART_SIZE, Report.CHART_SIZE);
			Bounds bounds = BoundsImpl.create(0, 0, size.x, size.y);
			int resolution = render.getDisplayServer().getDpiResolution();
			bounds.scale(Report.BOUNDS_SCALE_CONST / resolution);
			Generator generator = Generator.instance();
			GeneratedChartState state = generator.build(render.getDisplayServer(), chart, bounds,
					null, null, null);
			generator.render(render, state);
		} catch (Exception ex) {
			Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), ex);
			Activator.getDefault().getLog().log(status);
		}

	}

	/**
	 * @param benchmark
	 * @throws IOException
	 */
	private static void generateHTML(final Benchmark benchmark, final File targetDirectory)
			throws IOException {
		new HtmlReport(benchmark, targetDirectory, new ArrayList<Object>()).doGenerate(null);
	}

	private void createYAxis(final Axis yAxis, final String columnName,
			final ColorDefinition colorDefinition) {

		LineSeries serie = (LineSeries) LineSeriesImpl.create();
		serie.setSeriesIdentifier(columnName);

		Integer indexx = this.titleMap.get(columnName);
		Object values = this.map.get(indexx);
		NumberDataSet dataSet = NumberDataSetImpl.create(values);
		serie.setDataSet(dataSet);

		serie.getMarkers().clear();

		LineAttributes lineAttr = LineAttributesImpl.create(colorDefinition,
				LineStyle.SOLID_LITERAL, 1);
		serie.setLineAttributes(lineAttr);

		Label label = LabelImpl.create();
		label.setCaption(TextImpl.create(columnName));
		label.setVisible(false);
		serie.setLabel(label);

		SeriesDefinition seriesDefinition = SeriesDefinitionImpl.create();
		seriesDefinition.getSeries().add(serie);
		yAxis.getSeriesDefinitions().add(seriesDefinition);

	}

	/**
	 *
	 */
	private void rescaleDebugCode(final long maxMemory) {
		float coef = new Float(maxMemory) / Report.RESCALE_COEF;
		ArrayList<Float> l = this.map.get(this.titleMap.get(Statistics.DEBUG_CODE));
		ArrayList<Float> l2 = new ArrayList<Float>();
		for (Float f : l) {
			l2.add(f * coef);
		}
		this.map.put(this.titleMap.get(Statistics.DEBUG_CODE), l2);

	}

	private void addToSeries(final String line) {
		this.index++;
		this.map.get(-1).add(new Float(this.index));
		String[] splits = line.split("\t"); //$NON-NLS-1$
		for (int i = 0; i < splits.length; i++) {
			Float f;
			try {
				f = new Float(splits[i]);
			} catch (Exception e) {
				f = new Float(0);
			}
			List<Float> serie = this.map.get(i);
			serie.add(f);
		}
	}

	private String getValue(final String line, final String columnName) {
		try {
			String[] splits = line.split("\t"); //$NON-NLS-1$
			return splits[this.titleMap.get(columnName).intValue()];
		} catch (Exception e) {
			return ""; //$NON-NLS-1$
		}
	}

	private void titleLine(final String line) {
		String[] titles = line.split("\t"); //$NON-NLS-1$
		this.titleMap.put("index", -1); //$NON-NLS-1$
		this.map.put(-1, new ArrayList<Float>());
		for (int i = 0; i < titles.length; i++) {
			this.titleMap.put(titles[i], i);
			this.map.put(i, new ArrayList<Float>());
		}
	}

}
