/////////////////////////////////////////////////////////////////////////
//
// © University of Southampton IT Innovation Centre, 2004
//
// Copyright in this library belongs to the IT Innovation Centre of
// 2 Venture Road, Chilworth Science Park, Southampton, SO16 7NP, UK.
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//      Created by:             Stuart E. Middleton
//      Created date:           2004/04/30
//      Created for project:    GEMSS
//
/////////////////////////////////////////////////////////////////////////
//
//      Dependencies: None
//
/////////////////////////////////////////////////////////////////////////
//
//      Last commit info:       $Author: $
//                              $Date: $
//                              $Revision: $
//
/////////////////////////////////////////////////////////////////////////

package uk.ac.soton.itinnovation.gemss.bindings.javarmi;

import java.rmi.*;
import java.io.*;
import java.util.logging.*;
import java.util.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.rmi.PortableRemoteObject;

import org.w3c.dom.Document;

import eu.gemss.GEMSS;
import eu.gemss.components.ComponentManager;
import eu.gemss.GridException;
import eu.gemss.components.proxies.GEMSSProxy;
import eu.gemss.components.proxies.GEMSSProxyRequest;
import eu.gemss.signals.*;
import eu.gemss.signals.negotiation.*;
import eu.gemss.signals.security.*;

import uk.ac.soton.itinnovation.gemss.*;
import uk.ac.soton.itinnovation.gemss.utils.zip.*;
import uk.ac.soton.itinnovation.gemss.utils.signalhandlers.*;
import uk.ac.soton.itinnovation.gemss.xmlobject.XMLObject;
import uk.ac.soton.itinnovation.gemss.transportmessaging.servicedescription.endpointtypes.WSDLEndpointImp;
import uk.ac.soton.itinnovation.gemss.utils.configuration.ConfigurationException;

/*
 * RMI proxy implementation, wrapping the real java 1.4 GEMSS proxy
 */
public class GEMSSRMIProxyImpl extends PortableRemoteObject implements GEMSSRMIProxy {
    // logging and test files
    private static Logger mLogger = Logger.getLogger("uk.ac.soton.itinnovation.gemss.bindings.java13");

    // member variables
    private String mstrWSDLFilename;
    private String mstrServiceName;
    private String mstrPortTypeEndPoint;
    private String mstrPortTypeService;
    private String mstrBinding;
    private String mstrTestFileUpload;
    private String mstrTestFileDownload;
    private boolean mbooleanUseSecureMessaging = true;

    private static String mstaticInputData = "input.zip";
    private static String mstaticOutputData = "output.zip";

    // constants
    private static String mstaticGetCID = "getCId";
    private static String mstaticUploadData = "upload";
    private static String mstaticDownloadData = "download";
    private static String mstaticGetStatus = "getStatus";
    private static String mstaticStart = "start";
    private static String mstaticKill = "kill";

    private SignalHandler mGuiHandler = null;

    // wrapper objects
    private CredentialRequestGUIHandler mHandler = null;
    private eu.gemss.components.proxies.GEMSSProxy mgemssproxy = null;

    /*
    * constructor
    */
    public GEMSSRMIProxyImpl() throws RemoteException {
    }

    /*
    * Proxy wrapper to the GEMSSProxy init method
    * @param strConfigFile filename containing the GEMSSProxy config options (end point etc)
     */
    public void init( String strConfigFile ) throws RemoteException
    {
	    ComponentManager compManager;
	    GEMSSProxyRequest request;

	    try {
		    // get the component manager
		    compManager = GEMSS.getInstance();
		    if( compManager == null ) {
			    mLogger.log(Level.INFO,"Component manager object null");
			    throw new RemoteException("Component manager object null");
		    }

		    // make a ProxyRequest with teh init parameters
		    request = new GEMSSProxyRequest( strConfigFile, "eu.gemss.components.proxies.GEMSSProxy", null, null );
		    if( request == null ) {
			    mLogger.log(Level.INFO,"Proxy request object null");
			    throw new RemoteException("Proxy request object null");
		    }

		    // get a GEMSS proxy
		    mgemssproxy = (eu.gemss.components.proxies.GEMSSProxy) compManager.getInstance( request );
		    if( mgemssproxy == null ) {
			    mLogger.log(Level.INFO,"GEMSS Proxy object null");
			    throw new RemoteException("GEMSS Proxy object null");
		    }

		    //register the GUI signal handler
		    mHandler = new CredentialRequestGUIHandler();
		    mLogger.log(Level.INFO,"*** Registering signal handler '" + mHandler.getClass().getName() + "' for signal '" + eu.gemss.signals.security.CredentialRequest.SIGNAL_TYPE +"***");
		    compManager.registerSignalHandler(mHandler,eu.gemss.signals.security.CredentialRequest.SIGNAL_TYPE);
	    }
	    catch(Exception ex) {
		    throw new RemoteException(ex.getMessage());
	    }
    }

