package wenrgise.ejb.common.business;

import java.rmi.RemoteException;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
import java.util.logging.Logger;
import javax.ejb.CreateException;
import wenrgise.common.bean.BaseHeaderBean;
import wenrgise.common.exception.EnrgiseApplicationException;
import wenrgise.common.exception.EnrgiseMessageKeyException;
import wenrgise.common.exception.EnrgiseSystemException;
import wenrgise.common.utility.EnrgiseUtil;
import wenrgise.common.utility.UserInfo;
import wenrgise.ejb.common.helper.DBObject;
import wenrgise.ejb.common.session.UserSession;
import wenrgise.ejb.common.session.UserSessionHome;
import wenrgise.ejb.common.utility.DBUtilitiesBean;
import wenrgise.ejb.common.utility.ServiceLocator;

public abstract class BaseBO {
  public static Logger log = Logger.getLogger("wenrgise.ejb.common.business.BaseBO");
  
  protected String headerTable = null;
  
  private String headerPKColumnName = null;
  
  private String detailTable = null;
  
  private String detailPKColumnName = null;
  
  protected DateFormat userDateFormat;
  
  protected DateFormat defaultDateFormat;
  
  protected Locale userLocale;
  
  protected Locale defaultLocale;
  
  protected UserInfo oUserInfo;
  
  public BaseBO() {}
  
  public BaseBO(UserInfo oUserInfo) {
    this.oUserInfo = oUserInfo;
  }
  
  private void setDateFormatAndLocale() throws EnrgiseSystemException {
    this.userDateFormat = new SimpleDateFormat("dd/MM/yyyy");
    this.defaultDateFormat = new SimpleDateFormat("dd/MM/yyyy");
    try {
      UserSessionHome oHome = (UserSessionHome)ServiceLocator.getLocator().getService("UserSession");
      UserSession oUser = oHome.create();
      this.userDateFormat = oUser.getUserDateFormat();
      this.defaultDateFormat = oUser.getDefaultDateFormat();
      this.userLocale = oUser.getUserLocale();
      this.defaultLocale = oUser.getDefaultLocale();
      this.oUserInfo = oUser.getUserInfo();
    } catch (RemoteException oEx) {
      log.severe(oEx.getMessage());
      throw new EnrgiseSystemException();
    } catch (CreateException oCrt) {
      log.severe(oCrt.getMessage());
      throw new EnrgiseSystemException();
    } 
  }
  
  public String saveData(BaseHeaderBean oBaseHeaderBean, Timestamp oWhenPicked, String sScreenName, String sScreenMode, boolean bHeaderDataChanged, ArrayList oDetailBeanArray, boolean bDetailDataChanged, Timestamp oDetailPicked) throws EnrgiseApplicationException, EnrgiseSystemException {
    String sScreenHeaderPrimaryKey = (null != oBaseHeaderBean) ? oBaseHeaderBean.getHeaderPrimaryKey() : "";
    String sHeaderPrimaryKey = sScreenHeaderPrimaryKey;
    if (sScreenMode.equals("U"))
      initializeBOImpl(); 
    if (sScreenMode.equals("U"))
      if (bHeaderDataChanged || bDetailDataChanged)
        if (oWhenPicked != null) {
          if (!checkHeaderTimeStamp(oBaseHeaderBean.getHeaderPrimaryKey(), oDetailPicked))
            throw new EnrgiseApplicationException("wenrgise.common.changed", "M"); 
        } else if (!checkHeaderTimeStamp(null, oDetailPicked)) {
          throw new EnrgiseApplicationException("wenrgise.common.changed", "M");
        }   
    additionalFieldValidationImpl(oBaseHeaderBean, oWhenPicked, sScreenName, sScreenMode, bHeaderDataChanged, oDetailBeanArray, bDetailDataChanged, oDetailPicked);
    additionalTimestampValidationImpl(oBaseHeaderBean, oWhenPicked, sScreenName, sScreenMode, bHeaderDataChanged, oDetailBeanArray, bDetailDataChanged, oDetailPicked);
    additionalBusinessValidationImpl(oBaseHeaderBean, oWhenPicked, sScreenName, sScreenMode, bHeaderDataChanged, oDetailBeanArray, bDetailDataChanged, oDetailPicked);
    if (bHeaderDataChanged) {
      sHeaderPrimaryKey = saveHeaderImpl(oBaseHeaderBean, sScreenMode);
      if (sHeaderPrimaryKey == null && !sScreenMode.equalsIgnoreCase("D"))
        sHeaderPrimaryKey = sScreenHeaderPrimaryKey; 
    } 
    if (bDetailDataChanged && !sScreenMode.equalsIgnoreCase("D"))
      if (oBaseHeaderBean == null) {
        saveDetailImpl(sHeaderPrimaryKey, sScreenName, oDetailBeanArray);
        if (oWhenPicked != null)
          updateHeaderTimeStamp(sHeaderPrimaryKey); 
      } else if (!EnrgiseUtil.checkString(oBaseHeaderBean.getPseudoHeader())) {
        saveDetailImpl(sHeaderPrimaryKey, sScreenName, oDetailBeanArray);
        if (oWhenPicked != null)
          updateHeaderTimeStamp(sHeaderPrimaryKey); 
      } else {
        saveDetailImpl(oBaseHeaderBean, sScreenName, oDetailBeanArray);
      }  
    return sHeaderPrimaryKey;
  }
  
