package wenrgise.workflow.impl;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.logging.Logger;
import javax.ejb.CreateException;
import wenrgise.common.exception.EnrgiseApplicationException;
import wenrgise.common.exception.EnrgiseSystemException;
import wenrgise.common.utility.EnrgiseUtil;
import wenrgise.common.utility.UserInfo;
import wenrgise.workflow.bean.WflDocMstAttrDtlBean;
import wenrgise.workflow.bean.WflDtlDocTypeDtlBean;
import wenrgise.workflow.core.WflDocumentInfo;
import wenrgise.workflow.core.WflResource;
import wenrgise.workflow.core.WflStatus;
import wenrgise.workflow.core.WorkFlow;
import wenrgise.workflow.core.impl.WflStatusImpl;
import wenrgise.workflow.ejb.business.WflDocMstBO;
import wenrgise.workflow.ejb.business.WorkFlowCommonBO;
import wenrgise.workflow.exception.AtributesNotDefinedException;
import wenrgise.workflow.utility.AttributesHandler;
import wenrgise.workflow.utility.ConditionChecker;
import wenrgise.workflow.utility.Node;
import wenrgise.workflow.utility.RouteHandler;
import wenrgise.workflow.utility.WorkFlowUtil;

public class WorkFlowImpl implements WorkFlow {
  public static final Logger log = Logger.getLogger("wenrgise.workflow.impl.LeaveWorkFlow");
  
  public boolean canDo(WflDocumentInfo wflDocInfo) throws EnrgiseApplicationException, EnrgiseSystemException {
    if (EnrgiseUtil.checkString(wflDocInfo.getInitiatedFlag()))
      if (!wflDocInfo.getInitiatedFlag().equalsIgnoreCase("Initiated"))
        if (!EnrgiseUtil.checkString(wflDocInfo.getWorkListId()))
          return false;   
    return true;
  }
  
