package com.szpg.plc.message.response.read;

import com.szpg.db.dao.PgAlarmDao;
import com.szpg.db.dao.PgDeviceDao;
import com.szpg.db.dao.PgFjDao;
import com.szpg.db.dao.PgHjsbblDao;
import com.szpg.db.dao.impl.PgAlarmDaoImpl;
import com.szpg.db.dao.impl.PgDeviceDaoImpl;
import com.szpg.db.dao.impl.PgFjDaoImpl;
import com.szpg.db.dao.impl.PgHjsbblDaoImpl;
import com.szpg.db.data.PgAlarm;
import com.szpg.db.data.PgFjStat;
import com.szpg.db.data.PgHjsbbl;
import com.szpg.plc.message.response.ReadMemoryCommandResponse;
import com.szpg.plc.util.ByteUtil;
import com.szpg.util.Configure;
import com.szpg.util.DataPushInterface;
import com.szpg.util.NumberFormat;
import com.szpg.util.TimeFormat;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

public class ReadFjStatCommandResponse extends ReadMemoryCommandResponse {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -5849842153973146848L;

	private final Logger logger = Logger.getLogger(this.getClass().getName());
	
	private List<Boolean> fjFlt;
	private List<Boolean> fjRun;
	private List<Boolean> fjAm;
	private String[] zcList; //资产列表，从配置文件中获取

	public ReadFjStatCommandResponse() {
		fjFlt = new ArrayList<Boolean>();
		fjRun = new ArrayList<Boolean>();
		fjAm = new ArrayList<Boolean>();
	}
	
	public List<Boolean> getFjFlt() {
		return fjFlt;
	}

	public void setFjFlt(List<Boolean> fjFlt) {
		this.fjFlt = fjFlt;
	}

	public List<Boolean> getFjRun() {
		return fjRun;
	}

	public void setFjRun(List<Boolean> fjRun) {
		this.fjRun = fjRun;
	}

	public List<Boolean> getFjAm() {
		return fjAm;
	}

	public void setFjAm(List<Boolean> fjAm) {
		this.fjAm = fjAm;
	}

	public String[] getZcList() {
		return zcList;
	}

	public void setZcList(String[] zcList) {
		this.zcList = zcList;
	}

	@Override
	public void afterAction() {
		// 1将风机运行状态数据存入数据库
		PgDeviceDao deviceDao = new PgDeviceDaoImpl();
		PgAlarmDao alarmDao = new PgAlarmDaoImpl();
		PgFjDao fjDao = new PgFjDaoImpl();
		
		if (null != zcList && zcList.length > 0) {
			// 遍历设备列表，将风机运行状态存入数据库
			for (int i = 0; i < zcList.length; i++) {
				String zcbh = zcList[i];
				
				int deviceId = deviceDao.findDeviceIdByCode(zcbh);
				if (deviceId > 0) {
					logger.info("风机[" + zcbh + "][运行状态" + fjRun.get(i) + "][风机故障" + fjFlt.get(i) + "][手自动" + fjAm.get(i) + "]");
					deviceDao.updateDeviceStatus(deviceId, fjRun.get(i) == true ? "风机运行" : "风机停止");

					// 更新风机状态现状表
					PgFjStat temp = fjDao.findLatestStatByDevice(deviceId);
					if (null == temp) {
						fjDao.addStatRecord(fjRun.get(i), fjFlt.get(i), fjAm.get(i), TimeFormat.formatTimestamp(Calendar.getInstance().getTime()), deviceId);
					} else {
						fjDao.updateStatRecord(fjRun.get(i), fjFlt.get(i), fjAm.get(i), TimeFormat.formatTimestamp(Calendar.getInstance().getTime()), deviceId);
					}

					if (null != fjFlt.get(i) && fjFlt.get(i) == true) {
						PgAlarm alarm = new PgAlarm();
						alarm.setActive(1);
						alarm.setAlarm_date(this.getTime().getTime());
						alarm.setAlarmdevid(deviceId);
						alarm.setAlarmtypeid(PgAlarm.ALARM_TYPE_DEVRUN);
						alarm.setDescription("风机故障");
						alarm.setUserid(null);

						// 数据库操作
						alarmDao.insertAlarmRecord(alarm);
						deviceDao.updateDeviceStatus(deviceId, "风机故障");
						
						// 将报警日志推送至市级平台
						String date = TimeFormat.formatDate(getTime().getTime());
						int count = alarmDao.findAlarmCountByDate(date);
						String bjbh = "THXC." + date + "." + NumberFormat.format(count+1, "0000");
						String bjms = alarm.getDescription();
						String bjsj = date.replace("-", "");
						String dsbjResp = DataPushInterface.addFJAlarmData(bjbh, zcbh, bjms, bjsj);
						logger.info("同步风机故障报警记录日志结果：" + dsbjResp);
					}
				}
			}
		}
	}

