package com.szpg.service;

import org.apache.log4j.Logger;

import com.szpg.db.dao.PgAcuDao;
import com.szpg.db.dao.PgAcuRdcmdDao;
import com.szpg.db.dao.impl.PgAcuDaoImpl;
import com.szpg.db.dao.impl.PgAcuRdcmdDaoImpl;
import com.szpg.db.data.PgAcu;
import com.szpg.db.data.PgAcuRdcmd;
import com.szpg.plc.message.CommandResponse;
import com.szpg.plc.message.command.ReadMemoryCommand;
import com.szpg.plc.protocol.DTProtocolInterface;
import com.szpg.plc.protocol.ProtocolFactory;
import com.szpg.plc.server.ACUClient;
import com.szpg.plc.server.ACUClientUtil;

/**
 * 读取环境变量报警状态的服务过程
 * 
 * @author admin
 *
 */
public class ReadSensorStatusService {
	
	private final Logger logger = Logger.getLogger(this.getClass().getName());
	
	private PgAcuRdcmdDao cmdDao = new PgAcuRdcmdDaoImpl();
	private PgAcuDao acuDao = new PgAcuDaoImpl();
	
	public void executeService(ACUClient client, ReadMemoryCommand command) {
		// 解析命令对象为字节数组
		DTProtocolInterface finspi = ProtocolFactory.getDefaultDTProtocol();
		byte[] content = finspi.messageToBytes(command);
		
		// 通过socket接口发送出去
		ACUClientUtil.getInstance().sendACUCommand(client, content);
		
		// 1查找数据库中的ACU对象
		PgAcu acu = acuDao.findACUByDest(command.getDestinationId());
		if (null == acu) {
			return;
		}
		
		// 2生成读取命令对象
		PgAcuRdcmd cmd = new PgAcuRdcmd();
		cmd.setCmd_type(command.getCommandType());
		cmd.setDest_acu_code(acu.getAcu_code());
		cmd.setTm(command.getTime().getTime());
		
		// 3将命令保存入数据库
		cmdDao.addCmdRecord(cmd);
		
		// 4阻塞，循环查找响应消息池，找到对应的响应消息
		boolean flag = false;
		int times = 0;
		CommandResponse response = null;
		while (flag == false && times < 240) {
			response = ACUClientUtil.getInstance().responsePool.getResponse(cmd.getId());
			
			if (null != response && response.equals("") == false) {
				flag = true;
			}
			
			times++;
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO 阻塞线程被打断，需要处理异常
				// 目前的处理流程为1）记录日志；2）将命令置为超时
				logger.error("在响应池中查找命令的响应消息阻塞线程被异常打断", e);
				cmdDao.updateCmdRecordTimeout(cmd.getId());
				
				return;
			}
		}
		
		// 5若未超时，将值存入数据库
		if (null != response) {
			// 6根据命令类型的不同将监测值存入对应的数据库
			response.afterAction();
		
			// 7如果没有报警值则退出
		
			// 8如果有报警值则推送报警信息
			
			// 9发送命令查询报警时的监测值
			
		} else {
			// 10超时，将命令的超时标志位置1
			logger.warn("命令超时" + cmd.getId());
			cmdDao.updateCmdRecordTimeout(cmd.getId());
		}
	}
	
}
