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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.Location;
import org.apache.tools.ant.Task;
import org.eclipse.ant.internal.launching.debug.AntDebugState;
import org.eclipse.ant.internal.launching.debug.IDebugBuildLogger;
import org.eclipse.ant.internal.launching.debug.model.DebugMessageIds;

/**
 * Parts adapted from org.eclipse.jdt.internal.junit.runner.RemoteTestRunner A build logger that reports via a socket connection. See DebugMessageIds
 * and MessageIds for more information about the protocol.
 */
public class RemoteAntDebugBuildLogger extends RemoteAntBuildLogger implements IDebugBuildLogger {

	private ServerSocket fServerSocket;
	private static final int fgServerSocketTimeout = 5000;
	private Socket fRequestSocket;

	private PrintWriter fRequestWriter;

	private BufferedReader fRequestReader;

	private boolean fBuildStartedSuspend = true;

	private Task fStepOverTaskInterrupted;

	private List<RemoteAntBreakpoint> fBreakpoints = null;

	/**
	 * Request port to connect to. Used for debug connections
	 */
	private int fRequestPort = -1;
	private AntDebugState fDebugState;

	/**
	 * Reader thread that processes requests from the debug client.
	 */
	private class ReaderThread extends Thread {
		public ReaderThread() {
			super("ReaderThread"); //$NON-NLS-1$
			setDaemon(true);
		}

		@Override
		public void run() {
			try {
				String message = null;
				while (fRequestReader != null) {
					if ((message = fRequestReader.readLine()) != null) {

						if (message.startsWith(DebugMessageIds.STEP_INTO)) {
							synchronized (RemoteAntDebugBuildLogger.this) {
								fDebugState.setStepIntoSuspend(true);
								fDebugState.setStepIntoTask(fDebugState.getCurrentTask());
								RemoteAntDebugBuildLogger.this.notifyAll();
							}
						}
						if (message.startsWith(DebugMessageIds.STEP_OVER)) {
							synchronized (RemoteAntDebugBuildLogger.this) {
								fDebugState.stepOver();
							}
						} else if (message.startsWith(DebugMessageIds.SUSPEND)) {
							synchronized (RemoteAntDebugBuildLogger.this) {
								fDebugState.setStepIntoTask(null);
								fDebugState.setStepOverTask(null);
								fStepOverTaskInterrupted = null;
								fDebugState.setClientSuspend(true);
							}
						} else if (message.startsWith(DebugMessageIds.RESUME)) {
							synchronized (RemoteAntDebugBuildLogger.this) {
								fDebugState.setStepIntoTask(null);
								fDebugState.setStepOverTask(null);
								fStepOverTaskInterrupted = null;
								RemoteAntDebugBuildLogger.this.notifyAll();
							}
						} else if (message.startsWith(DebugMessageIds.TERMINATE)) {
							synchronized (RemoteAntDebugBuildLogger.this) {
								sendRequestResponse(DebugMessageIds.TERMINATED);
								shutDown();
							}
						} else if (message.startsWith(DebugMessageIds.STACK)) {
							synchronized (RemoteAntDebugBuildLogger.this) {
								marshallStack();
							}
						} else if (message.startsWith(DebugMessageIds.ADD_BREAKPOINT)) {
							synchronized (RemoteAntDebugBuildLogger.this) {
								addBreakpoint(message);
							}
						} else if (message.startsWith(DebugMessageIds.REMOVE_BREAKPOINT)) {
							synchronized (RemoteAntDebugBuildLogger.this) {
								removeBreakpoint(message);
							}
						} else if (message.startsWith(DebugMessageIds.PROPERTIES)) {
							synchronized (RemoteAntDebugBuildLogger.this) {
								marshallProperties();
							}
						}
					}
				}
			}
			catch (Exception e) {
				RemoteAntDebugBuildLogger.this.shutDown();
			}
		}
	}

