/*******************************************************************************
 * 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;
/*


 */


import java.io.*;
import java.net.Socket;

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

import org.eclipse.jem.internal.proxy.common.CommandException;
import org.eclipse.jem.internal.proxy.common.remote.*;
import org.eclipse.jem.internal.proxy.common.remote.Commands.*;
import org.eclipse.jem.internal.proxy.core.ProxyPlugin;
import org.eclipse.jem.util.TimerTests;
/**
 * The default implementation of the connection.
 *
 * It uses the property "proxyvm.bufsize" to determine the buffer size to use. If not specified, it uses the system default
 */
public class REMConnection implements IREMConnection, IREMExpressionConnection {
	
	public final static String INVOKE_STEP = "Invoke"; //$NON-NLS-1$
	public final static String INVOKE_METHOD_STEP = "Invoke Method"; //$NON-NLS-1$
	protected Socket fSocket = null;
	protected DataInputStream in = null;
	protected DataOutputStream out = null;
	private static final int TIME_OUT = 1000 * 30;	// Wait up to half minute before timeout.
	
	public REMConnection(Socket socket, boolean noTimeouts) {
		try {
			fSocket = socket;
			fSocket.setSoLinger(true, 10);	// Wait 10 seconds if necessary for the final stuff to go out after closing.
			if (!noTimeouts)
				fSocket.setSoTimeout(TIME_OUT);	// Timeout period
			Integer bufSize = Integer.getInteger("proxyvm.bufsize"); //$NON-NLS-1$
			if (bufSize == null)
				bufSize = new Integer(16000);
			out = new DataOutputStream(new BufferedOutputStream(fSocket.getOutputStream(), bufSize.intValue()));	// It didn't take the hint, so we will buffer it.
			in = new DataInputStream(new BufferedInputStream(fSocket.getInputStream(), bufSize.intValue()));	// It didn't take the hint, so we will buffer it.
		} catch (IOException e) {
			ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.ERROR, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$
			
			if (out != null)
				try {
					out.close();
				} catch (IOException e2) {
				}
			if (in != null)
				try {
					in.close();
				} catch (IOException e3) {
				}
			try {
				fSocket.close();
			} catch (IOException e4) {
			}
			fSocket = null;
			in = null;
			out = null;
		}
	}
	
	/**
	 * Did this construct correctly.
	 * This is needed because an exception could be thrown in the ctor and
	 * that's not a good thing to do.
	 */
	public boolean isConnected() {
		return fSocket != null;
	}
	
	/**
	 * Terminate the server. 
	 */
	public void terminateServer() {
		if (isConnected()) {
			try {
				Commands.sendTerminateCommand(out);
			} catch (IOException e) {
			}
			close();
		}
	}
	
	/**
	 * Close the connection.
	 */
	public void close() {
		if (isConnected()) {
			try {
				Commands.sendQuitCommand(out);
			} catch (IOException e) {
			} finally {
				try {
					out.close();
				} catch (IOException e2) {
				}
				try {
					in.close();
				} catch (IOException e3) {
				}
				try {
					fSocket.close();
				} catch (IOException e4) {
				}
			}
			fSocket = null;
			in = null;
			out = null;
		}
	}
		
					
	/**
	 * Return the class information.
	 */
	public GetClassReturn getClass(String className) throws CommandException {
		if (isConnected())
			try {
				// It's simple, just pass onto Commands.
				return Commands.sendGetClassCommand(out, in, className);
			} catch (CommandErrorException e) {
				if (e.getErrorCode() != Commands.GET_CLASS_NOT_FOUND)
					throw e;	// Not class not found, send it on
			}			
		return null;	// Not found, so return null				
	}
	
	
	/**
	 * Return the class information given an ID.
	 */
	public GetClassIDReturn getClassFromID(int classID) throws CommandException {
		if (isConnected()) {
			// It's simple, just pass onto Commands.
			return Commands.sendGetClassFromIDCommand(out, in, classID);
		}
		return null;	// Not found, so return null		
	}	
	
	/**
	 * Get the object data from an id.
	 */
	public void getObjectData(int classID, Commands.ValueObject valueReturn) throws CommandException {
		if (isConnected()) {
			// Just pass onto Commands.
			Commands.sendGetObjectData(out, in, classID, valueReturn);
		} else
			valueReturn.set();	// Set it to null since we aren't connected.
	}	

	/**
	 * Get a new instance using an init string
	 */
	public void getNewInstance(int classID, String initString, Commands.ValueObject newInstance) throws CommandException {
		if (isConnected()) {
			// Just pass onto Commands.
			Commands.sendNewInstance(out, in, classID, initString, newInstance);
		} else
			newInstance.set();	// Set it to null since we aren't connected.
	}
	