  public WflStatus start(WflDocumentInfo wflDocInfo) {
    try {
      log.severe("Log Started");
      log.severe(String.valueOf("Creator ").concat(String.valueOf(wflDocInfo.getCreator().getEmployeeId())));
      log.severe(String.valueOf("Document Id ").concat(String.valueOf(wflDocInfo.getDocumentId())));
      log.severe(String.valueOf("Document Number ").concat(String.valueOf(wflDocInfo.getDocumentNumber())));
      log.severe(String.valueOf("Document Number ").concat(String.valueOf(wflDocInfo.getDocumentNumber())));
      log.severe(String.valueOf(" Requester Id ").concat(String.valueOf(wflDocInfo.getRequester().getEmployeeId())));
      log.severe("start1");
      RouteHandler routeHandl = new RouteHandler();
      log.severe("start2");
      UserInfo oUserInfo = new UserInfo();
      oUserInfo.setUserId(wflDocInfo.getRequester().getUserId());
      oUserInfo.setSiteId(wflDocInfo.getRequester().getLoginSite().getSiteId());
      oUserInfo.setUserSystemId(wflDocInfo.getRequester().getEmployeeId());
      oUserInfo.setSiteName(wflDocInfo.getRequester().getLoginSite().getSiteName());
      log.severe("start3");
      String activityCode = WorkFlowUtil.getActivityCode(wflDocInfo.getRequesterAction());
      log.severe("start4");
      log.severe(String.valueOf("The WorkList Id Is:-").concat(String.valueOf(wflDocInfo.getWorkListId())));
      log.severe(String.valueOf("The InitiatedFlag Is:-").concat(String.valueOf(wflDocInfo.getInitiatedFlag())));
      if (EnrgiseUtil.checkString(wflDocInfo.getInitiatedFlag())) {
        if (wflDocInfo.getInitiatedFlag().equalsIgnoreCase("Initiated")) {
          log.severe("start5");
          AttributesHandler attrChecker = new AttributesHandler();
          if (!attrChecker.checkAttributes(wflDocInfo, oUserInfo))
            throw new AtributesNotDefinedException(); 
          log.severe("Checking Condition");
          ConditionChecker cc = new ConditionChecker();
          ArrayList oList = WorkFlowUtil.getDetailDocs(wflDocInfo.getDocumentTypeId(), oUserInfo);
          WflDocMstBO oWflDocMstBO = new WflDocMstBO();
          oWflDocMstBO.setOUserInfo(oUserInfo);
          long oDocAttrCount = oWflDocMstBO.getWflDocTypeAttrDtlMetaInfo(wflDocInfo.getDocumentTypeId()).getRecordCount();
          ArrayList arylstDocType = oWflDocMstBO.getWflDocTypeAttrDtlInfo(wflDocInfo.getDocumentTypeId(), 1L, oDocAttrCount);
          Iterator oIt1 = arylstDocType.iterator();
          HashMap oDocAttrTypeMap = new HashMap();
          while (oIt1.hasNext()) {
            WflDocMstAttrDtlBean oWflDocMstAttrDtlBean = oIt1.next();
            oDocAttrTypeMap.put(oWflDocMstAttrDtlBean.getTxtAttrName(), oWflDocMstAttrDtlBean.getTxtType());
          } 
          String dtlDocId = null;
          Iterator iterator = oList.iterator();
          while (iterator.hasNext()) {
            WflDtlDocTypeDtlBean oWflDtlDocTypeDtlBean = iterator.next();
            if (cc.checkCondition(oWflDtlDocTypeDtlBean.getTxtExp(), wflDocInfo.getDocumentAttributes(), oDocAttrTypeMap) > false) {
              dtlDocId = oWflDtlDocTypeDtlBean.getDetailId();
              break;
            } 
          } 
          log.severe("Checking Condition Finished");
          if (dtlDocId == null)
            throw new EnrgiseApplicationException("wenrgise.PumMaintainPI.header.UniqueKeyConstraint", "E"); 
          Node node = new Node(String.valueOf(1), String.valueOf(0));
          routeHandl.setNodeInfo(node);
          WorkFlowCommonBO oWorkFlowCommonBO = new WorkFlowCommonBO();
          routeHandl.setActivityId(wflDocInfo.getRequesterAction());
          routeHandl.setDtlDocId(dtlDocId);
          routeHandl.populateData();
        } 
      } else {
        log.severe("Not Initiated");
        routeHandl.setRouteDtlId(WorkFlowUtil.getRouteDtlId(wflDocInfo));
        routeHandl.populateData();
      } 
      wflDocInfo.getCreator().setRouteDtlId(routeHandl.getRouteDtlId());
      if (!EnrgiseUtil.checkString(wflDocInfo.getInitiatedFlag()))
        WorkFlowUtil.updateWorkList("U", wflDocInfo.getRequester(), wflDocInfo); 
      log.severe("start6");
      WflStatusImpl wflStatusImpl = new WflStatusImpl();
      ArrayList oNextApprover = routeHandl.findNextApprover(wflDocInfo);
      log.severe("start7");
      Iterator oIt = oNextApprover.iterator();
      boolean notifFlagForFinalAppr = false;
      if (oIt.hasNext()) {
        while (oIt.hasNext()) {
          WflResource wflResource = oIt.next();
          log.severe(String.valueOf("Approver ").concat(String.valueOf(wflResource.getEmployeeId())));
          if (null != wflResource) {
            log.severe("start8");
            WorkFlowUtil.updateWorkList("N", wflResource, wflDocInfo);
            if (routeHandl.getNotifFlag().equalsIgnoreCase("Y")) {
              wflStatusImpl.setStatus("Notification");
              continue;
            } 
            wflStatusImpl.assign(wflResource);
            wflStatusImpl.setStatus("Pending");
            log.severe("start9");
          } 
        } 
      } else if (activityCode.equalsIgnoreCase("Reject")) {
        wflStatusImpl.setStatus("Rejected");
      } else {
        wflStatusImpl.setStatus("FinallyApproved");
      } 
      if (activityCode.equalsIgnoreCase("Reject"))
        wflStatusImpl.setStatus("Rejected"); 
      log.severe("start10");
      System.out.println(String.valueOf("The Status is:").concat(String.valueOf(wflStatusImpl.getStatus())));
      System.out.println(String.valueOf("The Error Code is:").concat(String.valueOf(wflStatusImpl.getErrCode())));
      System.out.println(String.valueOf("The Error Message is:").concat(String.valueOf(wflStatusImpl.getErrMsg())));
      return (WflStatus)wflStatusImpl;
    } catch (EnrgiseSystemException oSx) {
      log.severe(String.valueOf(String.valueOf(oSx.getClass().getName()).concat(String.valueOf(" "))).concat(String.valueOf(oSx.getMessage())));
      return null;
    } catch (EnrgiseApplicationException oAx) {
      log.severe(String.valueOf(String.valueOf(oAx.getClass().getName()).concat(String.valueOf(" "))).concat(String.valueOf(oAx.getMessage())));
      return null;
    } catch (CreateException oCx) {
      log.severe(String.valueOf(String.valueOf(oCx.getClass().getName()).concat(String.valueOf(" "))).concat(String.valueOf(oCx.getMessage())));
      return null;
    } catch (RemoteException oRx) {
      log.severe(String.valueOf(String.valueOf(oRx.getClass().getName()).concat(String.valueOf(" "))).concat(String.valueOf(oRx.getMessage())));
      return null;
    } catch (Exception oEx) {
      log.severe(String.valueOf(String.valueOf(oEx.getClass().getName()).concat(String.valueOf(" "))).concat(String.valueOf(oEx.getMessage())));
      return null;
    } 
  }
}