	private void requestConnect() {
		if (fDebugMode) {
			System.out.println("RemoteAntDebugBuildLogger: trying to connect" + fHost + ":" + fRequestPort); //$NON-NLS-1$ //$NON-NLS-2$
		}

		try {
			fServerSocket.setSoTimeout(fgServerSocketTimeout);
			fRequestSocket = fServerSocket.accept();
			fRequestWriter = new PrintWriter(fRequestSocket.getOutputStream(), true);
			fRequestReader = new BufferedReader(new InputStreamReader(fRequestSocket.getInputStream()));

			ReaderThread readerThread = new ReaderThread();
			readerThread.setDaemon(true);
			readerThread.start();
			return;
		}
		catch (SocketTimeoutException e) {
			// do nothing
		}
		catch (IOException e) {
			// do nothing
		}
		shutDown();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.antsupport.logger.RemoteAntBuildLogger#shutDown()
	 */
	@Override
	protected synchronized void shutDown() {
		if (fRequestWriter != null) {
			fRequestWriter.close();
			fRequestWriter = null;
		}

		if (fRequestReader != null) {
			try {
				fRequestReader.close();
			}
			catch (IOException e) {
				// do nothing
			}
			fRequestReader = null;
		}

		if (fRequestSocket != null) {
			try {
				fRequestSocket.close();
			}
			catch (IOException e) {
				// do nothing
			}
		}
		fRequestSocket = null;

		super.shutDown();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.BuildListener#buildStarted(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public synchronized void buildStarted(BuildEvent event) {
		fDebugState = new AntDebugState(this);
		super.buildStarted(event);
		marshalMessage(-1, DebugMessageIds.BUILD_STARTED);
		if (fRequestPort != -1) {
			try {
				fServerSocket = new ServerSocket(fRequestPort);
			}
			catch (IOException ioe) {
				shutDown();
			}
			requestConnect();
		} else {
			shutDown();
		}
		fDebugState.buildStarted();
		fDebugState.setShouldSuspend(true);
		waitIfSuspended();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.launching.remote.logger.RemoteAntBuildLogger#buildFinished(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public synchronized void buildFinished(BuildEvent event) {
		super.buildFinished(event);
		fDebugState.buildFinished();
		fDebugState = null;
		if (fBreakpoints != null) {
			fBreakpoints.clear();
		}
		if (fRequestReader != null) {
			try {
				fRequestReader.close();
			}
			catch (IOException e) {
				// do nothing
			}
		}
		if (fRequestWriter != null) {
			fRequestWriter.close();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.BuildListener#taskStarted(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public synchronized void taskStarted(BuildEvent event) {
		super.taskStarted(event);
		fDebugState.taskStarted(event);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.BuildListener#taskFinished(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public synchronized void taskFinished(BuildEvent event) {
		super.taskFinished(event);
		fDebugState.taskFinished();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.antsupport.logger.util.IDebugBuildLogger#waitIfSuspended()
	 */
	@Override
	public synchronized void waitIfSuspended() {
		String detail = null;
		boolean shouldSuspend = true;
		RemoteAntBreakpoint breakpoint = breakpointAtLineNumber(fDebugState.getBreakpointLocation());
		if (breakpoint != null) {
			detail = breakpoint.toMarshallString();
			fDebugState.setShouldSuspend(false);
			if (fDebugState.getStepOverTask() != null) {
				fStepOverTaskInterrupted = fDebugState.getStepOverTask();
				fDebugState.setStepOverTask(null);
			}
		} else if (fDebugState.getCurrentTask() != null) {
			if (fDebugState.isStepIntoSuspend()) {
				detail = DebugMessageIds.STEP;
				fDebugState.setStepIntoSuspend(false);
			} else if ((fDebugState.getLastTaskFinished() != null && fDebugState.getLastTaskFinished() == fDebugState.getStepOverTask())
					|| fDebugState.shouldSuspend()) {
				// suspend as a step over has finished
				detail = DebugMessageIds.STEP;
				fDebugState.setStepOverTask(null);
				fDebugState.setShouldSuspend(false);
			} else if (fDebugState.getLastTaskFinished() != null && fDebugState.getLastTaskFinished() == fDebugState.getStepIntoTask()) {
				// suspend as a task that was stepped into has finally completed
				detail = DebugMessageIds.STEP;
				fDebugState.setStepIntoTask(null);
			} else if (fDebugState.getLastTaskFinished() != null && fDebugState.getLastTaskFinished() == fStepOverTaskInterrupted) {
				// suspend as a task that was stepped over but hit a breakpoint has finally completed
				detail = DebugMessageIds.STEP;
				fStepOverTaskInterrupted = null;
			} else if (fDebugState.isClientSuspend()) {
				detail = DebugMessageIds.CLIENT_REQUEST;
				fDebugState.setClientSuspend(false);
			} else {
				shouldSuspend = false;
			}
		} else if (fDebugState.shouldSuspend() && fBuildStartedSuspend) {
			fBuildStartedSuspend = false;
			fDebugState.setShouldSuspend(false);
		} else {
			shouldSuspend = false;
		}

		if (shouldSuspend) {
			if (detail != null) {
				StringBuffer message = new StringBuffer(DebugMessageIds.SUSPENDED);
				message.append(detail);
				sendRequestResponse(message.toString());
			}
			try {
				wait();
				shouldSuspend = false;
			}
			catch (InterruptedException e) {
				// do nothing
			}
		}
	}

	private RemoteAntBreakpoint breakpointAtLineNumber(Location location) {
		if (fBreakpoints == null || location == null || location == Location.UNKNOWN_LOCATION) {
			return null;
		}
		String fileName = fDebugState.getFileName(location);
		int lineNumber = fDebugState.getLineNumber(location);
		for (int i = 0; i < fBreakpoints.size(); i++) {
			RemoteAntBreakpoint breakpoint = fBreakpoints.get(i);
			if (breakpoint.isAt(fileName, lineNumber)) {
				return breakpoint;
			}
		}
		return null;
	}

	private synchronized void sendRequestResponse(String message) {
		if (fRequestWriter == null) {
			return;
		}

		fRequestWriter.println(message);
	}

	protected void marshallStack() {
		StringBuffer stackRepresentation = new StringBuffer();
		fDebugState.marshalStack(stackRepresentation);
		sendRequestResponse(stackRepresentation.toString());
	}

	protected void marshallProperties() {
		StringBuffer propertiesRepresentation = new StringBuffer();
		fDebugState.marshallProperties(propertiesRepresentation, true);
		sendRequestResponse(propertiesRepresentation.toString());
	}

	@SuppressWarnings("unused")
	protected void addBreakpoint(String breakpointRepresentation) {
		if (fBreakpoints == null) {
			fBreakpoints = new ArrayList<RemoteAntBreakpoint>();
		}
		RemoteAntBreakpoint newBreakpoint = new RemoteAntBreakpoint(breakpointRepresentation);
		if (!fBreakpoints.contains(newBreakpoint)) {
			fBreakpoints.add(newBreakpoint);
		}
	}

	protected void removeBreakpoint(String breakpointRepresentation) {
		if (fBreakpoints == null) {
			return;
		}
		RemoteAntBreakpoint equivalentBreakpoint = new RemoteAntBreakpoint(breakpointRepresentation);
		for (Iterator<RemoteAntBreakpoint> iter = fBreakpoints.iterator(); iter.hasNext();) {
			RemoteAntBreakpoint breakpoint = iter.next();
			if (breakpoint.equals(equivalentBreakpoint)) {
				iter.remove();
				return;
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.BuildListener#targetStarted(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public synchronized void targetStarted(BuildEvent event) {
		fDebugState.targetStarted(event);
		if (!fSentProcessId) {
			establishConnection();
		}
		waitIfSuspended();
		super.targetStarted(event);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.tools.ant.BuildListener#targetFinished(org.apache.tools.ant.BuildEvent)
	 */
	@Override
	public synchronized void targetFinished(BuildEvent event) {
		super.targetFinished(event);
		fDebugState.setTargetExecuting(null);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ant.internal.ui.antsupport.logger.RemoteAntBuildLogger#configure(java.util.Map)
	 */
	@Override
	public synchronized void configure(Map<String, String> userProperties) {
		super.configure(userProperties);
		String requestPortProperty = userProperties.remove("eclipse.connect.request_port"); //$NON-NLS-1$
		if (requestPortProperty != null) {
			fRequestPort = Integer.parseInt(requestPortProperty);
		}
	}
}
