package cn.hmsoft.weixin.processor;

import java.io.StringReader;
import java.util.Date;

import javax.xml.bind.JAXBContext;

import cn.hmsoft.application.SpringHelper;
import cn.hmsoft.frame.exception.BusinessException;
import cn.hmsoft.helper.ClassHelper;
import cn.hmsoft.jdbc.core.DatabaseDao;
import cn.hmsoft.log.LogHelper;
import cn.hmsoft.weixin.data.model.WxDefine;
import cn.hmsoft.weixin.data.model.WxUser;
import cn.hmsoft.weixin.entity.message.BasicMessage;
import cn.hmsoft.weixin.entity.reply.WeiXinReply;
import cn.hmsoft.weixin.request.UserinfoRequest;
import cn.hmsoft.weixin.util.WeiXinUtil;

public abstract class AbstractProcessor<T> implements Runnable {


	@Override
	public void run() {
		this.process();
	}

	protected BasicMessage msg;
	protected T jsonEntity;
	protected WxUser user;
	protected DatabaseDao daoWeiXin;
	protected Date msg_time;
	protected WxDefine wxDefine;
	protected String xml;

	public void setEntity(WxDefine wxDefine,Date msg_time, BasicMessage msg, String xml) {
		this.msg = msg;
		this.msg_time = msg_time;
		this.xml = xml;
		this.wxDefine = wxDefine;
		this.daoWeiXin = SpringHelper.AppGobalDao;
	}

	@SuppressWarnings("unchecked")
	public WeiXinReply process() {

		try {

			jsonEntity = (T) JAXBContext.newInstance(BasicMessage.class, ClassHelper.getGenericsClass(this.getClass()))
					.createUnmarshaller().unmarshal(new StringReader(xml));
		} catch (Exception e) {
			LogHelper.error(e);
		} // 获取用户
		if (this.jsonEntity == null) {
			return null;
		}
		try {
			this.user = findWxUser();
		} catch (Exception e) {
			LogHelper.error(e);

		}
		if (this.user == null)
			return null;

		try {
			return this.handle();
		} catch (BusinessException ex) {
			return null;

		} catch (Exception e) {
			LogHelper.error(e);
			return null;
		}
	}

	private final static String FIND_WX_USER = "select * from wx_user where open_id=?";

	protected WxUser findWxUser() {
		WxUser u = this.daoWeiXin.findBySql(WxUser.class, FIND_WX_USER, this.msg.getFromUserName());
		if (u == null) {
			// 去服务器获取用户
			UserinfoRequest uReq = new UserinfoRequest(this.msg.getFromUserName());
			uReq.setWxDefine(WeiXinUtil.getWxDefineByCode(this.msg.getToUserName()));
			u = (WxUser) uReq.request();
		}
		return u;
	}

	protected abstract WeiXinReply handle() throws Exception;
}
