/*******************************************************************************
 * Copyright (c) 2005, 2015 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.ant.internal.launching.debug;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;
import java.util.Vector;

import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.Location;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.MacroInstance;
import org.eclipse.ant.internal.launching.debug.model.DebugMessageIds;

public class AntDebugState {

	private static final String fgAntTaskName = "ant"; //$NON-NLS-1$
	private static final String fgAntCallTaskName = "antcall"; //$NON-NLS-1$

	private IDebugBuildLogger fLogger;
	@SuppressWarnings("unused")
	private Stack<Task> fTasks = new Stack<Task>();
	@SuppressWarnings("unused")
	private Map<Task, Object> fTaskToProxies = new HashMap<Task, Object>();
	private Task fCurrentTask;
	private Task fStepOverTask;
	private Task fStepIntoTask;
	private Task fLastTaskFinished;

	// properties set before execution
	private Map<String, Object> fInitialProperties = null;
	private Map<String, Object> fProperties = null;

	private Map<Project, Vector<?>> fProjectToTargetNames = null;
	private Map<Project, Map<Target, Vector<Target>>> fProjectToMapOfTargetToBuildSequence = null;
	@SuppressWarnings("unused")
	private Stack<Target> fTargetsToExecute = new Stack<Target>();
	@SuppressWarnings("unused")
	private Stack<Target> fTargetsExecuting = new Stack<Target>();

	private boolean fConsiderTargetBreakpoints = false;
	private boolean fShouldSuspend;
	private boolean fClientSuspend = false;
	private boolean fStepIntoSuspend = false;
	private boolean fIsAfterTaskEvent = false;

	public AntDebugState(IDebugBuildLogger logger) {
		fLogger = logger;
	}

	@SuppressWarnings("unused")
	public void buildStarted() {
		fProjectToTargetNames = new HashMap<Project, Vector<?>>();
		fProjectToMapOfTargetToBuildSequence = new HashMap<Project, Map<Target, Vector<Target>>>();
	}

	/**
	 * Call-back from {@link org.eclipse.ant.internal.launching.runtime.logger.AntProcessDebugBuildLogger} when the build has finished
	 * 
	 * @since 1.0.1
	 */
	public void buildFinished() {
		if (fProjectToTargetNames != null) {
			fProjectToTargetNames.clear();
		}
		if (fProjectToMapOfTargetToBuildSequence != null) {
			fProjectToMapOfTargetToBuildSequence.clear();
		}
		fTargetsExecuting.clear();
		fTargetsToExecute.clear();
		if (fInitialProperties != null) {
			fInitialProperties.clear();
		}
		if (fProperties != null) {
			fProperties.clear();
		}
		if (fTaskToProxies != null) {
			fTaskToProxies.clear();
		}
		if (fTasks != null) {
			fTasks.clear();
		}
	}

	public void waitIfSuspended() {
		fLogger.waitIfSuspended();
	}

	public Task getLastTaskFinished() {
		return fLastTaskFinished;
	}

	private void setLastTaskFinished(Task lastTaskFinished) {
		fLastTaskFinished = lastTaskFinished;

	}

	public Task getCurrentTask() {
		return fCurrentTask;
	}

	public void setCurrentTask(Task currentTask) {
		fCurrentTask = currentTask;

	}

	private Map<String, Object> getInitialProperties() {
		return fInitialProperties;
	}

	public Task getStepOverTask() {
		return fStepOverTask;
	}

	public void setStepOverTask(Task stepOverTask) {
		fStepOverTask = stepOverTask;

	}

	private boolean considerTargetBreakpoints() {
		return fConsiderTargetBreakpoints;
	}

	private void setConsiderTargetBreakpoints(boolean considerTargetBreakpoints) {
		fConsiderTargetBreakpoints = considerTargetBreakpoints;
	}

	private Stack<Task> getTasks() {
		return fTasks;
	}

	public void setShouldSuspend(boolean shouldSuspend) {
		fShouldSuspend = shouldSuspend;
	}

	public boolean shouldSuspend() {
		return fShouldSuspend;
	}

	private Map<Target, Vector<Target>> getTargetToBuildSequence(Project project) {
		return fProjectToMapOfTargetToBuildSequence.get(project);
	}

	public void setTargetToExecute(Target target) {
		if (target == null) {
			if (!fTargetsToExecute.isEmpty()) {
				fTargetsToExecute.pop();
			}
		} else {
			fTargetsToExecute.push(target);
		}
	}

	public void setTargetExecuting(Target target) {
		if (target == null) {
			if (!fTargetsExecuting.isEmpty()) {
				fTargetsExecuting.pop();
			}
		} else {
			fTargetsExecuting.push(target);
		}
	}

	private Target getTargetToExecute() {
		if (fTargetsToExecute.isEmpty()) {
			return null;
		}
		return fTargetsToExecute.peek();
	}

	private Target getTargetExecuting() {
		if (fTargetsExecuting.isEmpty()) {
			return null;
		}
		return fTargetsExecuting.peek();
	}

	public boolean isStepIntoSuspend() {
		return isAfterTaskEvent() && fStepIntoSuspend;
	}

	public void setStepIntoSuspend(boolean stepIntoSuspend) {
		fStepIntoSuspend = stepIntoSuspend;
	}

	public boolean isClientSuspend() {
		return fClientSuspend;
	}

	public void setClientSuspend(boolean clientSuspend) {
		fClientSuspend = clientSuspend;
	}

	public Task getStepIntoTask() {
		return fStepIntoTask;
	}

	public void setStepIntoTask(Task stepIntoTask) {
		fStepIntoTask = stepIntoTask;
	}

	public void resume() {
		fLogger.notifyAll();
	}

	public Map<String, Object> getProperties() {
		return fProperties;
	}

	public Location getBreakpointLocation() {
		if (isAfterTaskEvent() && getCurrentTask() != null) {
			return getCurrentTask().getLocation();
		}
		if (considerTargetBreakpoints()) {
			Target targetExecuting = getTargetExecuting();
			if (targetExecuting != null) {
				return getLocation(targetExecuting);
			}
		}
		return null;
	}

	private boolean isAfterTaskEvent() {
		return fIsAfterTaskEvent;
	}

	private void setAfterTaskEvent(boolean isAfterTaskEvent) {
		fIsAfterTaskEvent = isAfterTaskEvent;
	}

	public void taskStarted(BuildEvent event) {
		setAfterTaskEvent(true);
		if (getInitialProperties() == null) {// implicit or top level target does not fire targetStarted()
			fInitialProperties = event.getProject().getProperties();
		}

		setCurrentTask(event.getTask());
		setConsiderTargetBreakpoints(false);
		Stack<Task> tasks = getTasks();
		if (!tasks.isEmpty()) {
			// cache the parent task proxy as when that task is started or finished the
			// proxy is not yet available or is nulled out
			Task parentTask = tasks.peek();
			Object proxy = parentTask.getRuntimeConfigurableWrapper().getProxy();
			if (proxy != null) {
				fTaskToProxies.put(parentTask, proxy);
			}
		}
		tasks.push(getCurrentTask());
		waitIfSuspended();
	}

	public void taskFinished() {
		Stack<Task> tasks = getTasks();
		if (!tasks.empty()) {
			Task lastTask = tasks.pop();
			setLastTaskFinished(lastTask);
			setCurrentTask(null);
			String taskName = lastTask.getTaskName();

			if (getStepOverTask() != null) {
				if ((fgAntCallTaskName.equals(taskName) || fgAntTaskName.equals(taskName))
						&& (!fgAntCallTaskName.equals(getStepOverTask().getTaskName()) && !fgAntTaskName.equals(getStepOverTask().getTaskName()))) {
					setShouldSuspend(true);
				} else if (fTaskToProxies.remove(lastTask) instanceof MacroInstance) {
					setShouldSuspend(true);
				}
			}
		}
		waitIfSuspended();
	}

	public void stepOver() {
		setStepOverTask(getCurrentTask());
		if (getCurrentTask() == null) {
			// stepping over target breakpoint
			setShouldSuspend(true);
		}
		resume();
	}

	public void targetStarted(BuildEvent event) {
		setAfterTaskEvent(false);
		Project eventProject = event.getProject();
		if (getInitialProperties() == null) {
			fInitialProperties = eventProject.getProperties();
		}
		if (fProjectToTargetNames.get(eventProject) == null) {
			Object ref = eventProject.getReference(IAntCoreConstants.TARGET_VECTOR_NAME);
			if (ref != null) {
				fProjectToTargetNames.put(eventProject, (Vector<?>) ref);
				@SuppressWarnings("unused")
				HashMap<Target, Vector<Target>> targetToBuildSequence = new HashMap<Target, Vector<Target>>();
				setTargetToExecute(initializeBuildSequenceInformation(event, targetToBuildSequence));
				fProjectToMapOfTargetToBuildSequence.put(eventProject, targetToBuildSequence);
			}
		}

		setTargetExecuting(event.getTarget());
		if (event.getTarget().equals(getTargetToExecute())) {
			// the dependencies of the target to execute have been met
			// prepare for the next target
			Vector<?> targets = fProjectToTargetNames.get(eventProject);
			if (!targets.isEmpty()) {
				setTargetToExecute(eventProject.getTargets().get(targets.remove(0)));
			} else {
				setTargetToExecute(null);
			}
		}
		setConsiderTargetBreakpoints(true);
	}

	public int getLineNumber(Location location) {
		try { // succeeds with Ant newer than 1.6
			return location.getLineNumber();
		}
		catch (NoSuchMethodError e) {
			// Ant before 1.6
			String locationString = location.toString();
			if (locationString.length() == 0) {
				return 0;
			}
			// filename: lineNumber: ("c:\buildfile.xml: 12: ")
			int lastIndex = locationString.lastIndexOf(':');
			int index = locationString.lastIndexOf(':', lastIndex - 1);
			if (index != -1) {
				try {
					return Integer.parseInt(locationString.substring(index + 1, lastIndex));
				}
				catch (NumberFormatException nfe) {
					return 0;
				}
			}
			return 0;
		}
	}

	public static Location getLocation(Target target) {
		try {// succeeds with Ant newer than 1.6.2
			return target.getLocation();
		}
		catch (NoSuchMethodError e) {
			return Location.UNKNOWN_LOCATION;
		}
	}

	public String getFileName(Location location) {
		try {// succeeds with Ant newer than 1.6
			return location.getFileName();
		}
		catch (NoSuchMethodError e) {
			// Ant before 1.6
			String locationString = location.toString();
			if (locationString.length() == 0) {
				return null;
			}
			// filename: lineNumber: ("c:\buildfile.xml: 12: ")
			int lastIndex = locationString.lastIndexOf(':');
			int index = locationString.lastIndexOf(':', lastIndex - 1);
			if (index == -1) {
				index = lastIndex; // only the filename is known
			}
			if (index != -1) {
				// bug 84403
				// if (locationString.startsWith("file:")) {
				// return FileUtils.newFileUtils().fromURI(locationString);
				// }
				// remove file:
				return locationString.substring(5, index);
			}
			return null;
		}
	}

	private void appendToStack(StringBuffer stackRepresentation, String targetName, String taskName, Location location) {
		stackRepresentation.append(targetName);
		stackRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER);
		stackRepresentation.append(taskName);
		stackRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER);

		stackRepresentation.append(getFileName(location));
		stackRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER);
		stackRepresentation.append(getLineNumber(location));
		stackRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER);
	}

	public void marshalStack(StringBuffer stackRepresentation) {
		Stack<Task> tasks = getTasks();

		stackRepresentation.append(DebugMessageIds.STACK);
		stackRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER);

		Target targetToExecute = getTargetToExecute();
		Target targetExecuting = getTargetExecuting();

		Project projectExecuting = null;
		if (targetExecuting != null) {
			projectExecuting = targetExecuting.getProject();
		} else if (!tasks.empty()) { // no target...must be a task
			Task task = tasks.peek();
			projectExecuting = task.getProject();
		}

		if (!isAfterTaskEvent()) {
			appendToStack(stackRepresentation, targetExecuting.getName(), IAntCoreConstants.EMPTY_STRING, getLocation(targetExecuting));
		}
		for (int i = tasks.size() - 1; i >= 0; i--) {
			Task task = tasks.get(i);
			if (task.getProject() == projectExecuting) {
				appendToStack(stackRepresentation, task.getOwningTarget().getName(), task.getTaskName(), task.getLocation());
			} else {
				// sub build target dependencies
				String targetName = task.getOwningTarget().getName();
				if (targetName != null && targetName.length() != 0) { // skip for implicit target
					Iterator<Target> itr = fTargetsToExecute.iterator();
					while (itr.hasNext()) {
						Target target = itr.next();
						if (target.getProject() != projectExecuting) {
							targetToExecute = target;
							continue;
						}
						marshalTargetDependancyStack(stackRepresentation, target, targetExecuting);
					}
				}
				projectExecuting = task.getProject();
				targetExecuting = task.getOwningTarget();
				appendToStack(stackRepresentation, targetExecuting.getName(), task.getTaskName(), task.getLocation());
			}
		}

		// target dependency stack
		marshalTargetDependancyStack(stackRepresentation, targetToExecute, targetExecuting);
	}

	private void marshalTargetDependancyStack(StringBuffer stackRepresentation, Target targetToExecute, Target targetExecuting) {
		if (targetToExecute != null) {
			Vector<Target> buildSequence = getTargetToBuildSequence(targetToExecute.getProject()).get(targetToExecute);
			int startIndex = buildSequence.indexOf(targetExecuting) + 1;
			int dependancyStackDepth = buildSequence.indexOf(targetToExecute);

			Target stackTarget;
			for (int i = startIndex; i <= dependancyStackDepth; i++) {
				stackTarget = buildSequence.get(i);
				if (stackTarget.dependsOn(targetExecuting.getName())) {
					appendToStack(stackRepresentation, stackTarget.getName(), IAntCoreConstants.EMPTY_STRING, getLocation(stackTarget));
				}
			}
		}
	}

	public void marshallProperties(StringBuffer propertiesRepresentation, boolean escapeLineSep) {
		Stack<Task> tasks = getTasks();
		if (tasks.isEmpty()) {
			return;
		}
		propertiesRepresentation.append(DebugMessageIds.PROPERTIES);
		propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER);

		Project project = tasks.peek().getProject();
		Map<String, Object> lastProperties = getProperties();

		Map<String, Object> currentProperties = project.getProperties();
		if (lastProperties != null && currentProperties.size() == lastProperties.size()) {
			// no new properties
			return;
		}

		Map<String, Object> initialProperties = getInitialProperties();
		Map<String, Object> currentUserProperties = project.getUserProperties();
		String originalPropertyName;
		String propertyValue;
		for (String propertyName : currentProperties.keySet()) {
			originalPropertyName = propertyName;
			if (lastProperties == null || lastProperties.get(propertyName) == null) { // new property
				if (escapeLineSep) {
					propertyName = escapeLineSeparator(propertyName);
				}
				propertiesRepresentation.append(propertyName.length());
				propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER);
				propertiesRepresentation.append(propertyName);
				propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER);
				propertyValue = (String) currentProperties.get(originalPropertyName);
				if (escapeLineSep) {
					propertyValue = escapeLineSeparator(propertyValue);
				}
				propertiesRepresentation.append(propertyValue.length());
				propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER);
				propertiesRepresentation.append(propertyValue);
				propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER);
				propertiesRepresentation.append(getPropertyType(initialProperties, currentUserProperties, originalPropertyName));
				propertiesRepresentation.append(DebugMessageIds.MESSAGE_DELIMITER);
			}
		}
		propertiesRepresentation.deleteCharAt(propertiesRepresentation.length() - 1);
		fProperties = currentProperties;
	}

	private int getPropertyType(Map<String, Object> initialProperties, Map<String, Object> currentUserProperties, String propertyName) {
		if (initialProperties.get(propertyName) != null) { // properties set before the start of the build
			if (currentUserProperties.get(propertyName) == null) {
				return DebugMessageIds.PROPERTY_SYSTEM;
			}
			return DebugMessageIds.PROPERTY_USER;
		} else if (currentUserProperties.get(propertyName) == null) {
			return DebugMessageIds.PROPERTY_RUNTIME;
		} else {
			return DebugMessageIds.PROPERTY_USER;
		}
	}

	private String escapeLineSeparator(String stringToEscape) {
		if (!(stringToEscape.indexOf('\r') != -1 || stringToEscape.indexOf('\n') != -1 || stringToEscape.indexOf("\\r") != -1 //$NON-NLS-1$
				|| stringToEscape.indexOf("\\n") != -1)) { //$NON-NLS-1$
			return stringToEscape;
		}
		StringBuffer escapedValue = new StringBuffer(stringToEscape);
		for (int i = 0; i < escapedValue.length(); i++) {
			switch (escapedValue.charAt(i)) {
				case '\r':
					escapedValue.replace(i, i + 1, "\\r"); //$NON-NLS-1$
					i++;
					break;
				case '\n':
					escapedValue.replace(i, i + 1, "\\n"); //$NON-NLS-1$
					i++;
					break;
				case '\\':
					if (escapedValue.charAt(i + 1) == 'r' || escapedValue.charAt(i + 1) == 'n') {
						escapedValue.replace(i, i + 1, "\\\\"); //$NON-NLS-1$
						i++;
					}
					break;
				default:
					break;
			}
		}

		return escapedValue.toString();
	}

	private Target initializeBuildSequenceInformation(BuildEvent event, Map<Target, Vector<Target>> targetToBuildSequence) {
		Project antProject = event.getProject();
		Vector<String> targets = antProject.getReference(IAntCoreConstants.TARGET_VECTOR_NAME);
		if (targets == null || targets.size() < 1) {
			return null;
		}
		Hashtable<String, Target> allTargets = antProject.getTargets();
		Vector<Target> sortedTargets;
		for (String targetName : targets) {
			sortedTargets = antProject.topoSort(targetName, allTargets);
			targetToBuildSequence.put(allTargets.get(targetName), sortedTargets);
		}
		// the target to execute
		return allTargets.get(targets.remove(0));
	}
}
