package de.ugoe.cs.quest.plugin.guitar;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import de.ugoe.cs.quest.eventcore.Event;
import de.ugoe.cs.quest.plugin.guitar.eventcore.EFGEvent;
import edu.umd.cs.guitar.model.IO;
import edu.umd.cs.guitar.model.data.EFG;
import edu.umd.cs.guitar.model.data.EventType;
import edu.umd.cs.guitar.model.data.StepType;
import edu.umd.cs.guitar.model.data.TestCase;

/**
 * <p>
 * Parser for GUITAR test case files.
 * </p>
 * 
 * @author Steffen Herbold
 * @version 1.0
 */
public class GUITARTestCaseParser {

	/**
	 * <p>
	 * Name of the EFG file for the application the test cases that are parsed
	 * are generated for.
	 * </p>
	 */
	private String efgFileName = null;

	/**
	 * <p>
	 * Internal handle to the parsed EFG.
	 * </p>
	 */
	private EFG efg = null;

	/**
	 * <p>
	 * Constructor. Creates a new GUITARTestCaseParser. No EFG file is
	 * associated with this parser.
	 * </p>
	 */
	public GUITARTestCaseParser() {

	}

	/**
	 * <p>
	 * Constructor. Creates a new GUITARTestCaseParser.
	 * </p>
	 * 
	 * @param efgFileName
	 *            EFG file associated with the test cases that are parsed.
	 */
	public GUITARTestCaseParser(String efgFileName) {
		this.efgFileName = efgFileName;
	}

	/**
	 * <p>
	 * Parses a GUITAR test case file and returns its contents as an event
	 * sequence.
	 * </p>
	 * 
	 * @param testcaseFile
	 *            file that is parsed
	 * @return event sequence describing the test case
	 */
	public List<Event<?>> parseTestCaseFile(File testcaseFile) {
		TestCase testcase = (TestCase) IO.readObjFromFile(
				testcaseFile.getAbsolutePath(), TestCase.class);
		List<StepType> steps = testcase.getStep();
		List<Event<?>> sequence = new LinkedList<Event<?>>();
		for (StepType step : steps) {
			String eventId = step.getEventId();
			EFGEvent event = new EFGEvent(eventId);
			event.setTarget(getWidgetId(eventId));
			sequence.add(event);
		}
		return sequence;
	}

	/**
	 * <p>
	 * If {@link #efgFileName} is specified, this function retrieves the
	 * widgetId of the widget the event with id eventId belongs to from the EFG.
	 * </p>
	 * 
	 * @param eventId
	 * @return widgetId of the associated widget; null if {@link #efgFileName}
	 *         ==null or no widgetId for the event is found in the EFG
	 */
	private String getWidgetId(String eventId) {
		if (eventId != null && efgFileName != null) {
			if (efg == null) {
				efg = (EFG) IO.readObjFromFile(efgFileName, EFG.class);
			}
			for (EventType event : efg.getEvents().getEvent()) {
				if (eventId.equals(event.getEventId())) {
					return event.getWidgetId();
				}
			}
		}
		return null;
	}
}
