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

package com.fujitsu.iflowqa.testframe;

import com.fujitsu.iflow.model.workflow.DataItem;
import com.fujitsu.iflow.model.workflow.NodeInstance;
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.WorkItem;

/*
 * This will Test The Activate/Deactivate of various node without any structural edit.
 */

public class TestNodeActivateDeactivate  extends BPMTestBase
{

    public TestNodeActivateDeactivate()
    {
    }

    public
    void
    runTests(TestRecorder ntr)
    throws Exception
    {
        try {
            tr = ntr;
            tr.log("TestNodeActivateDeactivate test point number 1");
            init(tr);
            tr.log("TestNodeActivateDeactivate test point number 2");
            login();
            String[] names = {"TestNodeActivateDeactivate.xpdl"};
            long[] planIds = importTemplates(tr.getTestDir(), names);
            waitForActionToComplete("after import");

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

            while(true){
                NodeInstance ni1 = getNodeInstance("Activity1", pi.getId());
                if(ni1.getState() == NodeInstance.STATE_RUNNING)
                {
                    ni1.reset();
                    break;
                }
                else
                {
                    waitForActionToComplete("in while loof for RUNNING");
                }
            }

            while(true){
                NodeInstance ni2 = getNodeInstance("Activity2", pi.getId());
                if(ni2.getState() == NodeInstance.STATE_RUNNING)
                {
                   makeChoiceOnWI(ni2.getNodeInstanceId());
                   break;
                }
                else
                {
                    waitForActionToComplete("in while loop for Activity2");
                }
            }
            NodeInstance ni1 = getNodeInstance("Activity1", pi.getId());
            testAndReport("DeActivate Regular node(Activity1) " ,ni1.getState(),  NodeInstance.STATE_COMPLETED);

            while(true)
            {
                NodeInstance niAnd = getNodeInstance("And Name19", pi.getId());
                if(niAnd.getState() == NodeInstance.STATE_RUNNING)
                {
                   niAnd.reset();
                   break;
                }
                else
                {
                    waitForActionToComplete("in While loop for Name19");
                }
            }
            NodeInstance niAnd = getNodeInstance("And Name19", pi.getId());
            testAndReport("DeActivate And node(And Name19) " , niAnd.getState(),  NodeInstance.STATE_COMPLETED);

            NodeInstance niAct1 = getNodeInstance("Activity1", pi.getId());
            niAct1.activate();
            testAndReport("Activate Regular node(Activity1) " , niAct1.getState(),  NodeInstance.STATE_RUNNING);

            //Activate or node
            NodeInstance niOr = getNodeInstance("Or Name17", pi.getId());
            niOr.activate();
            DataItem dit = pi.getDataItem("orNodeCounter");
            int cntr = Integer.parseInt(dit.getValue());
            testAndReport("Activate Or node(Or Name17) value of dataItem orNodeCounter " , cntr,  2);

        }
         catch (Exception e) {
            e.printStackTrace();
            tr.log("TestNodeActivateDeactivate caught exception: ") ;
            throw e ;
        }
        finally
        {
           close();
        }
    }

    private
    NodeInstance
    getNodeInstance(String nodeName, long piId)throws Exception
    {
        ProcessInstance pi = WFObjectFactory.getProcessInstance(piId, wfSession);
        NodeInstance[] nia = pi.getMemberNodeInstances();
        for(int i=0; i<nia.length; i++)
        {
            NodeInstance ni = nia[i];
            if(ni.getName().equals(nodeName))
            {
                return ni;
            }
        }

        return null;
    }

    private
    void
    makeChoiceOnWI(long niId)throws Exception
    {
        WorkItem wi = WFObjectFactory.getWorkItem(wfSession.getUserName(), niId, wfSession);
        String[] choices = wi.getChoices();
        wi.makeChoice(choices[0]);
    }

    // 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)
        {
            tr.log("Got exception waiting 500ms (improperly) should change this test to use SafeSleep:"+e);
        }
    }

     /**
    * TestDriver is the class that knows how to run these tests.
    * So just call it with the name of this class in there.
    */
    public
    static
    void
    main(String[] args)
    {
        String[] newArgs = new String[1];
        newArgs[0] = "com.fujitsu.iflowqa.testframe.TestNodeActivateDeactivate";
        TestDriver.main(newArgs);
    }
}