/*******************************************************************************
 * Copyright (c) 2003, 2013 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.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import org.eclipse.ant.internal.launching.AntLaunching;
import org.eclipse.ant.internal.launching.debug.IAntDebugController;
import org.eclipse.ant.internal.launching.launchConfigurations.RemoteAntBuildListener;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
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 RemoteAntDebugBuildListener extends RemoteAntBuildListener implements IAntDebugController {

	// sockets to communicate with the remote Ant debug build logger
	private Socket fRequestSocket;
	private PrintWriter fRequestWriter;
	private BufferedReader fResponseReader;

	private int fRequestPort = -1;
	private Thread fReaderThread;

	private AntDebugTarget fTarget;

	/**
	 * Reader thread that processes request responses from the remote Ant debug build logger
	 */
	private class ReaderThread extends Thread {
		public ReaderThread() {
			super("Ant Request Response Reader Thread"); //$NON-NLS-1$
			setDaemon(true);
		}

		@Override
		public void run() {
			try {
				String message = null;
				while (fResponseReader != null) {
					synchronized (RemoteAntDebugBuildListener.this) {
						if (fResponseReader != null && (message = fResponseReader.readLine()) != null) {
							receiveMessage(message);
						}
					}
				}
			}
			catch (IOException ie) { // the other end has shutdown
				RemoteAntDebugBuildListener.this.shutDown();
			}
			catch (Exception e) {
				AntLaunching.log("Internal error processing remote response", e); //$NON-NLS-1$
				RemoteAntDebugBuildListener.this.shutDown();
			}
		}
	}

	/**
	 * Constructor
	 * 
	 * @param launch
	 *            the backing launch to listen to
	 * @param encoding
	 *            the encoding to use for communications
	 */
	public RemoteAntDebugBuildListener(ILaunch launch, String encoding) {
		super(launch, encoding);
		// fDebug= true;
	}

	@Override
	protected void receiveMessage(String message) {
		if (message.startsWith(DebugMessageIds.BUILD_STARTED)) {
			buildStarted();
		} else if (message.startsWith(DebugMessageIds.SUSPENDED)) {
			handleSuspendMessage(message);
		} else if (message.startsWith(DebugMessageIds.TERMINATED)) {
			try {
				fTarget.terminate();
			}
			catch (DebugException e) {
				// do nothing
			}
		} else if (message.startsWith(DebugMessageIds.STACK)) {
			AntThread thread = (AntThread) fTarget.getThreads()[0];
			thread.buildStack(message);
		} else if (message.startsWith(DebugMessageIds.PROPERTIES)) {
			AntThread thread = (AntThread) fTarget.getThreads()[0];
			thread.newProperties(message);
		} else {
			super.receiveMessage(message);
		}
	}

	private void handleSuspendMessage(String message) {
		if (message.endsWith(DebugMessageIds.CLIENT_REQUEST)) {
			fTarget.suspended(DebugEvent.CLIENT_REQUEST);
		} else if (message.endsWith(DebugMessageIds.STEP)) {
			fTarget.suspended(DebugEvent.STEP_END);
		} else if (message.indexOf(DebugMessageIds.BREAKPOINT) >= 0) {
			fTarget.breakpointHit(message);
		}
	}

	private void buildStarted() {
		IProcess process = getProcess();
		while (process == null) {
			try {
				synchronized (this) {
					wait(400);
				}
				process = getProcess();
			}
			catch (InterruptedException ie) {
				// do nothing
			}
		}
		fTarget = new AntDebugTarget(fLaunch, process, this);
		fLaunch.addDebugTarget(fTarget);

		if (!connectRequest()) {
			RemoteAntDebugBuildListener.this.shutDown();
			return;
		}

		fTarget.buildStarted();
	}

	private boolean connectRequest() {
		Exception exception = null;
		for (int i = 1; i < 20; i++) {
			try {
				fRequestSocket = new Socket("localhost", fRequestPort); //$NON-NLS-1$
				fRequestWriter = new PrintWriter(fRequestSocket.getOutputStream(), true);
				fResponseReader = new BufferedReader(new InputStreamReader(fRequestSocket.getInputStream(), getEncoding()));

				fReaderThread = new ReaderThread();
				fReaderThread.start();
				return true;
			}
			catch (UnknownHostException e) {
				exception = e;
				break;
			}
			catch (IOException e) {
				exception = e;
			}
			try {
				Thread.sleep(500);
			}
			catch (InterruptedException e) {
				// do nothing
			}
		}
		AntLaunching.log("Internal error attempting to connect to debug target", exception); //$NON-NLS-1$
		return false;
	}

	/**
	 * Start listening to an Ant build. Start a server connection that the RemoteAntDebugBuildLogger can connect to.
	 * 
	 * @param eventPort
	 *            The port number to create the server connection on
	 * @param requestPort
	 *            The port number to use for sending requests to the remote logger
	 */
	public synchronized void startListening(int eventPort, int requestPort) {
		super.startListening(eventPort);
		fRequestPort = requestPort;
	}

	/**
	 * Sends a request to the Ant build
	 * 
	 * @param request
	 *            debug command
	 */
	protected void sendRequest(String request) {
		if (fRequestWriter == null) {
			return;
		}
		synchronized (fRequestWriter) {
			fRequestWriter.println(request);
		}
	}

	@Override
	protected synchronized void shutDown() {
		if (fTarget != null) {
			try {
				fTarget.terminate();
				fTarget = null;
			}
			catch (DebugException e) {
				// do nothing
			}
		}
		fLaunch = null;
		if (DebugPlugin.getDefault() != null) {
			DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
		}
		try {
			if (fReaderThread != null) {
				// interrupt reader thread so that we don't block on close
				// on a lock held by the BufferedReader
				// see bug: 38955
				fReaderThread.interrupt();
			}
			if (fResponseReader != null) {
				fResponseReader.close();
				fResponseReader = null;
			}
		}
		catch (IOException e) {
			// do nothing
		}
		if (fRequestWriter != null) {
			fRequestWriter.close();
			fRequestWriter = null;
		}
		try {
			if (fRequestSocket != null) {
				fRequestSocket.close();
				fRequestSocket = null;
			}
		}
		catch (IOException e) {
			// do nothing
		}
		super.shutDown();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#resume()
	 */
	@Override
	public void resume() {
		sendRequest(DebugMessageIds.RESUME);
	}

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

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#suspend()
	 */
	@Override
	public void suspend() {
		sendRequest(DebugMessageIds.SUSPEND);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#stepInto()
	 */
	@Override
	public void stepInto() {
		sendRequest(DebugMessageIds.STEP_INTO);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#stepOver()
	 */
	@Override
	public void stepOver() {
		sendRequest(DebugMessageIds.STEP_OVER);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#handleBreakpoint(IBreakpoint, boolean)
	 */
	@Override
	public void handleBreakpoint(IBreakpoint breakpoint, boolean add) {
		if (fTarget == null || !fTarget.supportsBreakpoint(breakpoint)) {
			return;
		}
		StringBuffer message = new StringBuffer();
		if (add) {
			try {
				if (!breakpoint.isEnabled()) {
					return;
				}
			}
			catch (CoreException e) {
				AntLaunching.log(e);
				return;
			}
			message.append(DebugMessageIds.ADD_BREAKPOINT);
		} else {
			message.append(DebugMessageIds.REMOVE_BREAKPOINT);
		}
		message.append(DebugMessageIds.MESSAGE_DELIMITER);
		message.append(breakpoint.getMarker().getResource().getLocation().toOSString());
		message.append(DebugMessageIds.MESSAGE_DELIMITER);
		try {
			message.append(((ILineBreakpoint) breakpoint).getLineNumber());
			sendRequest(message.toString());
		}
		catch (CoreException ce) {
			AntLaunching.log(ce);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#getProperties()
	 */
	@Override
	public void getProperties() {
		sendRequest(DebugMessageIds.PROPERTIES);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#getStackFrames()
	 */
	@Override
	public void getStackFrames() {
		sendRequest(DebugMessageIds.STACK);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#unescapeString(java.lang.StringBuffer)
	 */
	@Override
	public StringBuffer unescapeString(StringBuffer property) {
		if (property.indexOf("\\r") == -1 && property.indexOf("\\n") == -1) { //$NON-NLS-1$ //$NON-NLS-2$
			return property;
		}
		for (int i = 0; i < property.length(); i++) {
			if ('\\' == property.charAt(i)) {
				String newString = ""; //$NON-NLS-1$
				if ('r' == property.charAt(i + 1)) {
					if (i - 1 > -1 && '\\' == property.charAt(i - 1)) {
						newString = "r"; //$NON-NLS-1$
					} else {
						newString += '\r';
					}
				} else if ('n' == property.charAt(i + 1)) {
					if (i - 1 > -1 && '\\' == property.charAt(i - 1)) {
						newString = "n"; //$NON-NLS-1$
					} else {
						newString += '\n';
					}

				}
				if (newString.length() > 0) {
					property.replace(i, i + 2, newString);
				}
			}
		}

		return property;
	}
}
