/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package kr.co.kihyun.beans.entity.ecross;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import javax.jdo.JDOException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.Inheritance;
import javax.jdo.annotations.InheritanceStrategy;
import javax.jdo.annotations.NullValue;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import kr.co.kihyun.beans.entity.IMoumiEntity;
import kr.co.kihyun.beans.entity.MDept;
import kr.co.kihyun.beans.entity.MoumiEntity;
import kr.co.kihyun.beans.entity.util.MPersistenceManager;
import kr.co.kihyun.moumi.MoumiConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author bhs
 */
@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Inheritance(strategy = InheritanceStrategy.SUBCLASS_TABLE)
public abstract class ECross<T extends IRemotePersistable> implements Serializable, IMoumiEntity<Long> {
        
        //49.SerialVersionUID 선언 부재 : Add by YOUNGJUN,CHO
        private static final long serialVersionUID = 1L;
        //++++++++++++++++++++++++++++++++++++++++++++++++  
        
	private static final Logger LOG = LoggerFactory.getLogger(ECross.class);

	@Persistent(nullValue = NullValue.EXCEPTION)
	private String createDate;

	@Persistent(nullValue = NullValue.EXCEPTION)
	private CRUD crud;

	@Persistent(nullValue = NullValue.EXCEPTION)
	private NeisParty fromParty;

	@Persistent(nullValue = NullValue.EXCEPTION)
	private NeisSystem fromSystem;

	@Persistent
	private String messageId;

	@Persistent
	private String processResultCode;

	@Persistent(nullValue = NullValue.EXCEPTION)
	private String processStatus = "0000";

	@Persistent
	private String sendReceiveDate;

	@PrimaryKey
	private String sequence;

	@Persistent(nullValue = NullValue.EXCEPTION)
	private NeisParty toParty;

	@Persistent(nullValue = NullValue.EXCEPTION)
	private NeisSystem toSystem;

	@Persistent
	private String transactionId;

	@Persistent
	private boolean isAplied;

	private static transient DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

	protected T getMoumiEntity(PersistenceManager moumiPm, Class<T> clazz) {
		T entity ;
		if (getCrud() == CRUD.C) {
			try {
				entity = clazz.newInstance();
				entity.setId(getId());
			} catch (Exception ex) {
				throw new JDOException("Could not instantiate for class " + clazz + " with empty arguments constructor. "
						+ "You may override method ECross#getMoumiEntity(PersistenceManager pm, Class<T> clazz)", ex);
			}
		} else {
			entity = moumiPm.getObjectById(clazz, getId());
		}

		return entity;
	}

	public final T toMoumiEntity(MPersistenceManager moumiPm, Class<T> clazz) {
		LOG.debug("moumi entity: {}", getMoumiEntity(moumiPm, clazz));
		return setFieldValues(moumiPm, getMoumiEntity(moumiPm, clazz));
	}

	protected abstract T setFieldValues(MPersistenceManager moumiPm, T entity);

	protected ECross(T entity) {
		this.setId(entity.getId());
		this.setCreateDate(new Date());
		this.setSequence(entity.getId().toString());
		this.setFromParty(NeisParty.valueOf(MoumiConfig.getInitParameter("moumi.partyId")));
		this.setFromSystem(NeisSystem.valueOf(MoumiConfig.getInitParameter("moumi.subSystemId")));
		this.setToSystem(NeisSystem.valueOf(MoumiConfig.getInitParameter("moumi.subSystemId")));
	}

	public final Date getCreateDate() {
		try {
			return df.parse(this.createDate);
		} catch (ParseException ex) {
			LOG.error("Date format is incorrect. - {}.createDate::{}", this, this.createDate);
			throw new RuntimeException(ex);
		}
	}

	public final CRUD getCrud() {
		return this.crud;
	}

	public final NeisParty getFromParty() {
		return this.fromParty;
	}

	public final NeisSystem getFromSystem() {
		return this.fromSystem;
	}

	public final String getProcessResultCode() {
		return this.processResultCode;
	}

	public final String getProcessStatus() {
		return this.processStatus;
	}

	public final Date getSendReceiveDate() {
		try {
			return df.parse(this.sendReceiveDate);
		} catch (ParseException ex) {
			LOG.error("Date format is incorrect. - {}.createDate::{}", this, this.sendReceiveDate);
			throw new RuntimeException(ex);
		}
	}

	public final String getSequence() {
		return this.sequence;
	}

	public final NeisParty getToParty() {
		return this.toParty;
	}

	public final NeisSystem getToSystem() {
		return this.toSystem;
	}

	public final String getTransactionId() {
		return this.transactionId;
	}

	public final void setCreateDate(Date date) {
		this.createDate = df.format(date);
	}

	public final void setCrud(CRUD crud) {
		this.crud = crud;
	}

	public final void setFromParty(NeisParty party) {
		this.fromParty = party;
	}

	public final void setFromSystem(NeisSystem system) {
		this.fromSystem = system;
	}

	public final void setProcessResultCode(String code) {
		this.processResultCode = code;
	}

	public final void setProcessStatus(String status) {
		this.processStatus = status;
	}

	public final void setSendReceiveDate(Date date) {
		this.sendReceiveDate = df.format(date);
	}

	public final void setSequence(String sequence) {
		this.sequence = sequence;
	}

	public final void setToParty(NeisParty party) {
		this.toParty = party;
	}

	public final void setToSystem(NeisSystem system) {
		this.toSystem = system;
	}

	public final void setTransactionId(String transactionId) {
		this.transactionId = transactionId;
	}

	/**
	 * @return the messageId
	 */ public String getMessageId() {
		return messageId;
	}

	/**
	 * @param messageId the messageId to set
	 */ public void setMessageId(String messageId) {
		this.messageId = messageId;
	}

	/**
	 * @return the isAplied
	 */ public boolean isAplied() {
		return isAplied;
	}

	/**
	 * @param isAplied the isAplied to set
	 */ public void setAplied(boolean isAplied) {
		this.isAplied = isAplied;
	}
}