	/**
	 * Release the id.
	 */
	public void releaseID(int id){
		if (isConnected())
			try {
				// Just pass onto Commands.
				Commands.releaseObjectCommand(out, id);
			} catch (IOException e) {
				// Don't care it didn't work
			}
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMConnection#getArrayContents(int, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
	 */
	public void getArrayContents(int arrayID, Commands.ValueObject returnValue) throws CommandException {
		if (isConnected()) {
			// It's simple, just pass onto Commands.
			Commands.sendGetArrayContentsCommand(out, in, arrayID, returnValue);
		}			
	}
	
	/**
	 * Invoke the method call
	 */	
	public void invokeMethod(int methodID, Commands.ValueObject invokeOn, Commands.ValueObject parms, Commands.ValueObject returnValue) throws CommandException {
		if (isConnected()) {
			// It's simple, just pass onto Commands.
			TimerTests.basicTest.startCumulativeStep(INVOKE_METHOD_STEP);
			Commands.sendInvokeMethodCommand(out, in, methodID, invokeOn, parms, returnValue);
			TimerTests.basicTest.stopCumulativeStep(INVOKE_METHOD_STEP);
		}			
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMConnection#invokeMethod(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject, java.lang.String, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
	 */
	public void invokeMethod(ValueObject classType, String methodName, ValueObject parmTypes, ValueObject invokeOn, ValueObject parms,
			ValueObject returnValue) throws CommandException {
		if (isConnected()) {
			// It's simple, just pass onto Commands.
			TimerTests.basicTest.startCumulativeStep(INVOKE_STEP);
			Commands.sendInvokeMethodCommand(out, in, classType, methodName, parmTypes, invokeOn, parms, returnValue);
			TimerTests.basicTest.stopCumulativeStep(INVOKE_STEP);
		}			
	}
	
	/* ************************************************************
	 * Put the Expression processing commands here.
	 * 
	 * ************************************************************/
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#startExpressionProcessing()
	 */
	public void startExpressionProcessing(int expressionID, byte trace) throws IOException {
		if (isConnected())
			ExpressionCommands.sendStartExpressionProcessingCommand(expressionID, trace, out);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushExpressionCommand(byte)
	 */
	public void pushExpressionCommand(int expressionID, byte subcommand) throws IOException {
		if (isConnected())
			ExpressionCommands.sendExpressionCommand(expressionID, out, subcommand);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#stopExpressionProcessing()
	 */
	public void stopExpressionProcessing(int expressionID) throws IOException {
		if (isConnected())
			ExpressionCommands.sendEndExpressionProcessingCommand(expressionID, out);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushValueObject(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
	 */
	public void pushValueObject(ValueObject valueObject) throws CommandException {
		if (isConnected())
			Commands.writeValue(out, valueObject, false);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushByte(byte)
	 */
	public void pushByte(byte abyte) throws IOException {
		if (isConnected())
			ExpressionCommands.sendByte(out, abyte);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushInt(int)
	 */
	public void pushInt(int anInt) throws IOException {
		if (isConnected())
			ExpressionCommands.sendInt(out, anInt);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushString(java.lang.String)
	 */
	public void pushString(String aString) throws IOException {
		if (isConnected())
			ExpressionCommands.sendString(out, aString);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pushBoolean(boolean)
	 */
	public void pushBoolean(boolean aBool) throws IOException {
		if (isConnected())
			ExpressionCommands.sendBoolean(out, aBool);
	}

	
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#getFinalValue(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
	 */
	public void getFinalValue(ValueObject result) throws CommandException {
		if (isConnected())
			Commands.readBackValue(in, result, Commands.NO_TYPE_CHECK);
	}
	
	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#pullValue(int, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
	 */
	public void pullValue(int expressionID, ValueObject proxyids, ValueSender sender) throws CommandException {
		if (isConnected())
			ExpressionCommands.sendPullValueCommand(expressionID, out, in, proxyids, sender);
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMExpressionConnection#sync(int, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject)
	 */
	public void sync(int expressionID, ValueObject proxyids, ValueSender sender) throws CommandException {
		if (isConnected())
			ExpressionCommands.sendSyncCommand(expressionID, out, in, proxyids, sender);
	}

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.remote.IREMConnection#readProxyArrayValues(org.eclipse.jem.internal.proxy.common.remote.Commands.ValueObject, org.eclipse.jem.internal.proxy.common.remote.Commands.ValueSender, boolean)
	 */
	public void readProxyArrayValues(Commands.ValueObject returnValue, Commands.ValueSender valueSender, boolean allowFlag) throws CommandException {
		if (isConnected())
			Commands.readArray(in, returnValue.anInt, valueSender, returnValue, allowFlag);
	}

	public void transferExpression(int expressionID, ValueObject expController) throws CommandException {
		if (isConnected())
			ExpressionCommands.sendTransferExpressionCommand(expressionID, out, in, expController);
	}

	public void resumeExpression(int expressionID, ValueObject expController) throws CommandException {
		if (isConnected())
			ExpressionCommands.sendResumeExpressionCommand(expressionID, out, expController);
	}

}
