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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.tools.ant.Project;
import org.eclipse.ant.internal.core.AbstractEclipseBuildLogger;
import org.eclipse.ant.internal.launching.AntLaunch;
import org.eclipse.ant.internal.launching.AntLaunching;
import org.eclipse.ant.internal.launching.AntLaunchingUtil;
import org.eclipse.ant.internal.launching.IAntLaunchingPreferenceConstants;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchesListener;
import org.eclipse.debug.core.model.IProcess;

/**
 * Parts adapted from org.eclipse.jdt.internal.junit.ui.RemoteTestRunnerClient The client side of the RemoteAntBuildLogger. Handles the marshaling of
 * the different messages.
 */
public class RemoteAntBuildListener implements ILaunchesListener {
	public abstract static class ListenerSafeRunnable implements ISafeRunnable {
		@Override
		public void handleException(Throwable exception) {
			AntLaunching.log(exception);
		}
	}

	/**
	 * The server socket
	 */
	private ServerSocket fServerSocket;
	private Socket fSocket;
	private BufferedReader fBufferedReader;
	private IProcess fProcess;
	private String fProcessId;
	private List<String> fMessageQueue;
	protected ILaunch fLaunch;
	private String fLastFileName = null;
	private String fLastTaskName = null;
	private boolean fBuildFailed = false;
	/**
	 * The encoding to use
	 *
	 * @since 3.7
	 */
	private String fEncoding;

	/**
	 * Reads the message stream from the RemoteAntBuildLogger
	 */
	private class ServerConnection extends Thread {
		private int fServerPort;

		public ServerConnection(int port) {
			super("Ant Build Server Connection"); //$NON-NLS-1$
			setDaemon(true);
			fServerPort = port;
		}

		@Override
		public void run() {
			try {
				fServerSocket = new ServerSocket(fServerPort);
				int socketTimeout = Platform.getPreferencesService().getInt(AntLaunching.getUniqueIdentifier(), IAntLaunchingPreferenceConstants.ANT_COMMUNICATION_TIMEOUT, 20000, null);
				fServerSocket.setSoTimeout(socketTimeout);
				fSocket = fServerSocket.accept();
				fBufferedReader = new BufferedReader(new InputStreamReader(fSocket.getInputStream(), fEncoding));
				// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=414516
				// the launch can be terminated but we haven't been notified yet
				String message;
				while (fLaunch != null && !fLaunch.isTerminated() && fBufferedReader != null && (message = fBufferedReader.readLine()) != null) {
					receiveMessage(message);
				}
			}
			catch (SocketException e) {
				AntLaunching.log(e);
			}
			catch (SocketTimeoutException e) {
				AntLaunching.log(e);
			}
			catch (IOException e) {
				AntLaunching.log(e);
			}
			shutDown();
		}
	}

	/**
	 * Constructor
	 *
	 * @param launch
	 *            the backing launch to listen to
	 * @param encoding
	 *            the encoding to use for communications
	 */
	public RemoteAntBuildListener(ILaunch launch, String encoding) {
		super();
		fLaunch = launch;
		fEncoding = encoding;
		DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
	}

	/**
	 * Returns the encoding set on the listener
	 *
	 * @return the encoding set on the listener
	 * @since 3.7
	 */
	protected String getEncoding() {
		return fEncoding;
	}

	/**
	 * Start listening to an Ant build. Start a server connection that the RemoteAntBuildLogger can connect to.
	 *
	 * @param eventPort
	 *            The port number to create the server connection on
	 */
	public synchronized void startListening(int eventPort) {
		ServerConnection connection = new ServerConnection(eventPort);
		connection.start();
	}