  private boolean updateHeaderTimeStamp(String sPrimaryKey) throws EnrgiseSystemException {
    ArrayList oParameters = new ArrayList();
    DBUtilitiesBean oBean = new DBUtilitiesBean();
    oParameters = new ArrayList();
    oParameters.add(new DBObject(1, 1, 12, this.headerTable));
    oParameters.add(new DBObject(2, 1, 12, sPrimaryKey));
    oParameters.add(new DBObject(3, 2, 12));
    oParameters.add(new DBObject(4, 2, 12));
    oParameters.add(new DBObject(5, 2, 12));
    oParameters.add(new DBObject(6, 2, 4));
    ArrayList oOutArray = oBean.callProc(oParameters, "COMMONPROCEDURES.proc_UpdateHeaderTimeStamp(?,?,?,?,?,?)");
    DBObject oOutObject = oOutArray.get(0);
    String sSuccessFlag = (String)oOutObject.getObject();
    if (!sSuccessFlag.trim().equals("Y"))
      return false; 
    return true;
  }
  
  public void initializeBO(String sHeaderTable, String sDetailTable) {
    this.headerTable = sHeaderTable;
  }
  
  public void initializeBO(String sHeaderTable) {
    this.headerTable = sHeaderTable;
  }
  
  private boolean checkHeaderTimeStamp(String sPrimaryKey, Timestamp oWhenPicked) throws EnrgiseSystemException {
    ArrayList oParameters = new ArrayList();
    DBUtilitiesBean oBean = new DBUtilitiesBean();
    oParameters = new ArrayList();
    oParameters.add(new DBObject(1, 1, 12, this.headerTable));
    oParameters.add(new DBObject(2, 1, 12, sPrimaryKey));
    oParameters.add(new DBObject(3, 1, 93, oWhenPicked));
    oParameters.add(new DBObject(4, 2, 12));
    oParameters.add(new DBObject(5, 2, 12));
    oParameters.add(new DBObject(6, 2, 12));
    oParameters.add(new DBObject(7, 2, 4));
    ArrayList oOutArray = oBean.callProc(oParameters, "COMMONPROCEDURES.proc_CheckHeaderTimeStamp(?,?,?,?,?,?,?)");
    DBObject oOutObject = oOutArray.get(0);
    String sSuccessFlag = (String)oOutObject.getObject();
    if (!sSuccessFlag.trim().equals("Y"))
      return false; 
    return true;
  }
  
  private boolean checkDetailTimeStamp(String sPrimaryKey, Timestamp oWhenDetailPicked) throws EnrgiseSystemException {
    ArrayList oParameters = new ArrayList();
    DBUtilitiesBean oBean = new DBUtilitiesBean();
    oParameters = new ArrayList();
    oParameters.add(new DBObject(1, 1, 12, this.headerTable));
    oParameters.add(new DBObject(2, 1, 12, this.detailTable));
    oParameters.add(new DBObject(3, 1, 12, sPrimaryKey));
    oParameters.add(new DBObject(4, 1, 93, oWhenDetailPicked));
    oParameters.add(new DBObject(5, 2, 12));
    oParameters.add(new DBObject(6, 2, 12));
    oParameters.add(new DBObject(7, 2, 12));
    oParameters.add(new DBObject(8, 2, 4));
    ArrayList oOutArray = oBean.callProc(oParameters, "COMMONPROCEDURES.proc_CheckDetailTimeStamp(?,?,?,?,?,?,?,?)");
    DBObject oOutObject = oOutArray.get(0);
    String sSuccessFlag = (String)oOutObject.getObject();
    if (!sSuccessFlag.trim().equals("Y"))
      return false; 
    return true;
  }
  