    /*
    * Proxy wrapper to the GEMSSProxy upload method
    * @param strInputFile input filename for the archive file to upload
    */
    public void uploadData( String strInputFile ) throws RemoteException
    {
	    try{
		    mgemssproxy.uploadData( strInputFile );
		    mLogger.log( Level.INFO,"GEMSSProxy.uploadData call successful" );
	    }
	    catch(Exception ex) {
		    throw new RemoteException("upload failed "+ex.getMessage());
	    }
    }

    /*
    * Proxy wrapper to the GEMSSProxy start method
    */
    public void start() throws RemoteException
    {
	    try{
		    mgemssproxy.start();
		    mLogger.log( Level.INFO,"GEMSSProxy.start call successful" );
	    }
	    catch(Exception ex) {
		    throw new RemoteException("start failed : "+ex.getMessage());
	    }
    }

    /*
    * Proxy wrapper to the GEMSSProxy downloadData method
    * @param strFilename filename of the file you want to download. If "" then the output archive file
    * for this app will be downloaded, if it is available.
    * @param strOutputFile output filename for the downloaded archive file
    */
    public void downloadData( String strFilename, String strOutputFile ) throws RemoteException
    {
	    try{
		    mgemssproxy.downloadData( strFilename,strOutputFile );
		    mLogger.log( Level.INFO,"GEMSSProxy.downloadData call successful" );
	    }
	    catch(Exception ex) {
		    throw new RemoteException("Failed to download "+ex.getMessage());
	    }
    }

    /*
    * Proxy wrapper to the GEMSSProxy getStatus method
    * @return Status string as returned by the application specific monitor job script
    */
    public String getStatus() throws RemoteException
    {
	    String strStatus;

	    try{
		    strStatus = mgemssproxy.getStatus();
		    mLogger.log( Level.INFO,"GEMSSProxy.getStatus call successful" );
		    return strStatus;
	    }
	    catch(Exception ex) {
		    throw new RemoteException("get status failed "+ex.getMessage());
	    }
    }

    /*
    * Proxy wrapper to the GEMSSProxy kill method
    */
    public void kill() throws RemoteException
    {
	    try{
		    mgemssproxy.kill();
	    }
	    catch(Exception ex) {
		    throw new RemoteException(ex.getMessage());
	    }
    }

    /*
    * Proxy wrapper to the GEMSSProxy acknowledgeResults method
    */
    public void acknowledgeResults() throws RemoteException
    {
	    try{
		    mgemssproxy.acknowledgeResults();
		    mLogger.log( Level.INFO,"GEMSSProxy.acknowledgeResults call successful" );
	    }
	    catch(Exception ex) {
		    throw new RemoteException("acknowledgeResults failed : "+ex.getMessage());
	    }
    }

    /*
    * Proxy wrapper to the GEMSSProxy getCId method
    * getCId will eventually be replaced by a negotiation step, but for phase two this must
    * be called before using the other proxy methods. See design for more details.
    * @return ID string returned by the service
    */
    public String getJobCId() throws RemoteException
    {
	    String strResult;

	    try{
		    strResult = mgemssproxy.getJobCID();
		    mLogger.log( Level.INFO,"GEMSSProxy.getCId call successful" );
		    return strResult;
	    }
	    catch(Exception ex) {
		    throw new RemoteException("getCId failed : "+ex.getMessage());
	    }
    }

    /**
     * Shutdown this instance and shutdowns the GEMSS proxy
     */
    public void shutdown() {
	    // todo save session ??
    }
}