package com.dev.swms.server.utils;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;

import com.dev.swms.server.model.interfaceLog.InterfaceLog;
import com.dev.swms.server.model.interfaceLog.InterfaceLogConstant;
import com.dev.swms.server.service.interfaceLog.InterfaceLogManager;
import com.dev.energy.server.dao.CommonDao;
/**
 * @author  dev
 * @version $Id: AdapterLauncher.java,v 1.2 2010/06/01 09:14:16 peng.lei Exp $
 */

public class AdapterLauncher implements ApplicationListener {
	protected final Log logger = LogFactory.getLog(this.getClass());
	
	/** 执行间隔时间(ms) */
	protected int sleepInterval = 5000;
	/** 服务是否启动 */
	private boolean isApplicationAvailable = false;
	/** 是否允许运行，用于客户端对其进行控制 */
	private boolean allowed = true;
	/** 二进制回退算法重置的阈值(ms，默认是１０分钟) */
	protected int thresholdForResetValue = 600000;
	/** 本次要发送的日志数 */
	private int numOfLogsToBeSent;
	/** 已发送过的日志，包括成功和失败的 */
	private int numOfLogsSent;

	protected CommonDao commonDao;
	protected InterfaceLogManager logManager;

	public AdapterLauncher(CommonDao commonDao, InterfaceLogManager logManager) {
		this.commonDao = commonDao;
		this.logManager = logManager;
	}
	
	public boolean isAllowed() {
		return allowed;
	}

	public void setAllowed(boolean allowed) {
		this.allowed = allowed;
	}

	public int getSleepInterval() {
		return sleepInterval;
	}

	public void setSleepInterval(int sleepInterval) {
		this.sleepInterval = sleepInterval;
	}

	public int getThresholdForResetValue() {
		return thresholdForResetValue;
	}

	public void setThresholdForResetValue(int thresholdForResetValue) {
		this.thresholdForResetValue = thresholdForResetValue;
	}

	public int getNumOfLogsToBeSent() {
		return numOfLogsToBeSent;
	}

	public void setNumOfLogsToBeSent(int numOfLogsToBeSent) {
		this.numOfLogsToBeSent = numOfLogsToBeSent;
	}

	public int getNumOfLogsSent() {
		return numOfLogsSent;
	}

	public void setNumOfLogsSent(int numOfLogsSent) {
		this.numOfLogsSent = numOfLogsSent;
	}

	/**
	 * 从数据库中获取InterfaceLog信息并根据其业务类型进行相应处理
	 */
	public void dealReceivedLogs() {
		logger.info("application[dispatchXMLToWebMethods] started....................");
		while(allowed) {
			List types = new ArrayList<String>();
			types.add(InterfaceLogConstant.QUERY_INVENTORY);
			types.add(InterfaceLogConstant.AVAILABLE_ORDER_PO);
			types.add(InterfaceLogConstant.AVAILABLE_ORDER_SO);
			List<InterfaceLog> logs = logManager.getLogsByConditions(types, InterfaceLogConstant.RECEIVE);		
			dealLog(logs);
			try {
				Thread.sleep(sleepInterval);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			if(!isApplicationAvailable) {
				logger.info("application[dealReceivedLogs] closed....................");
				break;
			}
		}
	}

	private void dealLog(List<InterfaceLog> logs) {
		logger.info("log size:" + logs.size());
		for(InterfaceLog log : logs) {
			//按照log业务类型进行具体业务处理，处理完毕后更新log状态为FINISH
			//----(如果需要转发消息，则转发时设置状态为PROCESS，发送成功后改为FINISH)
			if (InterfaceLogConstant.QUERY_INVENTORY.equals(log.getType())) {
				//库存审核反馈处理
				try {
					logManager.inventoryResponse(log);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if (InterfaceLogConstant.AVAILABLE_ORDER_PO.equals(log.getType()) 
					|| InterfaceLogConstant.AVAILABLE_ORDER_SO.equals(log.getType())) {
				//订单生效反馈处理
				try {
					logManager.availableOrderResponse(log);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 从数据库中获取InterfaceLog信息并根据其业务类型进行相应处理
	 */
	public void batchSendLogs() {
		logger.info("application[batchSendLogs] started....................");
		while (allowed) {
			// 对库存审核task批量处理，调用http接口发送数据
			List types = new ArrayList<String>();
			types.add(InterfaceLogConstant.RECEIVE_REPORT);
			types.add(InterfaceLogConstant.PUTAWAY_REPORT);
			types.add(InterfaceLogConstant.PICKING_REPORT);
			types.add(InterfaceLogConstant.SHIPPING_REPORT);
			List<InterfaceLog> logs = logManager.getLogsByConditions(types, InterfaceLogConstant.READY);					
			for (InterfaceLog log : logs) {
				logManager.send(log, InterfaceLogConstant.REQUEST);
			}			
			try {
				Thread.sleep(sleepInterval);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			if (!isApplicationAvailable) {
				logger
						.info("application[dealReceivedLogs] closed....................");
				break;
			}
		}
	}
	
	public void onApplicationEvent(ApplicationEvent event) {
		if(event instanceof ContextClosedEvent) {
			logger.info("Context closing......................");
			isApplicationAvailable = false;
		} else if(event instanceof ContextRefreshedEvent) {
			logger.info("Context starting......................");
			isApplicationAvailable = true;
		}		
	}
}
