package condor.gahp.gt3;

import condor.gahp.*;
import condor.gahp.gsi.GSIUtils;

import org.globus.ogsa.impl.base.gram.client.*;
import org.globus.ogsa.impl.security.authentication.Constants;
import org.globus.ogsa.impl.security.authorization.Authorization;
import org.globus.ogsa.impl.security.authorization.SelfAuthorization;
import org.globus.ogsa.base.gram.types.JobStateType;

import org.globus.ogsa.base.gram.service.ManagedJobServiceGridLocator;
import org.globus.ogsa.impl.security.authorization.SelfAuthorization;
import org.gridforum.ogsi.GridService;
import org.globus.ogsa.impl.base.gram.client.GramRsl2XmlConverter;
import org.globus.rsl.ParseException;
import org.gridforum.ogsi.GridService;
import org.gridforum.ogsi.OGSIServiceLocator;
import org.globus.ogsa.handlers.GrimProxyPolicyHandler;
import org.globus.ogsa.impl.security.authentication.Constants;
import org.globus.ogsa.utils.AnyHelper;
import org.gridforum.ogsi.ExtensibilityType;
import org.globus.ogsa.types.properties.PropertiesDetailType;
import org.gridforum.ogsi.EntryType;
import org.globus.ogsa.base.gram.service.ManagedJobServiceLocator;
import org.gridforum.ogsi.EntryContentType;
import org.gridforum.ogsi.ServiceDataValuesType;
import org.gridforum.ogsi.Factory;
import org.globus.ogsa.utils.QueryHelper;
import org.globus.ogsa.impl.security.authorization.Authorization;
import org.globus.ogsa.ServiceData;
import org.gridforum.ogsi.TerminationTimeType;
import org.gridforum.ogsi.ExtendedDateTimeType;
import org.globus.ogsa.base.gram.ManagedJobPortType;
import org.gridforum.ogsi.LocatorType;
import org.globus.ogsa.utils.GridServiceFactory;
import org.globus.ogsa.impl.base.gram.utils.rsl.RslParser;
import org.globus.ogsa.impl.base.gram.utils.rsl.RslParseException;
import org.globus.ogsa.impl.base.gram.utils.rsl.RslParserFactory;
import org.globus.ogsa.base.gram.types.JobStatusType;
import org.globus.axis.gsi.GSIConstants;
import org.globus.ogsa.base.gram.types.JobStateType;
import org.w3c.dom.Element;
import javax.xml.namespace.QName;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;
import org.gridforum.jgss.ExtendedGSSManager;
import org.gridforum.ogsi.HandleType;
import javax.xml.rpc.Stub;
import java.net.URL;

public class Gt3GramJobStatusHandler implements CommandHandler {

    private GahpInterface gahp;

    public void setGahp (GahpInterface gahp) {
        this.gahp = gahp;
    }

    public CommandHandlerResponse handleCommand (String[] cmd) {
        Integer reqId = null;
        String contactString = null;

        try {
            // cmd[0] = GRAM_JOB_REQUEST
            reqId = new Integer(cmd[1]);
            contactString = cmd[2];
        }
        catch (Exception e) {
            e.printStackTrace(System.err);
            return CommandHandlerResponse.SYNTAX_ERROR;
        }

        return new CommandHandlerResponse (
            CommandHandlerResponse.SUCCESS,
            new JobStatusRunnable(reqId.intValue(), contactString, gahp) );
    } // handleCommand

    class JobStatusRunnable implements Runnable {
        private int requestId;
        private String gsh;
        private GahpInterface gahp;

        public JobStatusRunnable (int reqId, String gsh, GahpInterface gahp) {
            this.requestId = reqId;
            this.gsh = gsh;
            this.gahp = gahp;
        }

        public void run() {
            // Job status code
            int statusCode = 0;

            try {

                OGSIServiceLocator locator = new OGSIServiceLocator();
                GridService gridService =
                    locator.getGridServicePort(new URL(this.gsh));

                GrimProxyPolicyHandler grimPolicyHandler = new GrimProxyPolicyHandler();
                grimPolicyHandler.reset();

                ((Stub)gridService)._setProperty(Constants.GSI_SEC_CONV, Constants.SIGNATURE);
                ((Stub)gridService)._setProperty(Constants.GRIM_POLICY_HANDLER,grimPolicyHandler);
                ((Stub)gridService)._setProperty(Constants.AUTHORIZATION, SelfAuthorization.getInstance());
                GSSCredential cred = GSIUtils.getCredential (gahp);
                if ( cred != null ) {
                    ((Stub)gridService)._setProperty(GSIConstants.GSI_CREDENTIALS,cred);
                } 

                ExtensibilityType serviceData = gridService.findServiceData(
                                                   QueryHelper.getNamesQuery(
                                                   "ManagedJobState"));

                ServiceDataValuesType serviceDataValues = (ServiceDataValuesType)
                    AnyHelper.getAsServiceDataValues(serviceData);

                if (serviceDataValues == null || serviceDataValues.get_any() == null) {
                    throw new Exception("Query failed!");
                }

                JobStatusType jobStatus = (JobStatusType)AnyHelper.
                    getAsSingleObject(serviceDataValues, JobStatusType.class);

                JobStateType jobState = jobStatus.getJobState();

                if (jobState.equals(JobStateType.Failed)) {
                    statusCode = 4;
                } else if (jobState.equals(JobStateType.Done)) {
                    statusCode = 8;
                } else if (jobState.equals(JobStateType.Pending)) {
                    statusCode = 1;
                } else if (jobState.equals(JobStateType.Active)) {
                    statusCode = 2;
                } else if (jobState.equals(JobStateType.Suspended)) {
                    statusCode = 16;
                } else if (jobState.equals(JobStateType.StageIn)) {
                    statusCode = 64;
                } else if (jobState.equals(JobStateType.StageOut)) {
                    statusCode = 128;
                } else if (jobState.toString().equals("Unsubmitted")) {
                    statusCode = 32;
                } else {
                    System.err.println("Job state: ???");
                }

            } catch (Exception e) {
                System.err.println("status failed: ");
                e.printStackTrace(System.err);
                // TODO: Improve this shit
                String errorMessage = (e.getMessage()==null)?"unknown":e.getMessage();
                String [] result = {
                    ""+1, //result code
                    ""+0,
                    errorMessage}; // job state
                gahp.addResult (requestId, result); 
                return;
            }

            String[] result = 
                { "0", // result code
                  ""+statusCode, // jobState
                  "NULL" // error message
            };

            gahp.addResult (requestId, result);

        }
    }
} // GRAM_JOB_STATUS_Handler