	protected synchronized void shutDown() {
		fLaunch = null;
		if (DebugPlugin.getDefault() != null) {
			DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
		}
		try {
			if (fBufferedReader != null) {
				fBufferedReader.close();
				fBufferedReader = null;
			}
		}
		catch (IOException e) {
			AntLaunching.log(e);
		}
		try {
			if (fSocket != null) {
				fSocket.close();
				fSocket = null;
			}
		}
		catch (IOException e) {
			AntLaunching.log(e);
		}
		try {
			if (fServerSocket != null) {
				fServerSocket.close();
				fServerSocket = null;
			}
		}
		catch (IOException e) {
			AntLaunching.log(e);
		}
	}

	protected void receiveMessage(String message) {
		if (message.startsWith(MessageIds.TASK)) {
			receiveTaskMessage(message);
		} else if (message.startsWith(MessageIds.TARGET)) {
			receiveTargetMessage(message);
		} else if (message.startsWith(MessageIds.PROCESS_ID)) {
			fProcessId = message.substring(MessageIds.PROCESS_ID.length());
		} else {
			int index = message.indexOf(',');
			if (index > 0) {
				int priority = Integer.parseInt(message.substring(0, index));
				String msg = message.substring(index + 1);
				writeMessage(msg + System.getProperty("line.separator"), priority); //$NON-NLS-1$
				if (msg.startsWith("BUILD FAILED")) { //$NON-NLS-1$
					fBuildFailed = true;
				} else if (fBuildFailed) {
					if (msg.startsWith("Total time:")) { //$NON-NLS-1$
						fBuildFailed = false;
					} else {
						AntLaunchingUtil.linkBuildFailedMessage(msg, getProcess());
					}
				}

			}
		}
	}

	private void receiveTargetMessage(String message) {
		String msg = message.substring(MessageIds.TARGET.length());
		StringTokenizer tokenizer = new StringTokenizer(msg, ","); //$NON-NLS-1$
		msg = tokenizer.nextToken();
		if (tokenizer.hasMoreTokens()) {
			int locationLength = Integer.parseInt(tokenizer.nextToken());
			String location = tokenizer.nextToken();
			while (location.length() < locationLength) { // path with a comma in
				// it
				location += ","; //$NON-NLS-1$
				location += tokenizer.nextToken();
			}
			int lineNumber = Integer.parseInt(tokenizer.nextToken());
			generateLink(msg, location, lineNumber, 0, msg.length() - 1);
		}
		writeMessage(msg + System.getProperty("line.separator"), Project.MSG_INFO); //$NON-NLS-1$
	}

	private void receiveTaskMessage(String message) {
		String msg = message.substring(MessageIds.TASK.length());
		int index = msg.indexOf(',');
		int priority = Integer.parseInt(msg.substring(0, index));
		int index2 = msg.indexOf(',', index + 1);
		String taskName = msg.substring(index + 1, index2);
		if (taskName.length() == 0) {
			taskName = fLastTaskName;
		}
		int index3 = msg.indexOf(',', index2 + 1);
		int lineLength = Integer.parseInt(msg.substring(index2 + 1, index3));
		int index4 = index3 + 1 + lineLength;
		String line = msg.substring(index3 + 1, index4);
		StringBuilder labelBuff = new StringBuilder();
		labelBuff.append('[');
		labelBuff.append(taskName);
		labelBuff.append("] "); //$NON-NLS-1$
		labelBuff.append(line);
		line = labelBuff.toString();

		fLastTaskName = taskName;
		int locationIndex = msg.indexOf(',', index4 + 1);
		int finalIndex = locationIndex + 1;
		String fileName = msg.substring(index4 + 1, locationIndex);
		int locationLength = 0;
		if (fileName.length() == 0) {
			fileName = fLastFileName;
		} else {
			finalIndex = msg.indexOf(',', locationIndex) + 1;
			locationLength = Integer.parseInt(fileName);
			fileName = msg.substring(finalIndex, finalIndex + locationLength);
			locationLength += 1; // set past delimiter
		}
		fLastFileName = fileName;
		int lineNumber = Integer.parseInt(msg.substring(finalIndex + locationLength));
		int size = AntLaunching.LEFT_COLUMN_SIZE - (taskName.length() + 3);
		int offset = Math.max(size - 2, 1);
		int length = AntLaunching.LEFT_COLUMN_SIZE - size - 3;
		if (fileName != null) {
			generateLink(line, fileName, lineNumber, offset, length);
		}

		StringBuffer fullMessage = new StringBuffer();
		adornMessage(taskName, line, fullMessage);
		writeMessage(fullMessage.append(System.getProperty("line.separator")).toString(), priority); //$NON-NLS-1$
	}

