package org.projectapollo.demo.Jobs.LaunchJob;

import
apollo.*;
import apollo.Template.*;
import apollo.Storable.*;
import apollo.Job.*;

import
org.projectapollo.demo.*;
import org.projectapollo.demo.Jobs.*;
import org.projectapollo.demo.Storable.*;

import
java.util.*;
import java.lang.Thread;

import
apollo.Session.*;

public
class LaunchJobBroker extends PageBroker {
    private AcceptClause displayEntry;
    private AcceptClause launchJob;
    private Vector AS;
    public LaunchJobBroker(ManagerTracker MT,String fquid,PageBroker PB) throws TemplatePageException {
        super(MT,fquid,PB);
        MT.getPM().registerTemplatePage(FQUID,
new TemplatePage(MT,this,false));
        MT.getPM().registerTemplatePage(FQUID+
".Dispatched", new TemplatePage(MT,this,"dispatched.html"));
        displayEntry=
new AcceptClause("DisplayEntry");
        launchJob =
new AcceptClause("LaunchJob");
        launchJob.addAcceptClause(AcceptClause.STRING,
"StartJob", AcceptClause.REQUIRED);
        launchJob.addAcceptClause(AcceptClause.INT,
"JobType", AcceptClause.REQUIRED);
        launchJob.addAcceptClause(AcceptClause.INT,
"PauseTime", AcceptClause.REQUIRED);
        launchJob.addAcceptClause(AcceptClause.INT,
"Format", AcceptClause.REQUIRED);
        launchJob.addAcceptClause(AcceptClause.BOOLEAN,
"Foreground", AcceptClause.OPTIONAL);
        launchJob.addAcceptClause(AcceptClause.BOOLEAN,
"Crash", AcceptClause.OPTIONAL);
        AS =
new Vector();
        AS.addElement(launchJob);
        AS.addElement(displayEntry);
    }
 
    public HTTPResponse render(TransactionTracker TT, HTTPRequest req, WebSession thisSession) throws ApolloException {
        EntryAssertionManager EAM =
new EntryAssertionManager(MT, AS);
        EAM.evaluate(req);
        User user = (User) thisSession.getValue(
"User");
        Hashtable RT =
new Hashtable();
        if (EAM.isAccept(launchJob)) {
             //Check for already running jobs, because my computer is a P166 and she can't take too many
            //random number threads ;)
            // (But in the real world, having more then one job running is okay)
            /* This obviously could have been done much better. Especially though the use
            of the session. However we'll look in the database so you can see what nested
            db statements look like, and we used some NOT_EQUALS and ORs in here too
            This would evaluate in SQL to something like:
            select count(*) from [JobMembership], [JobRecord] where [JobMembership].userID=='username' AND
            [JobMembership].jobID==[JobRecord].jobID AND (JobRecord.statusID!=3 OR JobRecord.statusID!=4);
            */
             WhereQuery wq = new WhereQuery();
            wq.insertWhereClause(WhereQuery.AND,
"userID", JobMembership.class, user.getUserID());
            wq.insertWhereClause(WhereQuery.AND,
"jobID", JobMembership.class, "jobID", JobRecord.class);
            wq.insertWhereClause(WhereQuery.AND,
"statusID", JobRecord.class, new Integer(JobManager.JOB_FINISHED), WhereQuery.NOT_EQUAL);
            wq.insertWhereClause(WhereQuery.AND,
"statusID", JobRecord.class, new Integer(JobManager.JOB_FAILED), WhereQuery.NOT_EQUAL);
            Integer countOfRunningJobs = (Integer) JobRecord.loadFunction(MT,
new StorableFunction(Storable.COUNT), wq);
            if (!countOfRunningJobs.equals(new Integer(0))) {
                RT.put(
"JSMessage", "You already have a job running");
                RT.put(
"JSAlert", new Boolean(true));
            }
else {
                Job job;
                if (EAM.getInt("JobType")==1) {
                    job =
new RandomNumbersJob(MT, "Random Numbers Job", user, EAM.getInt("Format"), EAM.getInt("PauseTime"), EAM.getBoolean("Crash"));
                }
else {
                    job =
new LoggedInJob(MT, "Logged In Job", user, EAM.getInt("Format"), EAM.getInt("PauseTime"), EAM.getBoolean("Crash"));
                }
                MT.getJM().startJob(job);
 
                if (EAM.getBoolean("Foreground")) {
                     //Foreground operation
                       HTTPRequest newReq = new HTTPRequest();
                    newReq.setValue(
"JobID", Integer.toString(job.getJobID()));
                    newReq.setValue(
"Foreground", "1");
                    return MT.getPM().handleRequest(TT, "Jobs.StatusBar", newReq, thisSession);
                }
else {
                     //Background operation
 
                    thisSession.put(
"MonitorJobID", new Integer(job.getJobID()));
                    RT.put(
"JobID", new Integer(job.getJobID()));
                    return MT.getPM().getPage(FQUID+".Dispatched").render(RT,thisSession);
                }
            }
        }
 
   return MT.getPM().getPage(FQUID).render(RT,thisSession);
    }
}