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

		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;
	}
	
	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) {}
		} 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) {
        	}
        }
        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) {
			}
    	}
    	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);
		}		
	}
	
	protected synchronized void shutDown() {
        if (fTarget != null) {
            try {
				fTarget.terminate();
				fTarget= null;
			} catch (DebugException e) {}
        }
		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) {
		}	
		if (fRequestWriter != null) {
			fRequestWriter.close();
			fRequestWriter= null;
		}
		try{
			if(fRequestSocket != null) {
				fRequestSocket.close();
				fRequestSocket= null;
			}
		} catch(IOException e) {
		}
		super.shutDown();
	}

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

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

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

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

	/* (non-Javadoc)
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#handleBreakpoint(IBreakpoint, boolean)
	 */
	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()
	 */
	public void getProperties() {
		sendRequest(DebugMessageIds.PROPERTIES);
	}

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

	/* (non-Javadoc)
	 * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#unescapeString(java.lang.StringBuffer)
	 */
	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;
	}
}
