package cn.amq.traffic;

import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import cn.amq.basis.AmqBasisEvent;
import cn.amq.basis.AmqConst;
import cn.amq.business.AmqMainPoint;
import cn.amq.peas.TrafficEventLinkageActionHolder;
import cn.base.bean.BeanHelper;
import cn.base.util.DateUtil;
import cn.base.util.StringUtil;
import cn.base.util.Struts2Utils;
import cn.bsystem.ptuserrole.model.PtyhBean;
import cn.im.trafficalarm.model.TrafficdevicemessagelogBean;
import cn.im.trafficlinkage.model.TrafficdevicecurrstateBean;
import cn.im.trafficlinkage.model.TrafficdevicehisstateBean;

/**
 * 设备联动AMQ的service类
 * 用于发送设备联动控制命令AMQ
 * */
public class AmqTrafficEventLinkageActionService {

	static Logger logger = Logger.getLogger(AmqTrafficEventLinkageActionService.class);
	
	/**
	 * 发送   设备联动  信息 AMQ
	 * @param eventId  事故主键
	 * @param alarmCode 事故类型编码，1：交通事故；6：交通拥堵；30：车辆逆行(非法逆行)；31：行人闯入(行人/非机动车闯入)；32：非法停车(车辆异常停驶)；5：路面损毁(道路异常)；33：车辆异常缓驶；34：车辆横穿路面；35：车辆驶离路面；36：隧道内火灾；37：能见度过低；38：行人横穿路面( 行人/非机动车横穿路面)；39：道路障碍物；99：其他事件
	 * @param deviceType 设备类型，代码字段：1：情报板；2：交通诱导灯
	 * @param deviceId 设备ID，多个设备id用分号隔开;Led情报板：关联TrafficLedDevice表;交通诱导灯：关联TrafficLightDevice表
	 * @param deviceInstruction 设备指令；Led情报板指令：情报板显示文字。交通诱导灯指令：1：绿色；0：红灯。
	 * */
	public void publishTrafficEventLinkageAction(String eventId,String alarmCode,String deviceType,String deviceId,String deviceInstruction) {
		TrafficEventLinkageActionHolder action = new TrafficEventLinkageActionHolder();
		//TrafficEventLinkageAction action = new TrafficEventLinkageAction();
		action.setEventId(eventId);   //事故主键
		action.setAlarmCode(alarmCode);  //事故类型编码，1：交通事故；2：自然灾害；3：恶劣天气；4：严重违法行为；5：路面损毁；6：交通拥堵；7：货物散落；20：特殊事件；99：其他事件；10：恢复
		action.setDeviceType(deviceType); //设备类型，代码字段：1：情报板；2：交通诱导灯。
		action.setDeviceId(deviceId);  //设备ID，多个设备id用分号隔开;Led情报板：关联TrafficLedDevice表;交通诱导灯：关联TrafficLightDevice表
		action.setDeviceInstruction(deviceInstruction); //设备指令；Led情报板指令：情报板显示文字。交通诱导灯指令：1：绿色；0：红灯。
		action.setCreateAppName("trafficLinkage");   //创建人
		action.setCreateTime(DateUtil.getDateTimeStr(new java.util.Date()));  //创建时间
		//holder.getList().add(action);
		//System.out.println("发送设备联动amq==，事件id="+eventId+"，事故类型="+deviceType+"，设备类型="+deviceType+"，设备id="+deviceId+"，指令="+deviceInstruction);
		BeanHelper.getCacheExecStateDataService().setCacheExecStateDataMap(deviceId+"-"+deviceType, deviceInstruction);
		AmqMainPoint.publishJob.publishGeneralEvent(action, AmqConst.AMQ_SUBJECT_trafficEventLinkageAction);
	}
	
