/*******************************************************************************
 * Copyright (c) 2001, 2005 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.jem.internal.proxy.remote;
/*
 *  $RCSfile: REMCallbackThread.java,v $
 *  $Revision: 1.16 $  $Date: 2005/08/24 20:39:06 $ 
 */

import java.io.*;
import java.net.Socket;
import java.util.logging.Level;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;

import org.eclipse.jem.internal.proxy.common.remote.Commands;
import org.eclipse.jem.internal.proxy.common.remote.TransmitableArray;
import org.eclipse.jem.internal.proxy.core.*;

/**
 * This thread handles the actual callback.
 * It is package protected because no one else should access it.
 */
class REMCallbackThread extends Thread {
	final REMConnection fConnection;	// A connection to use
	final REMCallbackRegistry fServer;
	final REMStandardBeanProxyFactory fFactory;
	final REMStandardBeanTypeProxyFactory fTypeFactory;
	final REMProxyFactoryRegistry registry;
	protected boolean shuttingDown;
	protected boolean inTransaction;	// Is this thread currently participating in a transaction, (i.e. reading/writing), if so then we can't use it for another transaction.
	

	/**
	 * Is this callback thread currently participating in a transaction (reading/writing). If so then it can't be used for an
	 * independent new transaction. In other words you can't write/read data using this callback thread's
	 * connection because it is being used by someone else expecting to have exclusive read/write on this connection.
	 * 
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public boolean inTransaction() {
		return inTransaction;
	}
	
	/**
	 * Set whether this callback thread is in a transaction or not. If it is in a transaction it cannot be used
	 * for an independent new transaction. In other words you can't write/read data using this callback thread's
	 * connection because it is being used by someone else expecting to have exclusive read/write on this connection.
	 * @param inTransaction
	 * 
	 * @since 1.1.0
	 */
	public void setIntransaction(boolean inTransaction) {
		this.inTransaction = inTransaction;
	}
	
	// Kludge: Bug in Linux 1.3.xxx of JVM. Closing a socket while the socket is being read/accept will not interrupt the
	// wait. Need to timeout to the socket read/accept before the socket close will be noticed. This has been fixed
	// in Linux 1.4. So on Linux 1.3 need to put timeouts in on those sockets that can be separately closed while reading/accepting.
	static boolean LINUX_1_3 = "linux".equalsIgnoreCase(System.getProperty("os.name")) && System.getProperty("java.version","").startsWith("1.3");	 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
	
	public REMCallbackThread(Socket socket, REMCallbackRegistry server, String name, REMProxyFactoryRegistry registry, boolean noTimeouts) {
		super(name);
		
		fConnection = new REMConnection(socket, true);	// No timeouts since this is a server thread.
		this.registry = registry;
		fServer = server;
		fFactory = (REMStandardBeanProxyFactory) registry.getBeanProxyFactory();
		fTypeFactory = (REMStandardBeanTypeProxyFactory) registry.getBeanTypeProxyFactory();		
	}
	
	/**
	 * Request the thread to close down.
	 */
	public void close() {
		try {
			shuttingDown = true;	// So that if this is a forced close then it will know not to print error msgs.
			if (fConnection.fSocket != null)
				fConnection.fSocket.close();
		} catch (Exception e) {
		}
	}
	
	
	/*
	 * Return the IREMConnection associated with this callback. Used by
	 * the connection server to return this connection for any requests 
	 * made on this thread.
	 * <package-protected> so that only remote proxy can access.
	 */
	IREMConnection getConnection() {
		return fConnection;
	}
	