  public void reportError(ArrayList oList) throws EnrgiseSystemException, EnrgiseApplicationException {
    if (oList.size() > 0) {
      boolean bFirstTime = true;
      EnrgiseApplicationException oApp = null;
      EnrgiseSystemException oSys = null;
      Object obj = null;
      Iterator oIt = oList.iterator();
      while (oIt.hasNext()) {
        obj = oIt.next();
        if (obj instanceof EnrgiseApplicationException || obj instanceof EnrgiseMessageKeyException) {
          if (!bFirstTime) {
            oApp.addToList((EnrgiseApplicationException)obj);
            continue;
          } 
          bFirstTime = false;
          oApp = (EnrgiseApplicationException)obj;
          continue;
        } 
        oSys = (EnrgiseSystemException)obj;
        throw oSys;
      } 
      throw oApp;
    } 
  }
  
  public abstract String saveHeaderImpl(BaseHeaderBean paramBaseHeaderBean, String paramString) throws EnrgiseMessageKeyException, EnrgiseApplicationException, EnrgiseSystemException;
  
  public abstract void saveDetailImpl(String paramString1, String paramString2, ArrayList paramArrayList) throws EnrgiseApplicationException, EnrgiseSystemException;
  
  public void saveDetailImpl(BaseHeaderBean oBaseHeaderBean, String sScreenName, ArrayList oDetailBeanArray) throws EnrgiseApplicationException, EnrgiseSystemException {}
  
  public abstract void initializeBOImpl();
  
  public abstract void additionalFieldValidationImpl(BaseHeaderBean paramBaseHeaderBean, Timestamp paramTimestamp1, String paramString1, String paramString2, boolean paramBoolean1, ArrayList paramArrayList, boolean paramBoolean2, Timestamp paramTimestamp2) throws EnrgiseApplicationException, EnrgiseSystemException;
  
  public abstract void additionalTimestampValidationImpl(BaseHeaderBean paramBaseHeaderBean, Timestamp paramTimestamp1, String paramString1, String paramString2, boolean paramBoolean1, ArrayList paramArrayList, boolean paramBoolean2, Timestamp paramTimestamp2) throws EnrgiseApplicationException, EnrgiseSystemException;
  
  public abstract void additionalBusinessValidationImpl(BaseHeaderBean paramBaseHeaderBean, Timestamp paramTimestamp1, String paramString1, String paramString2, boolean paramBoolean1, ArrayList paramArrayList, boolean paramBoolean2, Timestamp paramTimestamp2) throws EnrgiseApplicationException, EnrgiseSystemException;
  
  public UserInfo getOUserInfo() {
    return this.oUserInfo;
  }
  
  public void setOUserInfo(UserInfo newOUserInfo) {
    this.oUserInfo = newOUserInfo;
  }
  
  public String approve(String sTableName, BaseHeaderBean oBaseHeaderBean, Timestamp oWhenPicked, ArrayList oDetailBeanArray, Timestamp oDetailPicked) throws EnrgiseApplicationException, EnrgiseSystemException {
    String sHeaderPrimaryKey = (null != oBaseHeaderBean) ? oBaseHeaderBean.getHeaderPrimaryKey() : "";
    initializeBOImpl();
    if (sHeaderPrimaryKey != null) {
      if (oWhenPicked != null && 
        !checkHeaderTimeStamp(sHeaderPrimaryKey, oWhenPicked))
        throw new EnrgiseApplicationException("wenrgise.common.changed", "M"); 
      validateApprove(sHeaderPrimaryKey);
      if (EnrgiseUtil.checkString(sTableName)) {
        DBUtilitiesBean oBean = new DBUtilitiesBean();
        String sQuery = String.valueOf(String.valueOf(String.valueOf(String.valueOf(String.valueOf("update ").concat(String.valueOf(sTableName))).concat(String.valueOf(" set status_flag='"))).concat(String.valueOf("A"))).concat(String.valueOf("',modified_site_id = 100,  user_id_modified = 100,  modified_time_stamp = sysdate  where id="))).concat(String.valueOf(sHeaderPrimaryKey));
        int i = oBean.executeUpsert(sQuery);
      } 
    } else {
      throw new EnrgiseApplicationException("wenrgise.common.norecordfound", "M");
    } 
    return sHeaderPrimaryKey;
  }
  
