/*****************************************************************************
 * Copyright (c) 2018 CEA LIST and others.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   CEA LIST - Initial API and implementation
 *   
 *****************************************************************************/

package org.eclipse.papyrus.cdo.benchmarks.tests;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import junit.framework.Assert;

/**
 * @author VL222926
 *
 */
public class ExecutionTimeHelperMerger {

	private String testResultDescription;

	public ExecutionTimeHelperMerger(final String testResultDescription) {
		this.testResultDescription = testResultDescription;
	}

	// nb elements created, elementTypeID, execution
	private Map<Integer, Map<String, List<ExecutionTimeHelper>>> timeHelperMap = new HashMap<Integer, Map<String, List<ExecutionTimeHelper>>>();



	public void addTimeHelper(final ExecutionTimeHelper helper) {
		int nbCreatedElement = helper.getNbCreation();
		Map<String, List<ExecutionTimeHelper>> subMap = timeHelperMap.get(Integer.valueOf(nbCreatedElement));
		if (null == subMap) {
			subMap = new HashMap<String, List<ExecutionTimeHelper>>();
			subMap.put(helper.getElementType(), new ArrayList<ExecutionTimeHelper>());
			timeHelperMap.put(Integer.valueOf(nbCreatedElement), subMap);
		}

		List<ExecutionTimeHelper> helpers = subMap.get(helper.getElementType());
		if (null == helpers) {
			helpers = new ArrayList<ExecutionTimeHelper>();
			subMap.put(helper.getElementType(), helpers);
		}
		helpers.add(helper);
	}

	public boolean isFull() {
		final Iterator<Entry<Integer, Map<String, List<ExecutionTimeHelper>>>> iter = timeHelperMap.entrySet().iterator();
		while (iter.hasNext()) {
			final Entry<Integer, Map<String, List<ExecutionTimeHelper>>> current = iter.next();
			final Map<String, List<ExecutionTimeHelper>> curr = current.getValue();
			final Iterator<Entry<String, List<ExecutionTimeHelper>>> iter2 = curr.entrySet().iterator();
			while (iter2.hasNext()) {
				if (2 != iter2.next().getValue().size()) {
					return false;
				}
			}

		}
		return true;
	}


	/**
	 * @see java.lang.Object#toString()
	 *
	 * @return
	 */
	@Override
	public String toString() {
		final List<Integer> keys = new ArrayList<Integer>(timeHelperMap.keySet());
		Collections.sort(keys);

		final StringBuilder builder = new StringBuilder(testResultDescription);
		builder.append("\n");
		for (int i = 0; i < keys.size(); i++) {
			ExecutionTimeHelper papyrusTimeHelper;
			ExecutionTimeHelper CDOTimeHelper;
			Map<String, List<ExecutionTimeHelper>> subMap = timeHelperMap.get(keys.get(i));
			final Iterator<Entry<String, List<ExecutionTimeHelper>>> subIter = subMap.entrySet().iterator();
			while (subIter.hasNext()) {
				final Entry<String, List<ExecutionTimeHelper>> current = subIter.next();

				List<ExecutionTimeHelper> helpers = current.getValue();
				if (ExecutionTimeHelper.CDO_TYPE.equals(helpers.get(0).getType())) {
					CDOTimeHelper = helpers.get(0);
					papyrusTimeHelper = helpers.get(1);
				} else {
					CDOTimeHelper = helpers.get(1);
					papyrusTimeHelper = helpers.get(0);
				}


				builder.append("Creating " + keys.get(i) + " " + current.getKey());
				builder.append("\n");

				builder.append(" ");
				builder.append("\t");
				builder.append(ExecutionTimeHelper.Papyrus_TYPE);
				builder.append("\t");
				builder.append(ExecutionTimeHelper.CDO_TYPE);
				builder.append("\n");

				builder.append(createStepsRows(ExecutionTimeHelper.STEP_1, papyrusTimeHelper, CDOTimeHelper));
				builder.append(createStepsRows(ExecutionTimeHelper.STEP_2, papyrusTimeHelper, CDOTimeHelper));
				builder.append(createStepsRows(ExecutionTimeHelper.STEP_3, papyrusTimeHelper, CDOTimeHelper));
				builder.append(createStepsRows(ExecutionTimeHelper.STEP_4, papyrusTimeHelper, CDOTimeHelper));
				builder.append(createStepsRows(ExecutionTimeHelper.STEP_5, papyrusTimeHelper, CDOTimeHelper));
				builder.append(createStepsRows(ExecutionTimeHelper.STEP_6, papyrusTimeHelper, CDOTimeHelper));
				builder.append(createStepsRows(ExecutionTimeHelper.STEP_7, papyrusTimeHelper, CDOTimeHelper));

			}
		}
		return builder.toString();
	}


	private String createStepsRows(final String step, final ExecutionTimeHelper papyrusHelper, final ExecutionTimeHelper cdoHelper) {
		final StringBuilder builder = new StringBuilder(step);
		builder.append("\t");
		builder.append(" ");
		builder.append("\t");
		builder.append(" ");
		builder.append("\n");

		builder.append(createValueList(papyrusHelper.getValuesForStep(step), cdoHelper.getValuesForStep(step)));
		builder.append("\n");

		return builder.toString();
	}

	private String createValueList(final List<Long> papyrusValues, final List<Long> cdoValues) {
		if (papyrusValues != null && cdoValues != null) {
			final StringBuilder builder = new StringBuilder();
			org.junit.Assert.assertEquals(papyrusValues.size(), cdoValues.size());
			for (int i = 0; i < papyrusValues.size() - 1; i++) {
				builder.append(" ");
				builder.append("\t");
				builder.append(Long.valueOf(papyrusValues.get(i + 1) - papyrusValues.get(i)) + "ms");
				builder.append("\t");
				builder.append(Long.valueOf(cdoValues.get(i + 1) - cdoValues.get(i)) + "ms");
				builder.append("\n");
			}
			return builder.toString();
		}
		return "";
	}

}