	public void run() {

		DataInputStream in = fConnection.in;
		DataOutputStream out = fConnection.out;	
		InputStream ins = null;	
		boolean shutdown = false;
		Commands.ValueObject valueObject = new Commands.ValueObject();	// Working value object so not continually recreated.
		BeanProxyValueSender valueSender = new BeanProxyValueSender(this.fFactory);	// Working valuesender so not continually recreated. 
		try {
			boolean doLoop = true;

			/**
			 * Note: In the cases below you will see a lot of finally clauses that null variables out.
			 * This is because this is a long running loop, and variables declared within blocks are not
			 * garbage collected until the method is terminated, so these variables once set would never
			 * be GC'd. The nulling at the end of the case makes sure that any of those objects set are
			 * now available for garbage collection when necessary.
			 */		
			while(doLoop) {
				byte cmd = 0;
				try {
					if (LINUX_1_3)
						fConnection.fSocket.setSoTimeout(1000);	// Linux 1.3 bug, see static LINUX_1_3 above
					cmd = in.readByte();
					if (LINUX_1_3)
						fConnection.fSocket.setSoTimeout(0);	// Linux 1.3 bug, see static LINUX_1_3 above
				} catch (InterruptedIOException e) {
					continue;	// Timed out, try again
				}
					
				switch (cmd) {
					case Commands.QUIT_CONNECTION:				
						doLoop = false;	
						break;	// Close this connection
						
					case Commands.TERMINATE_SERVER:
						doLoop = false;		
						shutdown = true;	// Shutdown everything
						break;
						
					case Commands.CALLBACK:
						int callID = in.readInt();	// The id of the registered callback to call.
						int msgID = in.readInt();	// The id of the message to call.
						Object parm = null;
						Object result = null;
						ICallback cb = null;
						try {
							// The register callback handler will know how to handle the parm,
							// it will know if it is an array of proxies, or an object of some kind.
							fFactory.startTransaction();	// Start a transaction.
							setIntransaction(true);	// Also tell ourselves that we are in a transaction.
							boolean isProxies = true;							
							try {
								Commands.readValue(in, valueObject);
								if (valueObject.type == Commands.ARRAY_IDS) {
									// It is an array containing IDs, as it normally would be.
									// However it will become IBeanProxy[]. That is because if ID's
									// they must be proxies over here.
									valueSender.initialize(valueObject);
									Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
									if (valueSender.getException() != null) {
										close();	// Something wrong, close the thread so next time we get a new one.
									}
									parm = valueSender.getArray();
								} else {
									// It is object or null. It could be an array of objects, or one object.
									isProxies = false;
									parm = valueObject.getAsObject();
								}
							} finally {
								setIntransaction(false);
								fFactory.stopTransaction();
							}
							// Now perform the callback.
							cb = fServer.getRegisteredCallback(callID);
							if (cb != null) {
								// Callback still registered. If proxies, then if first entry is just a proxy,
								// then we are sending only one. A convienence factor for callbacks.
								// If not a single entry of IBeanProxy, then send whole array.
								try {
									if (isProxies)
										if (((Object[]) parm).length == 1 && (((Object[]) parm)[0] == null || ((Object[]) parm)[0] instanceof IBeanProxy))
											result = cb.calledBack(msgID, (IBeanProxy) ((Object[]) parm)[0]);
										else
											result = cb.calledBack(msgID, (Object[]) parm);
									else
										result = cb.calledBack(msgID, parm);
									// We only accept null, IREMBeanProxies, and Object[], where
									// contents of Object[] are bean proxies.
									valueObject.set();
									if (result instanceof IREMBeanProxy)
										 ((IREMBeanProxy) result).renderBean(valueObject);
									else if (result instanceof Object[]) {
										class Retriever implements Commands.ValueRetrieve {
											int index = 0;
											Object[] array;
											Commands.ValueObject worker = new Commands.ValueObject();

											public Retriever(Object[] anArray) {
												array = anArray;
											}

											public Commands.ValueObject nextValue() {
												Object retParm = array[index++];
												if (retParm != null)
													if (retParm instanceof IREMBeanProxy)
														 ((IREMBeanProxy) retParm).renderBean(worker);
													else if (retParm instanceof TransmitableArray) {
														// It is another array, create a new
														// retriever.
														worker.setArrayIDS(
															new Retriever(((TransmitableArray) retParm).array),
															((TransmitableArray) retParm).array.length,
															((TransmitableArray) retParm).componentTypeID);
													} else {
														// It's an object. Need to get bean
														// type so that we can send it.
														IREMBeanProxy type =
															(IREMBeanProxy) fTypeFactory.getBeanTypeProxy(retParm.getClass().getName());
														if (type == null)
															throw new IllegalArgumentException();
														int classID = type.getID().intValue();
														worker.setAsObject(retParm, classID);
													}
												else
													worker.set();
												return worker; 
											}
										};

										valueObject.setArrayIDS(
											new Retriever((Object[]) result),
											((Object[]) result).length,
											Commands.OBJECT_CLASS);
									}
									
									Commands.sendCallbackDoneCommand(out, valueObject, Commands.NO_ERROR);
								} catch (RuntimeException e) {
									// Something happened, turn it into an error object
									// to send back.
									valueObject.set(e.getClass().getName() + ':' + e.getLocalizedMessage());
									Commands.sendCallbackDoneCommand(out, valueObject, Commands.CALLBACK_RUNTIME_EXCEPTION);
									ProxyPlugin.getPlugin().getLogger().log(e, Level.INFO);	// Just log it, but assume safe enough to just go back and wait for next callback request.
								}
							} else {
								valueObject.set();
								Commands.sendCallbackDoneCommand(out, valueObject, Commands.CALLBACK_NOT_REGISTERED);	// Send error msg back to indicate we weren't registered.								
							}
						} finally {
							parm = null;	// Clear out for GC to work
							result = null;
							cb = null;
							valueObject.set();
							valueSender.clear();
						}
						break;
						
					case Commands.CALLBACK_STREAM:
						// A request for a stream
						callID = in.readInt();	// The id of the registered callback to call.
						msgID = in.readInt();	// The id of the message to call.
						cb = null;
						try {
							// Now perform the callback.
							cb = fServer.getRegisteredCallback(callID);
							if (cb != null) {
								// Callback still registered
								valueObject.set();								
								Commands.sendCallbackDoneCommand(out, valueObject, Commands.NO_ERROR);	// Send null to let it know we've accepted the stream
								ins = new REMCallbackInputStream(in, out);
								try {
									cb.calledBackStream(msgID, ins);
								} finally {
									try {
										ins.close();	// Make sure it's closed.
									} catch (IOException e) {
										// Exception while closing, just log it and then mark to end the loop so we close connection too.
										doLoop = false;
										ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.ERROR, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "In REMCallbackThread", e)); //$NON-NLS-1$										
									}
								}
							} else {
								valueObject.set();
								Commands.sendCallbackDoneCommand(out, valueObject, Commands.CALLBACK_NOT_REGISTERED);	// Send error msg back to indicate we weren't registered.								
							}
						} finally {
							cb = null;	// Clear out for GC to work
							ins = null;
							valueObject.set();							
						}
						break;																	
						
					default:
						// Unknown command. We don't know how long the command is, so we need to close the connection.
						ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.ERROR, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "REMCallback: Invalid cmd sent="+cmd, null)); //$NON-NLS-1$
						doLoop = false;						
						break;
				}
			}
		} catch (EOFException e) {
			// This is ok. It means that the connection on the other side was terminated.
			// So just accept this and go down.
		} catch (Throwable e) {
			if (!shuttingDown)
				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.ERROR, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "In REMCallbackThread", e)); //$NON-NLS-1$
		} finally {
			if (in != null)
				try {
					in.close();
				} catch (Exception e) {
				}
			if (out != null)
				try {
					out.close();
				} catch (Exception e) {
				}
			close();
		}		
		fServer.removeCallbackThread(this);
		if (shutdown)
			fServer.requestShutdown();
	}	
}