	@Override
	public void parseData() {
		// 获取目标ACU的代码
		String acucode = this.getAcucode();
		byte[] messageData = this.getResponseData();
		
		logger.info("开始解析[读取风机状态][" + acucode + "]指令响应");
		
		// 判断数据的长度是否满足要求
		if (messageData.length != Integer.parseInt(Configure.getProperty("acubl", acucode + ".FJSTAT.WORDCOUNT")) * 2) {
			logger.error("返回的数据长度与读取的不一致！");
			this.setValid(false);
			return;
		}
		
		// 将数据转换为字符串
		// 按照高字在前，低字在后；高字节在前，低字节在后的顺序
		String dataStr = "";
		for (int c = 0; c < messageData.length; c = c + 2) {
			dataStr = ByteUtil.binToBinString(new byte[] {messageData[c], messageData[c + 1]}) + dataStr;
		}
		
		PgHjsbblDao blDao = new PgHjsbblDaoImpl();
		
		// 获取目标ACU风机运行状态内存区域的起始字地址
		int start = Integer.parseInt(Configure.getProperty("acubl", acucode + ".FJSTAT.START"));
		
		// 获取目标ACU风机相关的资产列表，即风机列表
		String zcListStr = Configure.getProperty("acubl", acucode + ".FJ.ZC.LIST");
		if (StringUtils.isEmpty(zcListStr) == true) {
			this.setValid(false);
			return;
		}
		zcList = zcListStr.split(";");

		// 初始化结果集合
		fjRun = Arrays.asList(new Boolean[zcList.length]);
		fjFlt = Arrays.asList(new Boolean[zcList.length]);
		fjAm = Arrays.asList(new Boolean[zcList.length]);

		// 解析风机运行状态
		for (int i = 0; i < zcList.length; i++) {
			String zcbh = zcList[i];
			
			// 解析风机运行状态
			PgHjsbbl runBlObj = blDao.findBlByBh(zcbh + ".Run");
			if (null != runBlObj) {
				int rkszdz = runBlObj.getKszdz(); //开始字地址
				int roffset = rkszdz - start; //与开始字的偏移量
				int rbit = runBlObj.getSzw(); //所在位

				int indexRun = dataStr.length() - 1 - roffset * 16 - rbit;
				if (indexRun >= 0) {
					char runBt = dataStr.charAt(indexRun); // 风机运行状态标志位
					getFjRun().set(i, runBt == '1' ? true : false);
				}
			}

			// 解析风机故障报警状态
			PgHjsbbl fltBlObj = blDao.findBlByBh(zcbh + ".Flt");
			if (null != fltBlObj) {
				int fkszdz = fltBlObj.getKszdz(); //开始字地址
				int foffset = fkszdz - start; //与开始字的偏移量
				int fbit = fltBlObj.getSzw(); //所在位

				int indexFlt = dataStr.length() - 1 - foffset * 16 - fbit;
				if (indexFlt >= 0) {
					char fltBt = dataStr.charAt(indexFlt); // 风机故障报警标志位
					getFjFlt().set(i, fltBt == '1' ? true : false);
				}
			}

			// 解析风机故障报警状态
			PgHjsbbl amBlObj = blDao.findBlByBh(zcbh + ".AM");
			if (null != amBlObj) {
				int fkszdz = amBlObj.getKszdz(); //开始字地址
				int foffset = fkszdz - start; //与开始字的偏移量
				int fbit = amBlObj.getSzw(); //所在位

				int indexAm = dataStr.length() - 1 - foffset * 16 - fbit;
				if (indexAm >= 0) {
					char amBt = dataStr.charAt(indexAm); // 风机手自动标志位
					getFjAm().set(i, amBt == '1' ? true : false);
				}
			}
		}
		
		logger.info("解析[读取风机状态]响应指令结束");
	}

}
