/*******************************************************************************
 * 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.contains(DebugMessageIds.BREAKPOINT)) {
			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;
		}
		StringBuilder message = new StringBuilder();
		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;
	}
}
