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