	private void generateLink(String line, String fileName, int lineNumber, int offset, int length) {
		if (fLaunch != null) {
			((AntLaunch) fLaunch).addLinkDescriptor(line, fileName, lineNumber, offset, length);
		}
	}

	/**
	 * Returns the associated process, finding it if necessary.
	 */
	protected IProcess getProcess() {
		if (fProcess == null) {
			if (fProcessId != null) {
				for (IProcess process : DebugPlugin.getDefault().getLaunchManager().getProcesses()) {
					if (fProcessId.equals(process.getAttribute(AbstractEclipseBuildLogger.ANT_PROCESS_ID))) {
						fProcess = process;
						break;
					}
				}
			}
		}
		return fProcess;
	}

	private AntStreamMonitor getMonitor(int priority) {
		IProcess process = getProcess();
		if (process == null) {
			return null;
		}
		AntStreamsProxy proxy = (AntStreamsProxy) process.getStreamsProxy();
		if (proxy == null) {
			return null;
		}
		AntStreamMonitor monitor = null;
		switch (priority) {
			case Project.MSG_INFO:
				monitor = (AntStreamMonitor) proxy.getOutputStreamMonitor();
				break;
			case Project.MSG_ERR:
				monitor = (AntStreamMonitor) proxy.getErrorStreamMonitor();
				break;
			case Project.MSG_DEBUG:
				monitor = (AntStreamMonitor) proxy.getDebugStreamMonitor();
				break;
			case Project.MSG_WARN:
				monitor = (AntStreamMonitor) proxy.getWarningStreamMonitor();
				break;
			case Project.MSG_VERBOSE:
				monitor = (AntStreamMonitor) proxy.getVerboseStreamMonitor();
				break;
			default:
				break;
		}
		return monitor;
	}

	/**
	 * Builds a right justified task prefix for the given build event, placing it in the given string buffer.
	 *
	 * @param taskName
	 *            the name of the task, can be <code>null</code>
	 * @param line
	 *            the line of text
	 * @param fullMessage
	 *            buffer to place task prefix in
	 */
	private void adornMessage(String taskName, String line, StringBuffer fullMessage) {
		String tname = taskName;
		if (tname == null) {
			tname = "null"; //$NON-NLS-1$
		}

		int size = AntLaunching.LEFT_COLUMN_SIZE - (tname.length() + 6);
		for (int i = 0; i < size; i++) {
			fullMessage.append(' ');
		}

		fullMessage.append(line);
	}

	protected void writeMessage(String message, int priority) {
		AntStreamMonitor monitor = getMonitor(priority);
		if (monitor == null) {
			if (fMessageQueue == null) {
				fMessageQueue = new ArrayList<>();
			}
			fMessageQueue.add(message);
			return;
		}
		if (fMessageQueue != null) {
			for (String oldMessage : fMessageQueue) {
				monitor.append(oldMessage);
			}
			fMessageQueue = null;
		}
		monitor.append(message);
	}

	@Override
	public void launchesAdded(ILaunch[] launches) {
		// do nothing
	}

	@Override
	public void launchesChanged(ILaunch[] launches) {
		// do nothing
	}

	@Override
	public void launchesRemoved(ILaunch[] launches) {
		for (ILaunch launch : launches) {
			if (launch.equals(fLaunch)) {
				shutDown();
				return;
			}
		}
	}
}