	/**
	 * 发送   设备联动  信息 AMQ，同时操作【操作设备当前状态表】【交通设备历史状态表】【交通设备日志表】
	 * @param eventId  事故主键
	 * @param alarmCode 事故类型编码，1：交通事故；2：自然灾害；3：恶劣天气；4：严重违法行为；5：路面损毁；6：交通拥堵；7：货物散落；20：特殊事件；99：其他事件；10：恢复
	 * @param deviceType 设备类型，代码字段：1-情报板；2-交通信号灯；3-大屏上墙； 4-平台通信；5-语音播报；6-声光报警；7-短信通知；8-通风控制器；9照明控制；11-车道指示器；99-结束预案
	 * @param deviceId 设备ID，多个设备id用分号隔开;Led情报板：关联TrafficLedDevice表;交通诱导灯：关联TrafficLightDevice表
	 * @param deviceInstruction 设备指令；Led情报板指令：情报板显示文字。交通诱导灯指令：1：绿色；0：红灯。
	 * @param operationType 操作类型，代码，1-预案执行；2-人工编辑；3-人工报警；4-初始化预案。
	 * @param operationId 操作源表主键
	 * @param operationId CreateAccount 创建人，改为发送模式，分别为顺序执行或者重新执行
	 * return msg 0：设备联动AMQ发送失败；1:设备联动AMQ发送成功，交通设备当前状态日志更新失败；2:设备联动AMQ发送成功，交通设备当前状态更新成功，日志写入失败；3：联动AMQ发送成功，日志写入成功。
	 * */
	public String publishTrafficEventLinkageAction(String eventId,String alarmCode,String deviceType,String deviceId,String deviceInstruction,String operationType,String operationId,String CreateAccount)  {
		String msg = "3";
		String errorMsg = "";
		//step1：发送设备联动AMQ
		try{
			TrafficEventLinkageActionHolder action = new TrafficEventLinkageActionHolder();
			//TrafficEventLinkageAction action = new TrafficEventLinkageAction();
			action.setEventId(eventId);   //事故主键
			action.setAlarmCode(alarmCode);  //事故类型编码，1：交通事故；2：自然灾害；3：恶劣天气；4：严重违法行为；5：路面损毁；6：交通拥堵；7：货物散落；20：特殊事件；99：其他事件；100：人工页面编辑；10：恢复
			action.setDeviceType(deviceType); //设备类型，代码字段：1：情报板；2：交通诱导灯。
			action.setDeviceId(deviceId);  //设备ID，多个设备id用分号隔开;Led情报板：关联TrafficLedDevice表;交通诱导灯：关联TrafficLightDevice表
			action.setDeviceInstruction(deviceInstruction); //设备指令；Led情报板指令：情报板显示文字。交通诱导灯指令：1：绿色；0：红灯。
			action.setCreateAppName(CreateAccount);   //创建人
			action.setCreateTime(DateUtil.getDateTimeStr(new java.util.Date()));  //创建时间
			//holder.getList().add(action);
			logger.debug("******发送AMQ消息******【设备联动AMQ】，发送内容为：事件编号："+eventId+"，设备类型为：" + deviceType + "，设备编号："+deviceId+"，执行命令为："+deviceInstruction);
			BeanHelper.getCacheExecStateDataService().setCacheExecStateDataMap(deviceId+"-"+deviceType, deviceInstruction);
			AmqMainPoint.publishJob.publishGeneralEvent(action, AmqConst.AMQ_SUBJECT_trafficEventLinkageAction);//发送设备联动AMQ消息
		}catch(Exception e){
			errorMsg = "发送【设备联动AMQ】出现异常，设备联动命令发送未成功！";
			msg = "0";  //0：设备联动AMQ发送失败
			logger.error("AmqTrafficEventLinkageActionService-publishTrafficEventLinkageAction error:" + msg);
			logger.debug("******发送AMQ消息error******【设备联动AMQ】，发送内容为：事件编号："+eventId+"，设备类型为：" + deviceType + "，设备编号："+deviceId+"，执行命令为："+deviceInstruction);
			e.printStackTrace();
			//return msg;
		}
		//step2：AMQ发送成功后，在操作交通设备当前状态和历史状态表
		msg = this.operateTrafficCurrState(msg,deviceId,deviceInstruction,deviceType,operationType,operationId,alarmCode);
		
		//step3：添加操作交通设备消息日志表
		try{
			TrafficdevicemessagelogBean logbean  = new TrafficdevicemessagelogBean();	
			logbean.setLogId(StringUtil.getUUID());
			logbean.setMessageType("4");   //消息类型，代码，1-WS接收；2-WS发送；3-AMQ接收；4-AMQ发送
			logbean.setDeviceType(deviceType);
			logbean.setDeviceId(deviceId);
			logbean.setMessageSubject("subject.trafficEventLinkageAction");
			logbean.setMessageContent(deviceInstruction);
			logbean.setSendTime(DateUtil.getDateTimeStr(new java.util.Date()));
			logbean.setSendState(msg);//消息指令发送状态；代码；0：设备联动AMQ发送失败；1:设备联动AMQ发送成功，交通设备当前状态日志更新失败；2:设备联动AMQ发送成功，交通设备当前状态更新成功，日志写入失败；3：联动AMQ发送成功，日志写入成功。
			logbean.setOperationType(operationType);
			logbean.setOperationId(operationId);
			logbean.setCreateAccount("AMQ");
			logbean.setCreateTime(DateUtil.getDateTimeStr(new java.util.Date()));
			logbean.setModifyAccount("AMQ");
			logbean.setModifyTime(DateUtil.getDateTimeStr(new java.util.Date()));
			BeanHelper.getTrafficDeviceMessageLogDao().insert_TrafficDeviceMessageLog(logbean);
		}catch(Exception e){
			errorMsg = "发送【设备联动AMQ】出现异常，设备联动命令发送成功，日志写入失败！";
			if("3".equals(msg) || "1".equals(msg)){
				msg = "2";  //0：设备联动AMQ发送失败；1:设备联动AMQ发送成功，交通设备当前状态日志更新失败；2:设备联动AMQ发送成功，交通设备当前状态更新成功，日志写入失败；3：联动AMQ发送成功，日志写入成功。
			}
			logger.error("AmqTrafficEventLinkageActionService-publishTrafficEventLinkageAction error:" + msg);
			e.printStackTrace();
		}
		return msg;
	}
	
