/*******************************************************************************
 * 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.debug.model;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.ant.internal.launching.debug.IAntDebugConstants;
import org.eclipse.ant.internal.launching.debug.IAntDebugController;

import org.eclipse.core.externaltools.internal.IExternalToolConstants;
import org.eclipse.core.variables.VariablesPlugin;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.core.resources.IMarkerDelta;

import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.IBreakpointManagerListener;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.ILineBreakpoint;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IThread;

/**
 * Ant Debug Target
 */
public class AntDebugTarget extends AntDebugElement implements IDebugTarget, IDebugEventSetListener, IBreakpointManagerListener {

	// associated system process (Ant Build)
	private IProcess fProcess;

	// containing launch object
	private ILaunch fLaunch;

	// Build file name
	private String fName;

	// suspend state
	private boolean fSuspended = false;

	// terminated state
	private boolean fTerminated = false;

	// threads
	private AntThread fThread;
	private IThread[] fThreads;

	private IAntDebugController fController;

	private List<IBreakpoint> fRunToLineBreakpoints;

	/**
	 * Constructs a new debug target in the given launch for the associated Ant build process.
	 * 
	 * @param launch
	 *            containing launch
	 * @param process
	 *            Ant build process
	 * @param controller
	 *            the controller to communicate to the Ant build
	 */
	public AntDebugTarget(ILaunch launch, IProcess process, IAntDebugController controller) {
		super(null);
		fLaunch = launch;
		fProcess = process;

		fController = controller;

		fThread = new AntThread(this);
		fThreads = new IThread[] { fThread };

		DebugPlugin.getDefault().getBreakpointManager().addBreakpointManagerListener(this);
		DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this);
		DebugPlugin.getDefault().addDebugEventListener(this);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IDebugTarget#getProcess()
	 */
	@Override
	public IProcess getProcess() {
		return fProcess;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IDebugTarget#getThreads()
	 */
	@Override
	public IThread[] getThreads() {
		return fThreads;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IDebugTarget#hasThreads()
	 */
	@Override
	public boolean hasThreads() throws DebugException {
		return !fTerminated && fThreads.length > 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IDebugTarget#getName()
	 */
	@Override
	public String getName() throws DebugException {
		if (fName == null) {
			try {
				fName = getLaunch().getLaunchConfiguration().getAttribute(IExternalToolConstants.ATTR_LOCATION, DebugModelMessages.AntDebugTarget_0);
				fName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(fName);
			}
			catch (CoreException e) {
				fName = DebugModelMessages.AntDebugTarget_0;
			}
		}
		return fName;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IDebugTarget#supportsBreakpoint(org.eclipse.debug.core.model.IBreakpoint)
	 */
	@Override
	public boolean supportsBreakpoint(IBreakpoint breakpoint) {
		if (breakpoint.getModelIdentifier().equals(IAntDebugConstants.ID_ANT_DEBUG_MODEL)) {
			// need to consider all breakpoints as no way to tell which set
			// of build files will be executed (ant task)
			return true;
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget()
	 */
	@Override
	public IDebugTarget getDebugTarget() {
		return this;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IDebugElement#getLaunch()
	 */
	@Override
	public ILaunch getLaunch() {
		return fLaunch;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
	 */
	@Override
	public boolean canTerminate() {
		return !fTerminated;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
	 */
	@Override
	public boolean isTerminated() {
		return fTerminated;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ITerminate#terminate()
	 */
	@Override
	public void terminate() throws DebugException {
		terminated();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ISuspendResume#canResume()
	 */
	@Override
	public boolean canResume() {
		return !fTerminated && fSuspended;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
	 */
	@Override
	public boolean canSuspend() {
		return !fTerminated && !fSuspended;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
	 */
	@Override
	public boolean isSuspended() {
		return fSuspended;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ISuspendResume#resume()
	 */
	@Override
	public void resume() throws DebugException {
		fSuspended = false;
		fController.resume();
		if (fThread.isSuspended()) {
			fThread.resumedByTarget();
		}
		fireResumeEvent(DebugEvent.CLIENT_REQUEST);
	}

	/**
	 * Notification the target has suspended for the given reason
	 * 
	 * @param detail
	 *            reason for the suspend
	 */
	public void suspended(int detail) {
		fSuspended = true;
		fThread.setStepping(false);
		fThread.fireSuspendEvent(detail);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
	 */
	@Override
	public void suspend() throws DebugException {
		fController.suspend();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint)
	 */
	@Override
	public void breakpointAdded(IBreakpoint breakpoint) {
		if (!fTerminated) {
			fController.handleBreakpoint(breakpoint, true);
			if (breakpoint instanceof AntLineBreakpoint) {
				if (((AntLineBreakpoint) breakpoint).isRunToLine()) {
					if (fRunToLineBreakpoints == null) {
						fRunToLineBreakpoints = new ArrayList<>();
					}
					fRunToLineBreakpoints.add(breakpoint);
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint,
	 * org.eclipse.core.resources.IMarkerDelta)
	 */
	@Override
	public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
		if (!fTerminated) {
			fController.handleBreakpoint(breakpoint, false);
			if (fRunToLineBreakpoints != null) {
				if (fRunToLineBreakpoints.remove(breakpoint) && fRunToLineBreakpoints.isEmpty()) {
					fRunToLineBreakpoints = null;
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint,
	 * org.eclipse.core.resources.IMarkerDelta)
	 */
	@Override
	public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
		if (supportsBreakpoint(breakpoint)) {
			try {
				if (breakpoint.isEnabled() && DebugPlugin.getDefault().getBreakpointManager().isEnabled()) {
					breakpointAdded(breakpoint);
				} else {
					breakpointRemoved(breakpoint, null);
				}
			}
			catch (CoreException e) {
				// do nothing
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IDisconnect#canDisconnect()
	 */
	@Override
	public boolean canDisconnect() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IDisconnect#disconnect()
	 */
	@Override
	public void disconnect() throws DebugException {
		// do nothing
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IDisconnect#isDisconnected()
	 */
	@Override
	public boolean isDisconnected() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval()
	 */
	@Override
	public boolean supportsStorageRetrieval() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long)
	 */
	@Override
	public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException {
		return null;
	}

	/**
	 * Notification we have connected to the Ant build logger and it has started. Resume the build.
	 */
	public void buildStarted() {
		fireCreationEvent();
		installDeferredBreakpoints();
		try {
			resume();
		}
		catch (DebugException e) {
			// do nothing
		}
	}

	/**
	 * Install breakpoints that are already registered with the breakpoint manager if the breakpoint manager is enabled and the breakpoint is enabled.
	 */
	private void installDeferredBreakpoints() {
		IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager();
		if (!manager.isEnabled()) {
			return;
		}
		IBreakpoint[] breakpoints = manager.getBreakpoints(IAntDebugConstants.ID_ANT_DEBUG_MODEL);
		for (int i = 0; i < breakpoints.length; i++) {
			IBreakpoint breakpoint = breakpoints[i];
			try {
				if (breakpoint.isEnabled()) {
					breakpointAdded(breakpoints[i]);
				}
			}
			catch (CoreException e) {
				// do nothing
			}
		}
	}

	/**
	 * Called when this debug target terminates.
	 */
	public synchronized void terminated() {
		if (!fTerminated) {
			fThreads = new IThread[0];
			fTerminated = true;
			fSuspended = false;
			fController.terminate();
			if (DebugPlugin.getDefault() != null) {
				DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener(this);
				DebugPlugin.getDefault().removeDebugEventListener(this);
				DebugPlugin.getDefault().getBreakpointManager().removeBreakpointManagerListener(this);
			}
			if (!getProcess().isTerminated()) {
				try {
					fProcess.terminate();
				}
				catch (DebugException e) {
					// do nothing
				}
			}
			if (DebugPlugin.getDefault() != null) {
				fireTerminateEvent();
			}
		}
	}

	/**
	 * Single step the Ant build.
	 */
	public void stepOver() {
		fSuspended = false;
		fController.stepOver();
		fireResumeEvent(DebugEvent.CLIENT_REQUEST);
	}

	/**
	 * Step-into the Ant build.
	 */
	public void stepInto() {
		fSuspended = false;
		fController.stepInto();
		fireResumeEvent(DebugEvent.CLIENT_REQUEST);
	}

	/**
	 * Notification a breakpoint was encountered. Determine which breakpoint was hit and fire a suspend event.
	 * 
	 * @param event
	 *            debug event
	 */
	public void breakpointHit(String event) {
		// determine which breakpoint was hit, and set the thread's breakpoint
		String[] datum = event.split(DebugMessageIds.MESSAGE_DELIMITER);
		String fileName = datum[1];
		int lineNumber = Integer.parseInt(datum[2]);
		IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(IAntDebugConstants.ID_ANT_DEBUG_MODEL);
		boolean found = false;
		for (int i = 0; i < breakpoints.length; i++) {
			ILineBreakpoint lineBreakpoint = (ILineBreakpoint) breakpoints[i];
			if (setThreadBreakpoint(lineBreakpoint, lineNumber, fileName)) {
				found = true;
				break;
			}
		}
		if (!found && fRunToLineBreakpoints != null) {
			Iterator<IBreakpoint> iter = fRunToLineBreakpoints.iterator();
			while (iter.hasNext()) {
				ILineBreakpoint lineBreakpoint = (ILineBreakpoint) iter.next();
				if (setThreadBreakpoint(lineBreakpoint, lineNumber, fileName)) {
					break;
				}
			}
		}
		suspended(DebugEvent.BREAKPOINT);
	}

	private boolean setThreadBreakpoint(ILineBreakpoint lineBreakpoint, int lineNumber, String fileName) {
		try {
			if (lineBreakpoint.getLineNumber() == lineNumber && fileName.equals(lineBreakpoint.getMarker().getResource().getLocation().toOSString())) {
				fThread.setBreakpoints(new IBreakpoint[] { lineBreakpoint });
				return true;
			}
		}
		catch (CoreException e) {
			// do nothing
		}
		return false;
	}

	public void breakpointHit(IBreakpoint breakpoint) {
		fThread.setBreakpoints(new IBreakpoint[] { breakpoint });
		suspended(DebugEvent.BREAKPOINT);
	}

	public void getStackFrames() {
		if (isSuspended()) {
			fController.getStackFrames();
		}
	}

	public void getProperties() {
		if (!fTerminated) {
			fController.getProperties();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
	 */
	@Override
	public void handleDebugEvents(DebugEvent[] events) {
		for (int i = 0; i < events.length; i++) {
			DebugEvent event = events[i];
			if (event.getKind() == DebugEvent.TERMINATE && event.getSource().equals(fProcess)) {
				terminated();
			}
		}
	}

	/**
	 * When the breakpoint manager disables, remove all registered breakpoints requests from the VM. When it enables, reinstall them.
	 * 
	 * @see org.eclipse.debug.core.IBreakpointManagerListener#breakpointManagerEnablementChanged(boolean)
	 */
	@Override
	public void breakpointManagerEnablementChanged(boolean enabled) {
		IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(IAntDebugConstants.ID_ANT_DEBUG_MODEL);
		for (int i = 0; i < breakpoints.length; i++) {
			IBreakpoint breakpoint = breakpoints[i];
			if (enabled) {
				breakpointAdded(breakpoint);
			} else {
				breakpointRemoved(breakpoint, null);
			}
		}
	}

	public IAntDebugController getAntDebugController() {
		return fController;
	}
}