  public String callWorkFlow(BaseHeaderBean oBaseHeaderBean, ArrayList arylstDetailBeanArray, String activity) throws EnrgiseApplicationException, EnrgiseSystemException {
    if (activity.equals("A"))
      return "FinallyApproved"; 
    if (activity.equals("R"))
      return "R"; 
    return "success";
  }
  
  public void validateApprove(String sHeaderPrimaryKey) {}
  
  public void validateReject(String sHeaderPrimaryKey) {}
  
  public void validateRevise(String sHeaderPrimaryKey) {}
  
  public String submit(String sTableName, BaseHeaderBean oBaseHeaderBean, Timestamp oWhenPicked, ArrayList oDetailBeanArray, Timestamp oDetailPicked) throws EnrgiseApplicationException, EnrgiseSystemException {
    String sHeaderPrimaryKey = (null != oBaseHeaderBean) ? oBaseHeaderBean.getHeaderPrimaryKey() : "";
    initializeBOImpl();
    if (sHeaderPrimaryKey != null)
      if (oWhenPicked != null)
        if (!checkHeaderTimeStamp(sHeaderPrimaryKey, oWhenPicked))
          throw new EnrgiseApplicationException("wenrgise.common.changed", "M");   
    return oBaseHeaderBean.getHeaderPrimaryKey();
  }
  
  public String reject(String sTableName, BaseHeaderBean oBaseHeaderBean, Timestamp oWhenPicked, ArrayList oDetailBeanArray, Timestamp oDetailPicked) throws EnrgiseApplicationException, EnrgiseSystemException {
    String sHeaderPrimaryKey = (null != oBaseHeaderBean) ? oBaseHeaderBean.getHeaderPrimaryKey() : "";
    if (sHeaderPrimaryKey != null) {
      initializeBOImpl();
      if (!checkHeaderTimeStamp(sHeaderPrimaryKey, oWhenPicked))
        throw new EnrgiseApplicationException("wenrgise.common.changed", "M"); 
      validateReject(sHeaderPrimaryKey);
      if (EnrgiseUtil.checkString(sTableName)) {
        DBUtilitiesBean oBean = new DBUtilitiesBean();
        String sQuery = String.valueOf(String.valueOf(String.valueOf(String.valueOf(String.valueOf("update ").concat(String.valueOf(sTableName))).concat(String.valueOf(" set status_flag='"))).concat(String.valueOf("R"))).concat(String.valueOf("',modified_site_id = 100,  user_id_modified = 100,  modified_time_stamp = sysdate  where id="))).concat(String.valueOf(sHeaderPrimaryKey));
        int i = oBean.executeUpsert(sQuery);
      } 
    } else {
      throw new EnrgiseApplicationException("wenrgise.common.norecordfound", "M");
    } 
    return sHeaderPrimaryKey;
  }
  
  public String revise(String sTableName, BaseHeaderBean oBaseHeaderBean, Timestamp oWhenPicked, ArrayList oDetailBeanArray, Timestamp oDetailPicked) throws EnrgiseApplicationException, EnrgiseSystemException {
    String sHeaderPrimaryKey = (null != oBaseHeaderBean) ? oBaseHeaderBean.getHeaderPrimaryKey() : "";
    if (sHeaderPrimaryKey != null) {
      initializeBOImpl();
      if (!checkHeaderTimeStamp(sHeaderPrimaryKey, oWhenPicked))
        throw new EnrgiseApplicationException("wenrgise.common.changed", "M"); 
      validateRevise(sHeaderPrimaryKey);
      DBUtilitiesBean oBean = new DBUtilitiesBean();
      String sQuery = String.valueOf(String.valueOf(String.valueOf(String.valueOf(String.valueOf(String.valueOf(String.valueOf(String.valueOf("update ").concat(String.valueOf(sTableName))).concat(String.valueOf(" sTablename set sTablename.status_flag = '"))).concat(String.valueOf("V"))).concat(String.valueOf("', sTablename.rev_no=sTablename.rev_no+1,sTablename.modified_site_id = 200,  sTablename.user_id_modified = 200,  sTablename.modified_time_stamp = sysdate  where sTablename.code in (select code from "))).concat(String.valueOf(sTableName))).concat(String.valueOf(" where id="))).concat(String.valueOf(sHeaderPrimaryKey))).concat(String.valueOf(")"));
      int i = oBean.executeUpsert(sQuery);
    } else {
      throw new EnrgiseApplicationException("wenrgise.common.norecordfound", "M");
    } 
    return sHeaderPrimaryKey;
  }
}
