/*******************************************************************************
 * Copyright (c) 2012 EclipseSource Muenchen GmbH.
 * 
 * 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:
 ******************************************************************************/
package org.eclipse.emf.emfstore.fuzzy;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.emfstore.fuzzy.Annotations.Data;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkField;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;

/**
 * A {@link org.junit.runner.Runner} for each {@link org.junit.runners.model.TestClass}.
 * Used in the {@link FuzzyRunner}.
 * 
 * @author Julian Sommerfeldt
 * 
 */
public class FuzzyTestClassRunner extends BlockJUnit4ClassRunner {

	/**
	 * Which run is it?
	 */
	private int counter;

	/**
	 * The {@link FuzzyDataProvider}, which "contains" the data for the test.
	 */
	private FuzzyDataProvider<?> dataProvider;

	/**
	 * The {@link FrameworkField} of the {@link TestClass} where to put in the data.
	 */
	private FrameworkField dataField;

	/**
	 * The {@link FrameworkField} for the {@link Util}.
	 */
	private FrameworkField utilField;

	private Util util;

	private FrameworkField optionsField;

	/**
	 * Constructor.
	 * 
	 * @param type The testclass
	 * @param dataProvider The {@link FuzzyDataProvider} providing the data to put into the dataField
	 * @param dataField The datafield in the testclass
	 * @param utilField the utilfield in the testclass
	 * @param optionsField the options field in the testclass
	 * @param util The {@link Util} class
	 * @param counter The counter of the run
	 * @throws InitializationError If there was a problem during the initialization of the test
	 */
	FuzzyTestClassRunner(Class<?> type, FuzzyDataProvider<?> dataProvider, FrameworkField dataField,
		FrameworkField utilField, FrameworkField optionsField, Util util, int counter) throws InitializationError {
		super(type);
		this.counter = counter;
		this.dataField = dataField;
		this.utilField = utilField;
		this.optionsField = optionsField;
		this.util = util;
		this.dataProvider = dataProvider;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Object createTest() {
		try {
			// create a new instance of the testclass
			Object testInstance = getTestClass().getOnlyConstructor().newInstance();

			// set the options to dataprovider
			if (optionsField != null) {
				Object options = getValueFromField(optionsField.getField(), testInstance);
				if (options == null) {
					throw new IllegalStateException(
						"The options field has to be not null! Fill it or remove annotation.");
				}
				try {
					dataProvider.setOptions((Map<String, Object>) options);
				} catch (ClassCastException e) {
					throw new ClassCastException("The options field is not of type: Map<String, Object>!");
				}
			}

			// get the new data from dataprovider
			Object data = dataProvider.get(counter);

			// set the data to the datafield
			setValueToField(dataField.getField(), testInstance, data,
				"The field annotated with " + Data.class.getSimpleName()
					+ " does not fit to the type of the dataprovider (" + dataProvider.getClass() + ").");

			// set the util to the util field
			if (util != null && utilField != null) {
				setValueToField(utilField.getField(), testInstance, util,
					"The field annotated " + Util.class.getSimpleName() + " does not fit to the Util type!");
			}

			return testInstance;		
		} catch (InstantiationException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} catch (InvocationTargetException e) {
			throw new RuntimeException(e);
		}
	}

	private Object getValueFromField(Field field, Object instance) throws IllegalAccessException {
		try{
			field.setAccessible(true);
			Object o = field.get(instance);
			return o;
		} finally {
			field.setAccessible(false);
		}
	}

	private void setValueToField(Field field, Object instance, Object value, String errorMsg) throws IllegalAccessException
		 {
		try {
			field.setAccessible(true);
			field.set(instance, value);
		} finally {
			field.setAccessible(false);
		}
	}

	@Override
	protected List<FrameworkMethod> getChildren() {
		List<Test> testsToRun = dataProvider.getTestsToRun();
		List<FrameworkMethod> allChildren = super.getChildren();

		// check if it should filter tests
		if (testsToRun != null) {
			List<FrameworkMethod> filteredChildren = new ArrayList<FrameworkMethod>();
			for (Test test : testsToRun) {
				String name = test.getName();
				int seedCount = test.getSeedCount();
				for (FrameworkMethod child : allChildren) {
					if (seedCount == counter && name.equals(child.getName())) {
						filteredChildren.add(child);
					}
				}
			}
			return filteredChildren;
		}

		// if not return all children
		return allChildren;
	}

	private String testName(String name) {
		return String.format("%s%s[%s]", name, FuzzyRunner.NAME_SEPARATOR, counter);
	}

	@Override
	protected String testName(final FrameworkMethod method) {
		return testName(method.getName());
	}

	@Override
	protected String getName() {
		return String.format("%s%s[%s]", getTestClass().getName(), FuzzyRunner.NAME_SEPARATOR, counter);
	}

	@Override
	protected Statement classBlock(RunNotifier notifier) {
		return childrenInvoker(notifier);
	}
}