	/*
	 * AMQ发送成功后，在操作交通设备当前状态和历史状态表
	 * 1、先根据设备id判断设备是否存在于设备当前状态表中，若存在更新记录
	 * 2、若不存在，新加入一条记录在设备当前状态表中
	 * */
	public synchronized String operateTrafficCurrState(String msg,String deviceId,String deviceInstruction,String deviceType,String operationType,String operationId,String alarmCode) {
		//更新交通设备当前状态表
		try{
			//step2：AMQ发送成功后，在操作交通设备当前状态和历史状态表
			if("3".equals(msg)){
				String device_str[] = deviceId.split(";"); //多个设备ID用分号隔开
				String deviceInstructions[] = deviceInstruction.split("#");
				for(int i=0;i<device_str.length;i++){  //每个设备编号单独为一条记录操作
					Map map_curr = new HashMap();
					map_curr.put("deviceId", device_str[i]);
					map_curr.put("deviceType", deviceType);
					//step1：根据设备编号和设备类型查询当前设备在表中是否存在
					TrafficdevicecurrstateBean bean_curr = BeanHelper.getTrafficdevicecurrstateDao().get_Trafficdevicecurrstate(map_curr);
					if(bean_curr==null){ 
						//step3：设备状态表中不存在记录，新增加一条记录
						TrafficdevicecurrstateBean trafficCurrBean = new TrafficdevicecurrstateBean();
						trafficCurrBean.setID(StringUtil.getUUID());
						trafficCurrBean.setOperationType(operationType); //操作类型，代码，1-预案执行；2-人工编辑；3-人工报警
						trafficCurrBean.setOperationId(operationId); //操作主键
						trafficCurrBean.setDeviceType(deviceType); //设备类型，代码， 1-信息发布；2-诱导灯联动； 3-大屏上墙； 4-平台通信； 5-语音提醒；6-声光报警；7-短信通知；99-结束预案
						trafficCurrBean.setDeviceId(device_str[i]); //关联设备ID 
						trafficCurrBean.setDeviceState("1");  //设备状态，代码，0-不在线；1-在线；2-异常
						trafficCurrBean.setAlarmCode(alarmCode);
						trafficCurrBean.setMessageSubject("subject.trafficEventLinkageAction");   //消息指令主题
						trafficCurrBean.setMessageContent(deviceInstructions[i]);//消息指令内容
						trafficCurrBean.setMessageSendTime(DateUtil.getDateTimeStr(new java.util.Date()));  //消息指令发送时间
						trafficCurrBean.setMessageSendState("2");   //消息指令发送状态；代码；1-未执行，2-执行中，3-执行成功，4-执行失败。
						trafficCurrBean.setSynchronize("1");  //是否同步，0-未同步，1-已同步
						trafficCurrBean.setSynchronizeTime(DateUtil.getDateTimeStr(new java.util.Date()));  //同步时间
						trafficCurrBean.setCreateAccount("AMQ");  //创建人
						trafficCurrBean.setCreateTime(DateUtil.getDateTimeStr(new java.util.Date()));
						trafficCurrBean.setModifyAccount("AMQ"); //修改人
						trafficCurrBean.setModifyTime(DateUtil.getDateTimeStr(new java.util.Date()));
						BeanHelper.getTrafficdevicecurrstateDao().insert_Trafficdevicecurrstate(trafficCurrBean);
					}else{ 
						//step3：交通设备状态表中已存在记录，更新当前状态表
						Map updateMap = new HashMap();  //XGTJoperationId
						updateMap.put("operationType", operationType); //操作类型，代码，1-预案执行；2-人工编辑；3-人工报警
						updateMap.put("operationId", operationId); //操作主键
						updateMap.put("alarmCode", alarmCode);
						updateMap.put("messageContent", deviceInstructions[i]); //消息指令内容
						updateMap.put("messageSendTime", DateUtil.getDateTimeStr(new java.util.Date())); //消息指令发送时间
						updateMap.put("messageSendState", "2"); //消息指令发送状态；代码；1-未执行，2-执行中，3-执行成功，4-执行失败。
						updateMap.put("modifyAccount", "AMQ"); 
						updateMap.put("modifyTime", DateUtil.getDateTimeStr(new java.util.Date())); 
						//修改条件
						updateMap.put("XGTJdeviceType", deviceType); //设备类型，代码， 1-信息发布；2-诱导灯联动； 3-大屏上墙； 4-平台通信； 5-语音提醒；6-声光报警；7-短信通知；99-结束预案
						updateMap.put("XGTJdeviceId", device_str[i]); //关联设备ID 
						BeanHelper.getTrafficdevicecurrstateDao().update_Trafficdevicecurrstate(updateMap);
						//step3：在历史状态表中插入上次状态记录
						TrafficdevicehisstateBean trafficHistoryBean = new TrafficdevicehisstateBean();
						trafficHistoryBean.setID(StringUtil.getUUID());
						trafficHistoryBean.setCurrentID(bean_curr.getID());
						trafficHistoryBean.setOperationType(bean_curr.getOperationType());
						trafficHistoryBean.setOperationId(bean_curr.getOperationId());
						trafficHistoryBean.setDeviceType(bean_curr.getDeviceType());
						trafficHistoryBean.setDeviceId(device_str[i]);
						trafficHistoryBean.setDeviceState(bean_curr.getDeviceState());
						trafficHistoryBean.setAlarmCode(bean_curr.getAlarmCode());
						trafficHistoryBean.setMessageSendState(bean_curr.getMessageSendState());
						trafficHistoryBean.setMessageSubject(bean_curr.getMessageSubject());
						trafficHistoryBean.setMessageContent(bean_curr.getMessageContent());
						trafficHistoryBean.setMessageSendTime(bean_curr.getMessageSendTime());
						trafficHistoryBean.setSynchronize(bean_curr.getSynchronize());
						trafficHistoryBean.setSynchronizeTime(bean_curr.getSynchronizeTime());
						trafficHistoryBean.setCreateAccount(bean_curr.getCreateAccount());
						trafficHistoryBean.setCreateTime(bean_curr.getCreateTime());
						trafficHistoryBean.setModifyAccount(bean_curr.getModifyAccount());
						trafficHistoryBean.setModifyTime(bean_curr.getModifyTime());
						BeanHelper.getTrafficdevicehisstateDao().insert_Trafficdevicehisstate(trafficHistoryBean);
					}
				}
			}
		}catch(Exception ex){
			//errorMsg = "发送【设备联动AMQ】出现异常，设备联动命令发送未成功！";
			if("3".equals(msg)){
				msg = "1";  //0：设备联动AMQ发送失败；1:设备联动AMQ发送成功，交通设备当前状态日志更新失败；2:设备联动AMQ发送成功，交通设备当前状态更新成功，日志写入失败；3：联动AMQ发送成功，日志写入成功。
			}
			logger.error("设备联动AMQ信息发送成功，操作设备当前状态表出现异常！");
			logger.error("AmqTrafficEventLinkageActionService-publishTrafficEventLinkageAction【operateTrafficCurrState】方法 error:" + msg);
			ex.printStackTrace();
			//return msg;
		}
		return msg;
	}
	
	/**
	 * 读取设备联动AMQ消息
	 * */
	public void doTrafficEventLinkageAction(AmqBasisEvent amqBasisMsg) {
		TrafficEventLinkageActionHolder linkalarm = (TrafficEventLinkageActionHolder)amqBasisMsg;
		System.out.println("-------****************----【设备联动AMQ读取消息】--------****************----------------");
		//List<TrafficEventLinkageAction> list = entity.getList();
		//for (TrafficEventLinkageAction linkalarm : list) {
			System.out.println("EventId = " + linkalarm.getEventId());
			System.out.println("DeviceType = " + linkalarm.getDeviceType());
			System.out.println("DeviceId = " + linkalarm.getDeviceId());
			System.out.println("DeviceInstruction = " + linkalarm.getDeviceInstruction());
		//}
		System.out.println("-------****************----【设备联动AMQ读取消息结束】--------****************----------------");
		
		//添加数据库示例
		//List<TrafficEventLinkageAction> ls = entity.getList();
		//BeanHelper.getAmqPoliceCaseAlarmData().setPoliceCaseAlarmListAdd(ls);
	}
	
	public void handleClose(SocketChannel channel) {
		
	}

}
