/*******************************************************************************
 * Copyright (c) 2004, 2016 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.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<>();
			}
			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;
	}
}
