/*******************************************************************************
 * Copyright (c) 2004, 2013 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.runtime.logger;

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

import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.Location;
import org.eclipse.ant.internal.launching.debug.AntDebugState;
import org.eclipse.ant.internal.launching.debug.IAntDebugController;
import org.eclipse.ant.internal.launching.debug.IDebugBuildLogger;
import org.eclipse.ant.internal.launching.debug.model.AntDebugTarget;
import org.eclipse.ant.internal.launching.debug.model.AntThread;
import org.eclipse.ant.internal.launching.launchConfigurations.AntProcess;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.ILineBreakpoint;
import org.eclipse.debug.core.model.IProcess;

public class AntProcessDebugBuildLogger extends AntProcessBuildLogger implements IAntDebugController, IDebugBuildLogger {

	private AntDebugState fDebugState = null;

	private List<IBreakpoint> fBreakpoints = null;

	private AntDebugTarget fAntDebugTarget;
	private boolean fResumed = false;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.BuildListener#buildStarted(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public void buildStarted(BuildEvent event) {
		fDebugState = new AntDebugState(this);
		super.buildStarted(event);
		IProcess process = getAntProcess(fProcessId);
		ILaunch launch = process.getLaunch();
		fAntDebugTarget = new AntDebugTarget(launch, process, this);
		launch.addDebugTarget(fAntDebugTarget);

		fAntDebugTarget.buildStarted();
		fDebugState.buildStarted();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.launching.runtime.logger.AntProcessBuildLogger#buildFinished(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public void buildFinished(BuildEvent event) {
		super.buildFinished(event);
		cleanup();
	}

	/**
	 * Cleans up all held memory. <br>
	 * <br>
	 * Called from {@link #buildFinished(BuildEvent)} and {@link #terminate()}
	 * 
	 * @since 1.0.1
	 */
	void cleanup() {
		if (fAntDebugTarget != null) {
			IProcess process = getAntProcess(fProcessId);
			if (process != null) {
				ILaunch launch = process.getLaunch();
				launch.removeDebugTarget(fAntDebugTarget);
			}
		}
		if (fDebugState != null) {
			fDebugState.buildFinished();
		}
		if (fBreakpoints != null) {
			fBreakpoints.clear();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.BuildListener#taskFinished(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public void taskFinished(BuildEvent event) {
		super.taskFinished(event);
		fDebugState.taskFinished();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.BuildListener#taskStarted(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public void taskStarted(BuildEvent event) {
		super.taskStarted(event);
		fDebugState.taskStarted(event);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.antsupport.logger.util.IDebugBuildLogger#waitIfSuspended()
	 */
	@Override
	public synchronized void waitIfSuspended() {
		fResumed = false;
		IBreakpoint breakpoint = breakpointAtLineNumber(fDebugState.getBreakpointLocation());
		if (breakpoint != null) {
			fAntDebugTarget.breakpointHit(breakpoint);
			try {
				while (!fResumed) {
					wait(500);
					checkCancelled();
				}
			}
			catch (InterruptedException e) {
				// do nothing
			}
		} else if (fDebugState.getCurrentTask() != null) {
			int detail = -1;
			boolean shouldSuspend = true;
			if (fDebugState.isStepIntoSuspend()) {
				detail = DebugEvent.STEP_END;
				fDebugState.setStepIntoSuspend(false);
			} else if ((fDebugState.getLastTaskFinished() != null && fDebugState.getLastTaskFinished() == fDebugState.getStepOverTask())
					|| fDebugState.shouldSuspend()) {
				detail = DebugEvent.STEP_END;
				fDebugState.setShouldSuspend(false);
				fDebugState.setStepOverTask(null);
			} else if (fDebugState.isClientSuspend()) {
				detail = DebugEvent.CLIENT_REQUEST;
				fDebugState.setClientSuspend(false);
			} else {
				shouldSuspend = false;
			}
			if (shouldSuspend) {
				fAntDebugTarget.suspended(detail);
				try {
					while (!fResumed) {
						wait(500);
						checkCancelled();
					}
				}
				catch (InterruptedException e) {
					// do nothing
				}
			}
		}
	}

	private void checkCancelled() {
		AntProcess process = getAntProcess(fProcessId);
		if (process != null && process.isCanceled()) {
			throw new OperationCanceledException(RuntimeMessages.AntProcessDebugBuildLogger_1);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#resume()
	 */
	@Override
	public synchronized void resume() {
		fResumed = true;
		notifyAll();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#suspend()
	 */
	@Override
	public synchronized void suspend() {
		fDebugState.setClientSuspend(true);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#stepInto()
	 */
	@Override
	public synchronized void stepInto() {
		fDebugState.setStepIntoSuspend(true);
		fResumed = true;
		notifyAll();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.launching.debug.IAntDebugController#terminate()
	 */
	@Override
	public void terminate() {
		cleanup();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#stepOver()
	 */
	@Override
	public synchronized void stepOver() {
		fResumed = true;
		fDebugState.stepOver();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#handleBreakpoint(org.eclipse.debug.core.model.IBreakpoint, boolean)
	 */
	@Override
	public void handleBreakpoint(IBreakpoint breakpoint, boolean added) {
		if (added) {
			if (fBreakpoints == null) {
				fBreakpoints = new ArrayList<IBreakpoint>();
			}
			if (!fBreakpoints.contains(breakpoint)) {
				fBreakpoints.add(breakpoint);
			}
		} else {
			if (fBreakpoints != null) {
				fBreakpoints.remove(breakpoint);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#getProperties()
	 */
	@Override
	public void getProperties() {
		if (fAntDebugTarget == null || !fAntDebugTarget.isSuspended()) {
			return;
		}
		StringBuffer propertiesRepresentation = new StringBuffer();
		fDebugState.marshallProperties(propertiesRepresentation, false);
		if (fAntDebugTarget.getThreads().length > 0) {
			((AntThread) fAntDebugTarget.getThreads()[0]).newProperties(propertiesRepresentation.toString());
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#getStackFrames()
	 */
	@Override
	public void getStackFrames() {
		StringBuffer stackRepresentation = new StringBuffer();
		fDebugState.marshalStack(stackRepresentation);
		((AntThread) fAntDebugTarget.getThreads()[0]).buildStack(stackRepresentation.toString());
	}

	private IBreakpoint breakpointAtLineNumber(Location location) {
		if (fBreakpoints == null || location == null || location == Location.UNKNOWN_LOCATION) {
			return null;
		}
		int lineNumber = fDebugState.getLineNumber(location);
		File locationFile = new File(fDebugState.getFileName(location));
		for (int i = 0; i < fBreakpoints.size(); i++) {
			ILineBreakpoint breakpoint = (ILineBreakpoint) fBreakpoints.get(i);
			int breakpointLineNumber;
			try {
				if (!breakpoint.isEnabled()) {
					continue;
				}
				breakpointLineNumber = breakpoint.getLineNumber();
			}
			catch (CoreException e) {
				return null;
			}
			IFile resource = (IFile) breakpoint.getMarker().getResource();
			if (breakpointLineNumber == lineNumber && resource.getLocation().toFile().equals(locationFile)) {
				return breakpoint;
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.BuildListener#targetStarted(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public void targetStarted(BuildEvent event) {
		fDebugState.targetStarted(event);
		waitIfSuspended();
		super.targetStarted(event);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.BuildListener#targetFinished(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public void targetFinished(BuildEvent event) {
		super.targetFinished(event);
		if (fDebugState != null) {
			fDebugState.setTargetExecuting(null);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#unescapeString(java.lang.StringBuffer)
	 */
	@Override
	public StringBuffer unescapeString(StringBuffer propertyValue) {
		return propertyValue;
	}
}
