/*******************************************************************************
 * Copyright (c) 2015 Christian Pontesegger 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:
 *     Christian Pontesegger - initial API and implementation
 *******************************************************************************/
package org.eclipse.ease.modules.unittest.ui.views;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.ease.modules.unittest.ITestListener;
import org.eclipse.ease.modules.unittest.components.TestFile;
import org.eclipse.ease.modules.unittest.components.TestStatus;
import org.eclipse.ease.modules.unittest.components.TestSuite;
import org.eclipse.ease.modules.unittest.ui.Activator;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.XMLMemento;

public class SuiteRuntimeInformation implements ITestListener {

	private static final String XML_PARAMETER_TIMING = "timing";
	private static final String XML_PARAMETER_INDEX = "index";
	private static final String XML_NODE_RUN = "run";
	private static final String XML_NODE_FILE = "file";

	/** Typical script runtime. In case we have no other information. */
	private static final long DEFAULT_RUNTIME = 10000;
	private static final int RUNS_TO_SAVE = 10;

	private class RuntimeInformation {

		private final ArrayList<Long> fTimings = new ArrayList<Long>();

		public synchronized long getEstimatedRuntime() {
			if (fTimings.isEmpty())
				return DEFAULT_RUNTIME;

			// use a linear weighted average
			int weight = 0;
			long timing = 0;
			for (final Long time : fTimings) {
				weight++;
				timing += time * weight;
			}

			timing /= (weight + 1) * (weight / 2.0);

			return timing;
		}

		public synchronized void addRuntime(final long time) {
			fTimings.add(time);
		}

		public ArrayList<Long> getTimings() {
			return fTimings;
		}
	}

	private final HashMap<String, RuntimeInformation> fRuntimes = new HashMap<String, RuntimeInformation>();
	private List<TestFile> fTestFiles;
	private long fEstimatedEndOfTests;
	private final TestSuite fTestSuite;

	public SuiteRuntimeInformation(final TestSuite suite) {
		fTestSuite = suite;
		load();

		// suite might already have started
		fTestFiles = fTestSuite.getActiveTestFiles();

		suite.addTestListener(this);
	}

	private void load() {
		try {
			final XMLMemento root = XMLMemento.createReadRoot(new FileReader(getSettingsFile()));

			final IWorkspaceRoot workspace = ResourcesPlugin.getWorkspace().getRoot();
			for (final IMemento fileNode : root.getChildren(XML_NODE_FILE)) {
				for (final IMemento runNode : fileNode.getChildren(XML_NODE_RUN))
					// TODO currently ignore index, expect we read sequentially
					addTiming(fileNode.getTextData(), Long.parseLong(runNode.getString(XML_PARAMETER_TIMING)));
			}

		} catch (final Exception e) {
			// cannot load stats, ignore
		}
	}

	public synchronized void save() {
		FileOutputStream outputStream = null;
		try {
			outputStream = new FileOutputStream(getSettingsFile());

			// create xml output
			final XMLMemento rootNode = XMLMemento.createWriteRoot("root");
			for (final Entry<String, RuntimeInformation> entry : fRuntimes.entrySet()) {
				final IMemento fileNode = rootNode.createChild(XML_NODE_FILE);
				fileNode.putTextData(entry.getKey());

				final List<Long> timings = entry.getValue().getTimings();

				int nodeIndex = 0;
				for (int index = Math.max(0, timings.size() - RUNS_TO_SAVE); index < timings.size(); index++) {
					final IMemento runNode = fileNode.createChild(XML_NODE_RUN);
					runNode.putInteger(XML_PARAMETER_INDEX, nodeIndex++);
					runNode.putString(XML_PARAMETER_TIMING, Long.toString(timings.get(index)));
				}
			}

			rootNode.save(new OutputStreamWriter(outputStream));

		} catch (final Exception e) {
		} finally {
			try {
				outputStream.close();
			} catch (final IOException e) {
			}
		}
	}

	@Override
	public synchronized void notify(final Object testObject, final TestStatus status) {
		if ((testObject instanceof TestSuite) && (status == TestStatus.RUNNING)) {
			// testsuite started
			fTestFiles = fTestSuite.getActiveTestFiles();

			estimateEndOfTests();

		} else if ((testObject instanceof TestFile) && (status != TestStatus.RUNNING) && (status != TestStatus.NOT_RUN)) {
			addTiming(createTestToken((TestFile) testObject), ((TestFile) testObject).getExecutionTime());
			fTestFiles.remove(testObject);

			estimateEndOfTests();
		}
	}

	private static String createTestToken(final TestFile testFile) {
		final Object file = testFile.getFile();

		if (file instanceof IFile)
			return ((IFile) file).getFullPath().toPortableString();

		if (file instanceof File)
			return ((File) file).getAbsolutePath();

		if (file != null)
			return file.toString();

		return "<undefind>";
	}

	private synchronized void addTiming(final String fileIdentifier, final long timing) {
		if (!fRuntimes.containsKey(fileIdentifier))
			fRuntimes.put(fileIdentifier, new RuntimeInformation());

		fRuntimes.get(fileIdentifier).addRuntime(timing);
	}

	private File getSettingsFile() {
		final IPath path = Activator.getDefault().getStateLocation().append("timing_" + fTestSuite.getModel().getFile().getProject().hashCode() + ".xml");
		return path.toFile();
	}

	private synchronized void estimateEndOfTests() {
		long time = 0;
		for (final TestFile file : fTestFiles) {
			final RuntimeInformation info = fRuntimes.get(createTestToken(file));
			time += (info != null) ? info.getEstimatedRuntime() : getAverageTestTime();
		}

		fEstimatedEndOfTests = System.currentTimeMillis() + time;
	}

	private synchronized long getAverageTestTime() {
		long time = 0;
		int items = 0;

		for (final RuntimeInformation info : fRuntimes.values()) {
			if (info.getEstimatedRuntime() > 0) {
				time += info.getEstimatedRuntime();
				items++;
			}
		}

		if (items > 0)
			return time / items;

		// we do not have any information at all, assume a typical test time of 10 seconds
		return DEFAULT_RUNTIME;
	}

	public long getEstimatedTestTime() {
		return fEstimatedEndOfTests - System.currentTimeMillis();
	}
}
