package com.fujitsu.iflowqa.testframe;

import java.awt.Point;

import com.fujitsu.iflow.model.workflow.AttachmentRef;
import com.fujitsu.iflow.model.workflow.Node;
import com.fujitsu.iflow.model.workflow.Plan;
import com.fujitsu.iflow.model.workflow.PlanVersionHistoryElement;
import com.fujitsu.iflow.model.workflow.ProcessInstance;
import com.fujitsu.iflow.model.workflow.WFObjectFactory;

/**
 *  Test to add the attachment to the process. It creates a dummy paln and process and attaches the attachment
 *  defined in the test.conf file "attachmentname" and specified at the location "attachmentpath".
 *  It retrieves the attachment from the process and valiadtes it against the "attachmentname".
*/

public class TestProcessAttachment extends BPMTestBase
{

    private String role = "Role";
    private String ATTACHMSG = "ProcessAttachment Test -- Validating Process Attachment: ";
    private String BEFORESTART_ATTACHNAME = "Test_B4StartProcAttachment";
    private String AFTERSTART_ATTACHNAME = "Test_AfterStartProcAttachment";
    private String ATTACHPATH = "";

    public
    void
    runTests(TestRecorder trin)
    throws Exception
    {
        try {
            init(trin);
            ATTACHPATH = tr.getRequiredProperty("attachmentpath");
            if(ATTACHPATH.length() == 0)
                throw new Exception("ProcessAttachment Test -- Retrieving attachmentpath Failed, Please provide the valid 'attachmentpath' property value in test.conf file");
            login();
            Plan testPlan = createTemplate();

            ProcessInstance pi = createProcess(testPlan);

            // after starting a process
            addAttachment(pi,AFTERSTART_ATTACHNAME,ATTACHPATH);
            validateProcAttach(pi,AFTERSTART_ATTACHNAME);
            logOut();
        }
        catch (Exception e)
        {
            logAndRethrow("Exception caught in main test level", e);
        }
    }

    public
    TestProcessAttachment()
    {

    }

    public
    Plan
    createTemplate()
        throws Exception
    {
        Plan plan = null;

        try {
            String planName = "QA_TestAttachmentPlan_20040503";
            PlanVersionHistoryElement[] planVersion = wfSession.getPlanVersionHistory(planName);
            if(planVersion.length > 0)
            {
                // always return a preant plan Id
                long planId = planVersion[0].getPlanId();
                return WFObjectFactory.getPlan(planId,wfSession);
            }
            plan = WFObjectFactory.getPlan();
            plan.setWFSession(wfSession);
            plan.startEdit();

            plan.setName( planName );
            plan.setTitle( planName + " title" );
            plan.setDesc( planName + " description" );
            plan.setPlanIdentifier("Global");

            Node startNode = plan.addNode( "Start", Node.TYPE_START );
            int startX = 50;
            int startY = 100;
            startNode.setPosition( new Point( startX, startY ) );

            Node firstActNode = plan.addNode( "ACTIVITY-ATTACHMENT", Node.TYPE_ACTIVITY );
            firstActNode.setPosition( new Point( startX + 200, startY ) );
            firstActNode.setRole(role);
            firstActNode.setDesc("ACTIVITY-ATTACHMENT");
            startNode.addArrow( "START", firstActNode );

            Node exitNode = plan.addNode( "EXIT", Node.TYPE_EXIT );
            exitNode.setPosition( new Point( startX + 200, startY + 200) );
            firstActNode.addArrow( "DONE", exitNode );
            plan = plan.createProcessDef();
            Thread.sleep(2000);
        }
        catch (Exception e) {
            logAndRethrow("ProcessAttachment Test -- Plan creation failed", e);
        }
        return plan;
    }

    private
    void
    addAttachment(ProcessInstance procInst, String attachName, String attachPath)
        throws Exception
    {
        try {
            // enactment edit begins
            procInst.startEdit();
            procInst.addAttachment(attachName,attachPath);
            // enactment edit ends
            procInst.commitEdit();
            if(attachName.equals(BEFORESTART_ATTACHNAME))
                testAndReport("ProcessAttachment Test -- Successfully added Attachment to a Process before starting it.",attachName,BEFORESTART_ATTACHNAME);
            if(attachName.equals(AFTERSTART_ATTACHNAME))
                testAndReport("ProcessAttachment Test -- Successfully added Attachment to a Process after starting it.",attachName,AFTERSTART_ATTACHNAME);
        } catch (Exception e) {
            logAndRethrow("ProcessAttachment Test -- Adding Attachemnt to a Process failed", e);
        }
    }

    public
    void
    validateProcAttach(ProcessInstance procInst, String attachName)
        throws Exception
    {
        try
        {
            AttachmentRef attachRef = procInst.getAttachment(attachName);
            if(attachRef != null)
            {
                String attachPath = attachRef.getPath();
                testAndReport(ATTACHMSG + attachName,attachPath,ATTACHPATH);
            }
            else
                testAndReport(ATTACHMSG + attachName,"",ATTACHPATH);
        }
        catch(Exception e)
        {
            logAndRethrow("ProcessAttachment Test -- To retrieve Attachment from Process", e);
        }
    }

    public
    void
    logAndRethrow(
        String message,
        Exception e)
            throws Exception
    {
        tr.log(message);
        throw new ExceptionWrapper(message, 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.TestProcessAttachment";
        TestDriver.main(newArgs);
    }
}

