/*******************************************************************************
 * 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.contains("\\r") //$NON-NLS-1$

				|| stringToEscape.contains("\\n"))) { //$NON-NLS-1$
			return stringToEscape;
		}
		StringBuilder escapedValue = new StringBuilder(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));
	}
}
