/*******************************************************************************
 * Copyright (c) 2005, 2015 IBM Corporation and others.
 *
 * 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
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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));
	}
}
