/********************************************************************************
 *                                                                              *
 *  COPYRIGHT (C) 1997-2003 FUJITSU SOFTWARE CORPORATION.  ALL RIGHTS RESERVED. *
 *                                                                              *
 ********************************************************************************/

package com.fujitsu.iflowqa.testframe;

import com.fujitsu.iflow.model.workflow.Filter;
import com.fujitsu.iflow.model.workflow.ProcessInstance;
import com.fujitsu.iflow.model.workflow.ProcessInstantiator;
import com.fujitsu.iflow.model.workflow.WFObjectFactory;
import com.fujitsu.iflow.model.workflow.WFObjectList;
import com.fujitsu.iflow.model.workflow.WorkItem;

/*
 * This will Test The group workitem.
 */

public class TestGroupWI extends BPMTestBase
{
    private static final String TEST_TEMPLATE  = "TestGroupWI.xpdl";
    private static final String optName = "SupportGroupWorkItem";

    public TestGroupWI()
    {
    }

    public
    void
    runTests(TestRecorder ntr)
    throws Exception
    {
        try {
            tr = ntr;
            init(tr);
            login();
            String optn = wfSession.getServerOption(optName);
            if(!Boolean.valueOf(optn).booleanValue())
            {
               tr.log("The server option " + optName + " is not set in Server Property. Exiting the test.");
               return;
            }
            String[] names = {TEST_TEMPLATE};
            long[] planIds = importTemplates(tr.getTestDir(), names);

            //Start Process
            ProcessInstantiator pins = WFObjectFactory.getProcessInstantiator(planIds[0], wfSession);
            ProcessInstance pi = pins.startNewProcess();
            waitForActionToComplete("after startNewProcess");
            testAccept(pi.getId());

            //Start Process
            pins = WFObjectFactory.getProcessInstantiator(planIds[0], wfSession);
            pi = pins.startNewProcess();
            waitForActionToComplete("after startNewProcess 2");
            this.testMakeChoice(pi.getId());
        }
        catch (Exception e) {
            e.printStackTrace();
            tr.log("TestGroupWI caught exception: ") ;
            throw e ;
        }
        finally
        {
           close();
        }
    }

    // DO NOT USE THIS
    // A test should never wait "blindly" for a period of time
    // If you design a test to do this, then undoubtably there will
    // be a machine or environment that the wait is not long enough.
    // Your test will be brittle and sensitive to the test environment
    // and therefor be flakey.  Just don't do this!!!!!
    private
    void
    waitForActionToComplete(String msg)
    {
        try {
            tr.log("Waiting 500ms for '"+msg+"' (improperly) should change this test to use SafeSleep");
            Thread.sleep(500);
        }
        catch(Exception e)
        {
            //Interupted  Exception
        }
    }

    public void
    testAccept(long piId)throws Exception
    {
        WFObjectList wfol = WFObjectFactory.getWFObjectList(wfSession);
        wfol.addFilter(WFObjectList.LISTFIELD_PROCESSINSTANCE_ID, "=",
                "'" + piId + "'");
        wfol.openBatchedList(Filter.AllWorkItems);
        Object[] workItemList = wfol.getNextBatch(0, 99);
        testAndReport("Number of Workitem.",workItemList.length, 1);

        if(workItemList.length == 1)
        {
            WorkItem wi = (WorkItem)workItemList[0];
            testAndReport("Workitem Responsible.",wi.getAssignee(), "Role");
            wi.accept();
            waitForActionToComplete("Workitem Responsible After Accept 1");
            testAndReport("Workitem Responsible After Accept.",wi.getAssignee(), wfSession.getUserName());
            waitForActionToComplete("Workitem Responsible After Accept 2");

            String[] wiChoices = wi.getChoices();
            wi.makeChoice(wiChoices[0]);
            waitForActionToComplete("after makeChoice");
            ProcessInstance pi = WFObjectFactory.getProcessInstance(piId, wfSession);
            testAndReport("Process State.",pi.getState(), ProcessInstance.STATE_CLOSED);
        }

    }

    public void
    testMakeChoice(long piId)throws Exception
    {
        WFObjectList wfol = WFObjectFactory.getWFObjectList(wfSession);
        wfol.addFilter(WFObjectList.LISTFIELD_PROCESSINSTANCE_ID, "=",
                "'" + piId + "'");
        wfol.openBatchedList(Filter.AllWorkItems);
        Object[] workItemList = wfol.getNextBatch(0, 99);
        testAndReport("Number of Workitem.",workItemList.length, 1);

        if(workItemList.length == 1)
        {
            WorkItem wi = (WorkItem)workItemList[0];
            testAndReport("Workitem Responsible.",wi.getAssignee(), "Role");
            String[] wiChoices = wi.getChoices();
            wi.makeChoice(wiChoices[0]);
            waitForActionToComplete("after makeChoice 2");
            ProcessInstance pi = WFObjectFactory.getProcessInstance(piId, wfSession);
            testAndReport("Process State.",pi.getState(), ProcessInstance.STATE_CLOSED);
        }

    }

    /**
     *
     * @param args
     */
    public static void main(String[] args)
    {
        String[] newArgs = new String[1];
        newArgs[0] = "com.fujitsu.iflowqa.testframe.TestGroupWI";
        TestDriver.main(newArgs);
    }
}