package com.nms.server.thread.detectDataHandler;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.fang.lang.Db;
import com.nms.server.bean.AlarmInfo;
import com.nms.server.bean.DetectInfo;
import com.nms.server.bean.TableColumnsModel;
import com.nms.server.common.Common;
import com.nms.server.common.Constants;
import com.nms.server.common.EmailTypeConstants;
import com.nms.server.service.CommonService;
import com.nms.server.util.CSVUtils;
import com.nms.server.util.FileUtils;
import com.nms.server.util.StringUtil;

/**
 * 数据解析线程
 *  1、从队列中获取数据
 *  2、计算监测数据id，十位时间戳 + uuid + setId
 *  3、根据监测类别存放到响应的队列
 * @author nanfang
 *
 */
public class DataResolveThread implements Runnable{
	private static Logger logger = Logger.getLogger(DataResolveThread.class);
	private final SimpleDateFormat format = Common.getFormat();	//Java Date 类型数据格式化格式
	private static Db db = Common.getDb();
	
	
	@Override
	public void run() {
		Thread.currentThread().setName("Data Resolve Thread");
		logger.info("监测数据解析线程开始运行");
		while(!Common.isStop() && ! Thread.currentThread().isInterrupted()){
			try {
				//从缓存队列中获取，阻塞等待
				byte[] data = Common.takeDeteDataQueue();
				if(data != null && data.length > 0){
					Queue queue = Common.DETECT_QUEUE.get(DetectInfo.INFO_KEY);
					if(queue != null && queue.size() > Constants.MAX_DETECT_DATA_RESOVE_LIMIT_NUM){
						//内存缓存达到阈值，保存到硬盘
						logger.warn("Excesive monitoring data："+queue.size()+"pieces， data written to the hard disk");
						saveByteToFile(data);
					}else{
						//csv解析
						List<String []> strsList = CSVUtils.csvBytesParser(data,Constants.COMMON_TEXT_CODING);
						if(strsList != null && strsList.size() > 0){
							Object[] result = resolveData(strsList);//解析之后的数据
							if(result != null){
								String checkType = (String)result[DetectInfo.CHECKTYPE];
								//将详细监测数据放到缓存队列
								List<Map<String, String>> detaiList = (List<Map<String, String>>)result[DetectInfo.DETAILS];
								if(detaiList != null && detaiList.size() >0){
									Common.putAllDetectQueue(checkType, detaiList);
									result[DetectInfo.DETAILS] = null;
								}
								
								//特殊监测数据
								if(Constants.DETEC_SYSTEMINFO_STR.equalsIgnoreCase(checkType) ) {
									//网卡
									List<Map<String, String>> netList = (List<Map<String, String>>)result[DetectInfo.NETINFOLIST];
									if(netList != null && netList.size() > 0){
										Common.putAllDetectQueue(DetectInfo.NET_STR_KEY, netList);
										result[DetectInfo.NETINFOLIST] = null;
									}
									
									//磁盘
									List<Map<String, String>> diskList = (List<Map<String, String>>)result[DetectInfo.DISKINFOLIST];
									if(diskList != null && diskList.size() > 0){
										Common.putAllDetectQueue(DetectInfo.DISK_STR_KEY, diskList);
										result[DetectInfo.DISKINFOLIST] = null;
									}
								}
								//info 信息放到队列
								Common.putDetectInfoQueue(result);
							}
						}
					}
				}
			} catch (Exception e) {
				logger.error("",e);
			}
		}
		
		logger.info("线程停止前将所有缓存数据写到文件");
		byte[] data = null;
		while((data = Common.pollDeteDataQueue())!=null){
			saveByteToFile(data);
		}
		logger.info("监测数据解析线程停止运行");
	}
	
	
	
	/**
	 * 解析监测数据，监测数据有两种类型：旧格式（15），新格式（12）
	 * @param list
	 * @return
	 * @throws Exception 
	 */
	public Object[] resolveData(List<String []> list) throws Exception{
		Object[] detecInfo = null;
		String [] detailsStr = list.get(0);	//取第一行数据
		if(detailsStr != null){
			if(detailsStr.length > 12){//旧格式 解析
				logger.debug("旧格式数据");
				detecInfo = resoveOldData(list);//解析数据，不判断状态变更
			}else if(detailsStr.length<12){
				logger.debug( "基本数据解析长度："+detailsStr.length+" 小于最小解析标准，不予解析；");
			}else{//新格式 解析
				logger.debug("新格式数据");
				detecInfo = resoveNewData(list);//解析数据，不判断状态变更
			}
		}
		return detecInfo;
	}
	

	
	/**
	 * 根据 seqId 获取 状态有效的端口名称
	 * @param seqId
	 * @return
	 */
	public static List<String> getPortNameBySeqId(String seqId) {
		logger.debug("获取端口名称：seqId = " + seqId );
		List<String> result = null;
		//查询detection_info_new数据
		StringBuffer sql = new StringBuffer();
		sql.append(" select  t.name_flag from node_figure_info t ");
		sql.append(" where  (t.port_set_state = 1 or t.port_set_state is null)  ");
		sql.append(" and seqid  =  ? " );
		sql.append("  and t.name_flag is not null  and t.is_leaf = 1   ");
		try {
			List<Map<String,Object>> list = db.select(sql.toString(), seqId);
			if(list != null && list.size() > 0){
				result = new ArrayList<String>(list.size());
				for(Map<String,Object> m : list){
					result.add((String)m.get("name_flag"));
				}
			}
		} catch (SQLException e) {
			logger.warn("",e);
		}
		return result;
	}
	
	
	
	/**
	 * 详细数据解析
	 * 第一步：解析公共数据部分，保存各字段值到Map<String, String> publicInfo 中
	 * 第二步：解析详细数据部分，保存各字段到 Map<String, String> detail 中
	 * 第三步：检查告警信息数据，多字段告警去最高级（Level最小）
	 * 第四步：查询数据库中最新同类监测记录，并判断状态是否变化（同类判定：seq_id、detection_set_info_id，变化判定：DETECTIONED_STATE 和 POLICE_LEVEL 至少一个变化）
	 * 第五步：根据告警信息数据，拼写告警信息 
	 * 第六步：状态变更时发送邮件，将告警信息邮件发送
	 * 第七步：保存到基本信息、非正常数据和状态变更数据信息保存到告警表中
	 * 完成...
	 * @time Sep 8, 2011-3:40:45 PM
	 * @param datas
	 * @param dao
	 */
	public Object[] resoveOldData(List<String []> strsList) throws Exception{
		/* 监测数据有效判断*/
		if(strsList==null || strsList.size()==0){
			logger.debug("旧格式监测数据解析：数据内容为空，不予解析;");
			return null;
		}
		//监测解析结果
		Object[] detectInfo = null;
		Iterator<String[]> strsIte = strsList.iterator();					
		String[] datas = null;
		if(strsIte!=null && strsIte.hasNext()) {
			datas = strsIte.next();//获得第一行基本信息
		}
		if(datas==null){
			logger.debug("旧格式监测数据解析：数据内容为空，不予解析;");
			return null;
		}else if(datas.length>0){/* 数据日志尝试输出 */
			String dateTime = null;
			if(datas.length>6){	//第7字段 为监测时间字段 作展示标记
				dateTime = format.format(Long.parseLong(datas[6])); 
			}
			logger.debug("监测数据-旧格式 监测时间》"+dateTime+"  内容》"+Arrays.toString(datas));
			/* 监测数据有效判断 */
			if(datas.length<15){
				logger.debug("旧格式监测数据解析：数据解析长度："+datas.length+" 小于最小解析标准，不予解析；");
				return null;
			}
			/** 
			 * 公共部分解析格式：
			 * seqId,
			 * 监测设置ID,
			 * 监测类别,
			 * 进程名称（监测类别设置名称）,
			 * 监测服务启动时间,
			 * 检测时延（秒）,
			 * 本次检测时间,
			 * 尝试次数,
			 * 下次计划监测时间,
			 * 执行状态是否成功是否正常,
			 * 告警列序号,
			 * 告警级别,
			 * 告警值,
			 * 状态信息（描述信息）,
			 * 性能数据
			 * （,详细数据部分）....
			 **/
			/* 基本信息解析格式变量  */
			String seqId = null;		//seqId
			String setInfoId = null;	//监测设置ID
			String checkType = null;	//监测类别
			String process = null;		//进程名称（监测类别设置名称）
			Long startTime = null;		//监测服务启动时间
			Integer delayTime = null;	//检测时延（秒）
			Long checkTime = null;		//本次检测时间
			Integer currentTimes = null;	//尝试次数
			Long nextCheckTime = null;		//下次计划监测时间
			int state = -1;				//执行状态是否成功是否正常
			String showNums =  null;	//告警序列(数据)
			String pLevel =  null;		//告警级别(数据)
			int pl = 99;				//告警级别（入库）
			String pValue =  null;		//告 警 值(数据)
			String dsinfo = null;		//状态信息（描述信息）
			String pdata = null;		//性能数据
			
			
			/* 其他变量 */
			StringBuffer errorInfo= new StringBuffer();		//数据文件错误，信息整理
			boolean delyFlag = true;	//详细数据获取标识
			//Long stateChangeTime = null;//状态变更时间
			
			/* 第一步：解析公共数据部分 */
			try {
				//--seqId，
				seqId = datas[0];
				if(StringUtils.isEmpty(seqId)){
//					errorInfo.append("位置"+(0)+"数据 节点seqId(物理主机标识)不能为空；");
					errorInfo.append("Location"+(0)+"data node seqId (physical host ID) cannot be empty；");
				}else if(!StringUtil.isNumber(seqId)){
//					errorInfo.append("位置"+(0)+"数据 节点seqId(物理主机标识)不是正整数:"+seqId);
					errorInfo.append("Location"+(0)+"data node seqId (Physical Host ID) is not a positive integer:"+seqId);
				}
				//--监测设置ID，
				setInfoId = datas[1];
				if(StringUtils.isEmpty(setInfoId)){
					errorInfo.append("位置"+(1)+"数据 监测设置ID不能为空；");
				}else if(!StringUtil.isNumber(setInfoId) && !"0".equals(setInfoId)){
					errorInfo.append("位置"+(1)+"数据 监测设置ID不是整数(包括0):"+setInfoId);
				}
				//--监测类别
				checkType = datas[2];
				if(StringUtils.isEmpty(checkType)){
					errorInfo.append("位置"+(2)+"数据 监测类别不能为空；");
				}
				//--进程名称（检查类别设置名称），
				process = datas[3];
				//--监测服务启动时间，
				String startTimeStr = datas[4];
				if(StringUtils.isNotEmpty(startTimeStr)){
					try {
						startTime = Long.parseLong(startTimeStr);
					} catch (Exception e) {
						errorInfo.append("位置"+(4)+"数据 “"+startTime+"” 监测服务启动时间须为整形数:"+startTime);
					}
				}else {
					errorInfo.append("位置"+(4)+"数据 监测服务启动时间不能为空；");
				}
				//--检测时延（秒），
				String delayTimeStr = datas[5];
				if(StringUtils.isNotEmpty(delayTimeStr)){
					try {
						delayTime = Integer.parseInt(delayTimeStr);
					} catch (Exception e) {
						errorInfo.append("位置"+(5)+"数据 “"+delayTime+"” 检测时延（秒）须为整形数:"+delayTime);
					}
				}
				//--本次检测时间，
				String checkTimeStr = datas[6];
				if(StringUtils.isNotEmpty(checkTimeStr)){
					try {
						checkTime = Long.parseLong(checkTimeStr);
					} catch (Exception e) {
						errorInfo.append("位置"+(6)+"数据 “"+checkTimeStr+"” 本次检测时间须为整形数:"+checkTime);
					}
				}else {
					errorInfo.append("位置"+(6)+"数据 本次检测时间不能为空；");
				}
				//--尝试次数，
				String currentTimesSre = datas[7];
				if(StringUtils.isNotEmpty(currentTimesSre)){
					try {
						currentTimes = Integer.parseInt(currentTimesSre);
					} catch (Exception e) {
						errorInfo.append("位置"+(7)+"数据 “"+currentTimesSre+"” 尝试次数须为整形数:"+currentTimes);
					}
				}else{
					errorInfo.append("位置"+(7)+"数据 尝试次数不能为空；");
				}
				//--下次计划监测时间，
				String nextCheckTimeStr = datas[8];
				if(StringUtils.isNotEmpty(nextCheckTimeStr)){
					try {
						nextCheckTime = Long.parseLong(nextCheckTimeStr);
					} catch (Exception e) {
						errorInfo.append("位置"+(8)+"数据 “"+nextCheckTimeStr+"” 下次计划监测时间须为整形数:"+nextCheckTime);
					}
				}else{
					errorInfo.append("位置"+(8)+"数据 尝试次数不能为空；");
				}
				//--执行状态是否成功，记录的状态是否正常（用于报警 -1执行失败 0不正常，1正常），
				String stateStr = datas[9];
				if(StringUtils.isNotEmpty(stateStr)){
					try {
						state = Integer.parseInt(stateStr);
					} catch (Exception e) {
						errorInfo.append("位置"+(9)+"数据 “"+stateStr+"” 执行状态须为整形数:"+state);
					}
				}else{
					errorInfo.append("位置"+(9)+"数据 执行状态不能为空；");
				}
				//--告警序列
				showNums =  datas[10];
				//--告警级别
				pLevel =  datas[11];
				String [] nums0 = pLevel.split("\\|");
				for(String num : nums0){
					if(StringUtils.isEmpty(num)){
						continue;
					}
					int level = Integer.parseInt(num);
					if(pl>level){
						pl = level;
					}
				}
				//失败	最高级
				if(state == -1){
					if(checkType.equalsIgnoreCase(Constants.DETEC_NMSC_STR)){
						pl = Constants.DETECT_FAIL_NMSC_POLICE_LEVEL;
					}else {
						pl = Constants.DETECT_FAIL_NON_NMSC_POLICE_LEVEL;
					}
				}
				//--  告警值
				pValue =  datas[12];
				//--状态信息（描述信息），
				dsinfo = datas[13];
				if(StringUtils.isNotEmpty(dsinfo)){
					// add by zg 增加对</br>的处理 begin
					dsinfo = dsinfo.replaceAll("</br>", "\n");
					// add by zg 增加对</br>的处理 end
					if(dsinfo.getBytes().length>Constants.VARCHAR_MAX_LENGTH){
						dsinfo = StringUtil.substring(dsinfo,Constants.VARCHAR_MAX_LENGTH);
					}
				}
				//--性能数据
				pdata = datas[14];
				if(StringUtils.isNotEmpty(pdata)){
					// add by zg 增加对</br>的处理 begin
					pdata = pdata.replaceAll("</br>", "\n");
					// add by zg 增加对</br>的处理 end
					if(pdata.getBytes().length>Constants.VARCHAR_MAX_LENGTH){
						pdata = StringUtil.substring(pdata,Constants.VARCHAR_MAX_LENGTH);
					}
				}else {//界面异常信息列表的状态信息显示为性能数据，所以如果性能数据为空，则取状态信息
					pdata = dsinfo;
				}
			} catch (Exception e) {
				String s = "基本数据部分解析失败"+e.getMessage();
				logger.warn(s);
				errorInfo.append(s);
			}
			//--基本信息解析 存在异常值 无须保存，返回错误信息 用于系统告警
			if(errorInfo.length() != 0){
				logger.error("          第一步-1： 旧格式监测数据解析异常：  seqId:"+seqId+",setInfoId:"+setInfoId+",checkType:"+checkType+" checkTime:"+new Date(checkTime)+" 监测数据解析异常："+errorInfo);
				return null;
			}
			//-- 根据执行状态判断是否需要获取详细数据的信息 及报警信息
			if(state < 0){	//失败	报警only
				delyFlag = false;
			}
			Calendar arriveTime = Calendar.getInstance();
			detectInfo = new Object[33];
			//detectInfo[DetectInfo.null] = (CSVUtils.csvBytesPrinter1(strsList, Constants.COMMON_TEXT_CODING));
			detectInfo[DetectInfo.SEQID] = (seqId);
			detectInfo[DetectInfo.SETINFOID] = (setInfoId);
			detectInfo[DetectInfo.STARTTIME] = (startTime);
			detectInfo[DetectInfo.DELAYTIME] = (delayTime);
			detectInfo[DetectInfo.CHECKTIME] = (checkTime);
			detectInfo[DetectInfo.CURRENTTIMES] = (currentTimes);
			detectInfo[DetectInfo.NEXTCHECKTIME] = (nextCheckTime);
			detectInfo[DetectInfo.CHECKTYPE] = (checkType);
			detectInfo[DetectInfo.PDATA] = (pdata);
			detectInfo[DetectInfo.ARRIVETIME] = (arriveTime.getTimeInMillis());
			detectInfo[DetectInfo.STATE] = (state);
			detectInfo[DetectInfo.PLEVEL] = (pl);
			detectInfo[DetectInfo.DSINFO] = (dsinfo);
			detectInfo[DetectInfo.PROCESS] = process;
			
			/**
			 * 储存详细数据前三个字段，恢复数据时使用
			 */
			List<String> showNumList = new LinkedList<String>();
			List<String> plevelList = new LinkedList<String>();
			List<String> alarmList = new LinkedList<String>();
	
			showNumList.add(showNums);
			plevelList.add(pLevel);
			alarmList.add(pValue);
			
			detectInfo[DetectInfo.SHOWNUMLIST] = (showNumList);
			detectInfo[DetectInfo.PLEVELLIST] = (plevelList);
			detectInfo[DetectInfo.ALARMLIST] = (alarmList);
			
			
			/* 第二步：解析详细数据部分 */
			Map<String, String> detail = new HashMap<String, String>();		//详细数据集合
			Map<Integer, TableColumnsModel> tableMap = Common.getTableMap().get(checkType);
			if(tableMap ==null || tableMap.size() == 0){
				logger.error(""+checkType+"无法获取表结构");
				delyFlag = false;
			}
			List<Map<String, String>> detaiList = null;	//详细数据集合
			if(delyFlag){
				detaiList = new ArrayList<Map<String, String>>();//初始化详细数据集合
				int index = 15;		//数据集合解析游标
				try {
					//--  详细信息整理 监测具体数据信息（每个字段一列）。
					int i = 0 ;
					while(detail.size() < tableMap.size()){
						TableColumnsModel field = tableMap.get(i);
						++i;
						if((i-1)>tableMap.size()){
							break;
						}
						if(field!=null){
							//当监测数据（index == datas.length）时，及有效监测数据已经读取完成，tableMap页无需增加空字段数据
							if(index == datas.length){
								detail.put(field.getFiledName(), null);
								continue;
							}
							try {
								String fileType = field.getFiledType().toUpperCase();
								if("DATE".equals(fileType)){
									if(StringUtils.isNumeric(datas[index])){//是数字型时间时格式化
										detail.put(field.getFiledName(), format.format(new Date(Long.parseLong(datas[index].trim()))));
									}else{//字符型时间 2016-06-17 08:02:02
										detail.put(field.getFiledName(), datas[index].trim());
									}
								}else{
									if("NUMBER".equals(fileType)){
										if (StringUtils.isBlank(datas[index])
												|| StringUtil.isRationalNumber(datas[index])) {
											detail.put(field.getFiledName(), datas[index].trim());
										}  else if (datas[index].trim().contains(" days, ")) {
											detail.put(field.getFiledName(), CommonService.getLongTimeStr(datas[index].trim()));
										} else {
											throw new Exception("NUMBER数据格式错误！");
										}
									}else{
										String length = fileType.replaceAll("VARCHAR2\\((\\d+)\\)", "$1");
										if(Integer.parseInt(length) < datas[index].trim().length()) {
											throw new Exception("VARCHAR2数据格式错误！");
										}
										detail.put(field.getFiledName(), datas[index].trim());
									}
								}
							} catch (Exception e) {
								errorInfo.append(checkType+" 表字段集合信息解析失败；");
								errorInfo.append(field.getFiledName()).append("字段取值")
								.append(datas[index]).append("发生错误；异常数据行：");
								for (String string : datas) { // 添加异常数据
									errorInfo.append(string).append(',');
								}
								errorInfo.deleteCharAt(errorInfo.length()-1);
								//监测数据的详细信息如果和指定的字段类型不匹配，则抛弃此条监测数据，避免影响批量入库
								logger.error("          第一步-1： 旧格式监测数据解析异常： seqId:"+seqId+",setInfoId:"+setInfoId+",checkType:"+checkType+" checkTime:"+new Date(checkTime)+" 监测数据解析异常："+errorInfo);
								return null;
							}
							index++;
						}
					}
					
					detail.put("SEQ_ID", seqId);
					detail.put("DETECTIONED_STATE", state+"");
					detail.put("DETECTION_SET_INFO_ID", setInfoId+"");
					detail.put("DATA_CHECK_TIME_DIGITAL", checkTime+""); // 测试时间
					detail.put("DATA_CHECK_TIME", format.format(new Date(checkTime))); // 测试时间				
					detail.put("DATA_ARRIVE_TIME_DIGITAL", arriveTime.getTimeInMillis()+"");		// 入库时间
					detail.put("DATA_ARRIVE_TIME",format.format(arriveTime.getTime()));	// 入库时间
					detaiList.add(detail);
				} catch (Exception e) {
					String s = "详细数据部分解析失败"+e.getMessage();
					logger.warn(s);
				}
			}
	
			int urgentLevel = EmailTypeConstants.URGENT_LATER;
			
			//NMSC 监测失败状态 程序设定为为紧急
			if(state == -1 ){
				if(checkType.equalsIgnoreCase(Constants.DETEC_NMSC_STR)){
					urgentLevel = Constants.DETECT_FAIL_NMSC_POLICE_EMERGENT;
				}else {
					urgentLevel = Constants.DETECT_FAIL_NON_NMSC_POLICE_EMERGENT;
				}
			}
			/*
			 *1.整理告警信息
			 *2.判断告警级别 
			 */
			//根据告警设置，获得当前告警紧急状态:由于之前的处理是当监测状态或者告警级别发生改变时，才发送邮件和根据告警设置来确定是否紧急，当第一次入库就异常时，是否紧急的判断就有问题了，
			String [] nums = showNums.split("\\|");
			String [] levels = pLevel.split("\\|");
			String [] values = pValue.split("\\|");
			List<AlarmInfo> aList = Common.getAlarmInfoMap().get(setInfoId);
			Iterator<AlarmInfo> iteAlarmList = null;
			String cpInfoTmp = "";
			StringBuffer alarmInfo = new StringBuffer();
			if(state == 0){
				int pl0 = 99;
				for(int i = 0 ; i<nums.length ;i++){
					String num = nums[i];
					if(StringUtils.isEmpty(num) || aList == null || aList.size() ==0){
						continue;
					}
					iteAlarmList = aList.iterator();
					while (iteAlarmList.hasNext()) {
						AlarmInfo elem = (AlarmInfo) iteAlarmList.next();
						//判断告警字段和告警级别是否相等
						if(elem.getShowNum().toString().equals(nums[i])){						
							try
							{
								if( pl0>=Integer.parseInt(levels[i].trim())){
									pl0 = Integer.parseInt(levels[i].trim());
									//告警紧急级别随告警级别走
									if(pl0==Constants.LEVEL_OF_EMERGENCY) {
										urgentLevel = EmailTypeConstants.URGENT_IMMEDIATELY;
									}else {
										urgentLevel = EmailTypeConstants.URGENT_LATER;
										
									}
								}
							} catch (Exception e)
							{
								logger.error("旧格式监测数据-修改正告警级别时，解析告警level:"+levels[i]+" 异常", e);
							}
							/** 字段名称 intDate 实际值： 80》60%（临界值） 级别 40 **/	
							String filedName = "";
							String filedComments = "";
							if(tableMap !=null){
								TableColumnsModel tm = tableMap.get(elem.getShowNum());
								filedName = tm==null?"":tm.getFiledName();
								filedComments = tm==null?"":tm.getFiledComments();
							}
							
							cpInfoTmp +=  " "+(StringUtils.isEmpty(elem.getFiledCommonts())?filedName:elem.getFiledCommonts());
							cpInfoTmp +=  " 为："+detail.get(filedName);
							cpInfoTmp +=  ""+(elem.getPoliceUnit()==null ? "" : "null".equals(elem.getPoliceUnit()) ? "" : elem.getPoliceUnit());
							cpInfoTmp +=  "   报警级别："+levels[i];
							cpInfoTmp +=  " \n";
						}
					}
					//如果是握手监测，不添加告警设置字段相关信息
					if(!Constants.DETEC_NMSC_STR.equalsIgnoreCase(checkType)) {
						alarmInfo.append(cpInfoTmp);
					}
				}
			}
			
			detectInfo[DetectInfo.ALARMINFO] = (alarmInfo.toString());
			detectInfo[DetectInfo.URGENTLEVEL] = (urgentLevel);
			detectInfo[DetectInfo.DELYFLAG] = (delyFlag);//用于邮件发送
			detectInfo[DetectInfo.DETAILS] = (detaiList);//用于批量入库详细信息
			
			//特殊追加信息解析--systeminfo-disk、net
			//-- 特殊信息保存整理
			if(Constants.DETEC_SYSTEMINFO_STR.equalsIgnoreCase(checkType) ) {
				while (strsIte.hasNext()) {
					String [] detailsArr = strsIte.next();	//取出 
					if(detailsArr == null || detailsArr.length ==0){	//空行不解析
						continue;
					}
					if(detailsArr.length != 2){	//不是[details:0]格式无法解析
						break;
					}

					if("disk".equalsIgnoreCase(detailsArr[0])){
						List<Map<String, String>> infoList = new ArrayList<Map<String, String>>();
						int endNum = StringUtils.isEmpty(detailsArr[1])?0:Integer.parseInt(detailsArr[1]);
						disk:while (strsIte.hasNext()) {
							endNum--;
							String [] detailsArr0 = strsIte.next();	//取出
							int len = detailsArr0.length;
							Map<String, String> diskInfo = new HashMap<String, String>();
							diskInfo.put("DISK_RANG", len>0 ? detailsArr0[0]:"");//盘符
							diskInfo.put("DISK_SIZE", len>1 ? detailsArr0[1]:"");//大小
							diskInfo.put("DATA_CHECK_TIME_DIGITAL", checkTime+"");//监测时间（long）
							diskInfo.put("DATA_CHECK_TIME", format.format(new Date(checkTime)));//监测时间（date）
							diskInfo.put("DATA_ARRIVE_TIME_DIGITAL", arriveTime.getTimeInMillis()+"");////录入记录时间（当前时间 long）
							diskInfo.put("DATA_ARRIVE_TIME", format.format(arriveTime.getTime()));////录入记录时间（当前时间 date）
							diskInfo.put("DETECTION_SET_INFO_ID", setInfoId);//
							diskInfo.put("SEQ_ID", seqId);
							diskInfo.put("DETECTIONED_STATE", state+"");
							infoList.add(diskInfo);
							if(endNum==0){
								logger.debug("disk解析完成 跳出循环");
								break disk;
							}
						}
						if(infoList.size()>0) {
							detectInfo[DetectInfo.DISKINFOLIST] = (infoList);
						}
					}else if("net".equalsIgnoreCase(detailsArr[0])) {
						List<Map<String, String>> infoList = new ArrayList<Map<String, String>>();
						int endNum = StringUtils.isEmpty(detailsArr[1])?0:Integer.parseInt(detailsArr[1]);
						net:while (strsIte.hasNext()) {
							endNum--;
							String [] netInfoTmp = strsIte.next();	//取出
							int len = netInfoTmp.length;
							Map<String, String> netInfo = new HashMap<String, String>();
							netInfo.put("NET_NAME", len>0 ? netInfoTmp[0]:"");//网卡名称
							netInfo.put("NET_STATE", len>1 ? netInfoTmp[1]:"");//网卡状态
							netInfo.put("NET_SPEED", len>2 ? netInfoTmp[2]:"");//网卡带宽
							netInfo.put("NET_IP", len>3 ? netInfoTmp[3]:"");//ip
							netInfo.put("NET_SUBMASK", len>4 ? netInfoTmp[4]:"");//子网掩码
							netInfo.put("NET_GATEWAY", len>5 ? netInfoTmp[5]:"");//网关
							netInfo.put("NET_MAC", len>6 ? netInfoTmp[6]:"");//NET_MAC
							netInfo.put("DATA_CHECK_TIME", format.format(new Date(checkTime)));
							netInfo.put("DATA_ARRIVE_TIME", format.format(arriveTime.getTime()));//录入记录时间（当前时间 date）
							netInfo.put("DATA_CHECK_TIME_DIGITAL",  checkTime+"");//监测时间（long）
							netInfo.put("DATA_ARRIVE_TIME_DIGITAL", arriveTime.getTimeInMillis()+"");//录入记录时间（当前时间 long）
							netInfo.put("DETECTION_SET_INFO_ID", setInfoId);// id
							netInfo.put("SEQ_ID", seqId);
							netInfo.put("DETECTIONED_STATE", state+"");
							infoList.add(netInfo);
							if(endNum ==0){
								break net;
							}
						}
						if(infoList.size()>0) {
							detectInfo[DetectInfo.NETINFOLIST] = (infoList);
						}
					}
				}
			}	
			
		}
		return detectInfo;
	}
	
	
	
	public Object[] resoveNewData(List<String []> strsList) throws Exception{
		/* 监测数据有效判断*/
		if(strsList==null || strsList.size()==0 
				|| strsList.get(0).length<12){
			return null;
		}
		
		//监测解析结果
		Object[] detectInfo = null;
		Iterator<String []> strsIte = strsList.iterator();//一条监测数据：有多行数据
		String [] datas = strsIte.next();
		
		/** 
		 * 公共部分解析格式：
		 * seqId,
		 * 监测设置ID,
		 * 监测类别,
		 * 进程名称（监测类别设置名称）,
		 * 监测服务启动时间,
		 * 检测时延（秒）,
		 * 本次检测时间,
		 * 尝试次数,
		 * 下次计划监测时间,
		 * 执行状态是否成功是否正常,
		 * 状态信息（描述信息）,
		 * 性能数据
		 **/
		
		/* 基本信息解析格式变量  */
		String seqId = null;		//seqId
		String setInfoId = null;	//监测设置ID
		String checkType = null;	//监测类别
		String process = null;		//进程名称（监测类别设置名称）
		Long startTime = null;		//监测服务启动时间
		
		Integer delayTime = null;	//检测时延（秒）
		Long checkTime = null;		//本次检测时间
		Integer currentTimes = null;	//尝试次数
		Long nextCheckTime = null;		//下次计划监测时间
		int state = -1;				//执行状态是否成功是否正常
		String dsinfo = null;		//状态信息（描述信息）
		String pdata = null;		//性能数据
		
		
		/* 其他变量 */
		StringBuffer errorInfo= new StringBuffer();		//数据文件错误，信息整理
		boolean delyFlag = true;	//详细数据获取标识
		Long stateChangeTime = null;		//状态变更时间
		
		/* 第一步：解析公共数据部分 */
		
		try {
			
			//--seqId，
			seqId = datas[0];
//			logger.debug("被监测节点seqId："+seqId);
			if(StringUtils.isEmpty(seqId)){
//				errorInfo.append("位置"+(0)+"数据 节点seqId(物理主机标识)不能为空；");
				errorInfo.append("Location"+(0)+"data node seqId (physical host ID) cannot be empty；");
			}else if(!StringUtil.isNumber(seqId)){
//				errorInfo.append("位置"+(0)+"数据 节点seqId(物理主机标识)不是正整数:"+seqId);
				errorInfo.append("Location"+(0)+"data node seqId (physical host ID) is not a positive integer:"+seqId);
			}
			
			//--监测设置ID，
			setInfoId = datas[1];
//			logger.debug("监测项："+setInfoId);
			if(StringUtils.isEmpty(setInfoId)){
				errorInfo.append("Location"+(1)+"data Monitoring Settings ID cannot be emp；");
			}else if(!StringUtil.isNumber(setInfoId) && !"0".equals(setInfoId)){
//				errorInfo.append("位置"+(1)+"数据 监测设置ID不是整数(可以为0，默认的系统基础信息的设置就为0):"+setInfoId);
				errorInfo.append("Location"+(1)+"Data Monitoring setting ID is not an integer (can be 0, the default system basic information is set to 0):"+setInfoId);
			}
			
			//--监测类别
			checkType = datas[2];
			if(StringUtils.isEmpty(checkType)){
				errorInfo.append("位置"+(2)+"数据 监测类别不能为空；");
			}
			
			//--进程名称（检查类别设置名称），
			process = datas[3];
			
			//--监测服务启动时间，
			String startTimeStr = datas[4];
			if(StringUtils.isNotEmpty(startTimeStr)){
				try {
					startTime = Long.parseLong(startTimeStr);
				} catch (Exception e) {
					errorInfo.append("位置"+(4)+"数据 “"+startTime+"” 监测服务启动时间须为整形数:"+startTime);
				}
			}else {
				errorInfo.append("位置"+(4)+"数据 监测服务启动时间不能为空；");
			}
			
			//--检测时延（秒），
			String delayTimeStr = datas[5];
			if(StringUtils.isNotEmpty(delayTimeStr)){
				try {
					delayTime = Integer.parseInt(delayTimeStr);
				} catch (Exception e) {
					errorInfo.append("位置"+(5)+"数据 “"+delayTime+"” 检测时延（秒）须为整形数:"+delayTime);
				}
			}
			
			//--本次检测时间，
			String checkTimeStr = datas[6];
			if(StringUtils.isNotEmpty(checkTimeStr)){
				try {
					checkTime = Long.parseLong(checkTimeStr);
				} catch (Exception e) {
					errorInfo.append("位置"+(6)+"数据 “"+checkTimeStr+"” 本次检测时间须为整形数:"+checkTime);
				}
			}else {
				errorInfo.append("位置"+(6)+"数据 本次检测时间不能为空；");
			}
			
			//--尝试次数，
			String currentTimesSre = datas[7];
			if(StringUtils.isNotEmpty(currentTimesSre)){
				try {
					currentTimes = Integer.parseInt(currentTimesSre);
				} catch (Exception e) {
					errorInfo.append("位置"+(7)+"数据 “"+currentTimesSre+"” 尝试次数须为整形数:"+currentTimes);
				}
			}else{
				errorInfo.append("位置"+(7)+"数据 尝试次数不能为空；");
			}
			
			//--下次计划监测时间，
			String nextCheckTimeStr = datas[8];
			if(StringUtils.isNotEmpty(nextCheckTimeStr)){
				try {
					nextCheckTime = Long.parseLong(nextCheckTimeStr);
				} catch (Exception e) {
					errorInfo.append("位置"+(8)+"数据 “"+nextCheckTimeStr+"” 下次计划监测时间须为整形数:"+nextCheckTime);
				}
			}else{
				errorInfo.append("位置"+(8)+"数据 尝试次数不能为空；");
			}
			
			//--执行状态是否成功，记录的状态是否正常（用于报警 -1执行失败 0不正常，1正常），
			String stateStr = datas[9];
			if(StringUtils.isNotEmpty(stateStr)){
				try {
					state = Integer.parseInt(stateStr);
				} catch (Exception e) {
					errorInfo.append("位置"+(9)+"数据 “"+stateStr+"” 执行状态须为整形数:"+state);
				}
			}else{
				errorInfo.append("位置"+(9)+"数据 执行状态不能为空；");
			}
			
			//--状态信息（描述信息），
			dsinfo = datas[10];
			
			
			//--性能数据
			pdata = datas[11];
			if(StringUtils.isNotEmpty(pdata)){
				// add by zg 增加对</br>的处理 begin
				pdata = pdata.replaceAll("</br>", "\n");
				// add by zg 增加对</br>的处理 end
				if(pdata.getBytes().length>Constants.VARCHAR_MAX_LENGTH){
					pdata = StringUtil.substring(pdata,Constants.VARCHAR_MAX_LENGTH);
				}
			}else {//界面异常信息列表的状态信息显示为性能数据，所以如果性能数据为空，则取状态信息
				pdata = dsinfo;
			}
			
		} catch (Exception e) {
			String s = "基本数据部分解析失败"+e.getMessage();
			logger.warn(s);
			errorInfo.append(s);
		}
		
		//--基本信息解析 存在异常值 无须保存，返回错误信息 用于系统告警
		if(errorInfo.length() != 0){
			logger.error("          第一步-1： 新格式监测数据解析异常： seqId:"+seqId+",setInfoId:"+setInfoId+",checkType:"+checkType+" checkTime:"+new Date(checkTime)+" 监测数据解析异常："+errorInfo);
			return null;
		}
		
		//-- 根据执行状态判断是否需要获取详细数据的信息 及报警信息,执行失败，则不要获取
		if(state < 0){	//失败	报警only
			delyFlag = false;//程序执行失败时，不入库详细监测信息
		}
		
		
		//公共信息集合
		Calendar arriveTime = Calendar.getInstance();
		detectInfo = new Object[33];
		//detectInfo[DetectInfo.null] = (CSVUtils.csvBytesPrinter1(strsList, Constants.COMMON_TEXT_CODING));
		detectInfo[DetectInfo.SEQID] = (seqId);
		detectInfo[DetectInfo.SETINFOID] = (setInfoId);
		detectInfo[DetectInfo.STARTTIME] = (startTime);
		detectInfo[DetectInfo.DELAYTIME] = (delayTime);
		detectInfo[DetectInfo.CHECKTIME] = (checkTime);
		detectInfo[DetectInfo.CURRENTTIMES] = (currentTimes);
		detectInfo[DetectInfo.NEXTCHECKTIME] = (nextCheckTime);
		detectInfo[DetectInfo.CHECKTYPE] = (checkType);
		detectInfo[DetectInfo.PDATA] = (pdata);
		detectInfo[DetectInfo.ARRIVETIME] = (arriveTime.getTimeInMillis());
		detectInfo[DetectInfo.PROCESS] = process;
		
		/* 第二步：解析详细数据部分 */
		Map<Integer, TableColumnsModel> tableMap = Common.getTableMap().get(checkType);
		if(tableMap ==null || tableMap.size() == 0){
			logger.error(""+checkType+"无法获取表结构");
			delyFlag = false;
		}
		
		List<Map<String, String>> detaiList = new ArrayList<Map<String, String>>();		//详细数据集合
		int pLevel =99;//默认恢复正常
		StringBuffer alarmInfo = new StringBuffer();
		int urgentLevel = EmailTypeConstants.URGENT_LATER;
		if(delyFlag){
			
			details:while(strsIte.hasNext()){
				String [] detailsArr = strsIte.next();	//取出 
				if(detailsArr == null || detailsArr.length ==0){	//空行不解析
					continue;
				}
				if(detailsArr.length != 2){	//不是[details:0]格式无法解析
					break details;
				}
				if("details".equalsIgnoreCase(detailsArr[0])){
                    int endNum = StringUtils.isEmpty(detailsArr[1])?0:Integer.parseInt(detailsArr[1]);
					/*
					 * 如果是checkType='switchport'监测，且有详细信息，才判断每个详细信息的状态，再确定公共信息的状态：人为设置状态、流量大于0
					 一、根据端口状态，修改监测信息（detection_info、di_switchport表）的detection_state：
					            公共信息状态：-1执行不成功；0异常；1正常
					            端口信息状态：1:正常，0：异常
							   1.查询当前节点人为设置状态port_set_state为up的端口：1up，2down
							   2.对于每个端口
							    if(端口state==1&&当前端口的设置状态为up) {//如果state非0才做判断，并修改，如果state已经为0，则没必要再判断端口的状态（只要有一个端口发生以下异常，则detection_state=0异常）
							   		
								            若IFADMINSTATUS状态为down，则端口state和公共信息state异常(1up,2down)
								           if(端口state==1) {
								           		判断流量（输入速度+输出速度）为0，则端口state和公共信息state异常
								           }
							     }
			   
					*/
					List<String> portNameList = null;
					if(endNum>0 && Constants.DETEC_SWITCH_STR.equalsIgnoreCase(checkType)) {
						//查询当前节点设置状态为up的端口名称，生成list<String>
						portNameList = DataResolveThread.getPortNameBySeqId(seqId);
					}
					
					/**
					 * 储存详细数据前三个字段，恢复数据时使用
					 */
					List<String> showNumList = new LinkedList<String>();
					List<String> plevelList = new LinkedList<String>();
					List<String> alarmList = new LinkedList<String>();
					while(strsIte.hasNext()){
						endNum--;
						String [] detailsArr0 = strsIte.next();	//取出
						Map<String, String> detail = new HashMap<String, String>();		//详细数据集合
						//-- 详细数据解析
						if(detailsArr0!=null && detailsArr0.length>0){
							//告警数据相关信息：0-2
							String showNumStr = detailsArr0[0];
							String pLevelStr = detailsArr0[1];
							String alarmValue = detailsArr0[2];
							
							showNumList.add(showNumStr);
							plevelList.add(pLevelStr);
							alarmList.add(alarmValue);
							
							int index = 3;		//数据集合解析游标
							try {
								//--  详细信息整理 监测具体数据信息（每个字段一列）。
								int i = 0 ;
								while(detail.size() < tableMap.size()){//将metadata表中对应的字段，按shouNum进行组合数据
									TableColumnsModel field = tableMap.get(i);
									++i;
									if((i-1)>tableMap.size()){
										break;
									}
									if(field!=null){
										//当监测数据（index == detailsArr0.length）时，及有效监测数据已经读取完成，tableMap页无需增加空字段数据
										if(index == detailsArr0.length){
											detail.put(field.getFiledName(), null);
											continue;
										}
										try {
											String fileType = field.getFiledType().toUpperCase();
											if("DATE".equals(fileType)){
												if(StringUtils.isNumeric(detailsArr0[index])){//如果为数字型时间，转换
													detail.put(field.getFiledName(), format.format(new Date(Long.parseLong(detailsArr0[index].trim()))));
												}else{//eg:2016-03-06 12:12:12
													detail.put(field.getFiledName(), detailsArr0[index].trim());
												}
											}else{
												if("NUMBER".equals(fileType)){
													if (StringUtils.isBlank(detailsArr0[index])
															|| StringUtil.isRationalNumber(detailsArr0[index])) {
														detail.put(field.getFiledName(), detailsArr0[index].trim());
													}  else if (detailsArr0[index].trim().contains(" days, ")) {
														detail.put(field.getFiledName(), CommonService.getLongTimeStr(detailsArr0[index].trim()));
													} else {
														throw new Exception("NUMBER数据格式错误！");
													}
												}else{ // VARCHAR2(x)
													String length = fileType.replaceAll("VARCHAR2\\((\\d+)\\)", "$1");
													if(Integer.parseInt(length) < detailsArr0[index].trim().length()) {
														throw new Exception("VARCHAR2数据格式错误！");
													}
													detail.put(field.getFiledName(), detailsArr0[index].trim());
												}
											}
										} catch (Exception e) {
											errorInfo.append(checkType+" 表字段集合信息解析失败；");
											errorInfo.append(field.getFiledName()).append("字段取值")
													.append(detailsArr0[index]).append("发生错误；异常数据行：");
											for (String string : detailsArr0) { // 添加异常数据
												errorInfo.append(string).append(',');
											}
											errorInfo.deleteCharAt(errorInfo.length()-1);
											//监测数据的详细信息如果和指定的字段类型不匹配，则抛弃此条监测数据，避免影响批量入库
											logger.error("          第一步-1： 新格式监测数据解析异常： seqId:"+seqId+",setInfoId:"+setInfoId+",checkType:"+checkType+" checkTime:"+new Date(checkTime)+" 监测数据解析异常："+errorInfo);
											return null;
										}
										index++;
									}
								}
								//组合附加的一些信息
								detail.put("SEQ_ID", seqId);
								String detailDetectionState = "";
								if(StringUtils.isBlank(pLevelStr)){//没有告警，当前详细监测信息正常
									detailDetectionState = "1";//正常
								}else{
									detailDetectionState = "0";//异常
								}								
								//如果是switchport监测,有端口详细信息，且端口状态为正常，才需要再根据以下条件判断端口是否异常
								if(portNameList!=null&&portNameList.size()>0&&"1".equals(detailDetectionState)) {
									String ifDescr = detailsArr0[4];//ifDescr-showNum:2--+2=4（因为有3个告警的字段）
									/**
									 * 1.人为设置端口状态为up时，若IFADMINSTATUS或者IFOPERSTATUS状态为down2（!=1:up），则state=0异常--1up,2down
								           if(state==1) {
								           		2.流量（输入速度+输出速度）为0，则state=0异常
								           }
									 */
									if(portNameList.contains(ifDescr)) {//如果此端口设置的状态为up
										String ifAdminStatus = detailsArr0[9];//showNum=7,1:up,2:down
										if("2".equals(ifAdminStatus)) {
											state = 0;//监测公共信息的状态
											dsinfo += "$@$端口"+ifDescr+"异常(配置状态与实际状态不符)";
											detailDetectionState = "0";//当前端口的状态
											pLevel = Constants.PORT_ALARM_LEVEL;//非界面设置，默认为5级
										}
										
										if("1".equals(detailDetectionState)) {//如果当前端口的状态正常，才需要判断流量是否为0
											double inOctetsSpeed = detailsArr0[25]==null?0d:("".equals(detailsArr0[25])?0d:Double.parseDouble(detailsArr0[25].trim()));//23+2=25,瞬时输入字节速度
											double outOctetsSpeed = detailsArr0[29]==null?0d:("".equals(detailsArr0[29])?0d:Double.parseDouble(detailsArr0[29].trim()));//27+2=29,瞬时输出字节速度
											logger.info("test:port:inOctetsSpeed="+inOctetsSpeed+";outOctetsSpeed="+outOctetsSpeed);
											if((inOctetsSpeed+outOctetsSpeed)<=0) {
												state = 0;//监测公共信息的状态
												dsinfo += "$@$端口"+ifDescr+"异常(流量为0),inOctetsSpeed="+inOctetsSpeed+",outOctetsSpeed="+outOctetsSpeed+",sum="+(inOctetsSpeed+outOctetsSpeed);
												detailDetectionState = "0";//当前端口的状态
												pLevel = Constants.PORT_ALARM_LEVEL;//非界面设置，默认为5级
											}
										}
									}
								}
								
								detail.put("DETECTIONED_STATE", detailDetectionState);
								detail.put("DETECTION_SET_INFO_ID",setInfoId);	// 入库时间
								detail.put("DATA_CHECK_TIME_DIGITAL", checkTime+""); // 测试时间
								detail.put("DATA_CHECK_TIME", format.format(new Date(checkTime))); // 测试时间
								detail.put("DATA_ARRIVE_TIME_DIGITAL", arriveTime.getTimeInMillis()+"");		// 入库时间
								detail.put("DATA_ARRIVE_TIME",format.format(arriveTime.getTime()));	// 入库时间
								detaiList.add(detail);
								//--  整理告警信息
								if(state == 0){
									String [] nums = showNumStr.split("\\|");
									String [] levels = pLevelStr.split("\\|");
									String [] values = alarmValue.split("\\|");
									List<AlarmInfo> aList = Common.getAlarmInfoMap().get(setInfoId);
									Iterator<AlarmInfo> ite = null;
									for(int m = 0 ; m<nums.length ;m++){
										String num = nums[m];
										if(StringUtils.isEmpty(num)){
											continue;
										}
										if(aList == null || aList.size() ==0){
											continue;
										}
										ite = aList.iterator();
										String cpInfo="";
										while (ite.hasNext()) {
											AlarmInfo elem = (AlarmInfo) ite.next();
											//判断告警字段和告警级别是否相等
											if(elem.getShowNum().toString().equals(nums[m])){
												/** 修正全局告警级别，取最高级别即plevel越小级别越高 **/
												logger.debug("********修正的告警级别："+elem.getPoliceLevel());
												try
												{//告警级别取决于监测数据的级别，是否紧急取决于级别（0级别：对应紧急，其它对应非紧急）
													if(pLevel >= Integer.parseInt(levels[m].trim())){
														pLevel = Integer.parseInt(levels[m].trim());
														//0级别：对应紧急，其它对应非紧急
														if(pLevel==Constants.LEVEL_OF_EMERGENCY) {
															urgentLevel = EmailTypeConstants.URGENT_IMMEDIATELY;
														}else {
															urgentLevel = EmailTypeConstants.URGENT_LATER;
														}
													}
												} catch (Exception e)
												{
													logger.error("新格式监测数据-修改正告警级别时，解析告警level:"+levels[m]+" 异常", e);
												}
												
												/** 字段名称 intDate 实际值： 80》60%（临界值） 级别 40 **/	
												String filedName = "";
												String filedComments = "";
												if(tableMap !=null){
													TableColumnsModel tm = tableMap.get(elem.getShowNum());
													filedName = tm==null?"":tm.getFiledName();
													filedComments = tm==null?"":tm.getFiledComments();
												}
												cpInfo +=  " "+(StringUtils.isEmpty(elem.getFiledCommonts())?filedName:elem.getFiledCommonts());
												cpInfo +=  " 为："+detail.get(filedName);
												cpInfo +=  (elem.getPoliceUnit()==null ? "" : "null".equals(elem.getPoliceUnit()) ? "" : elem.getPoliceUnit());
												cpInfo +=  "   报警级别："+pLevel;
												cpInfo +=  " \n";
											}
										}
										//如果是握手监测，不添加告警设置字段相关信息
										if(!Constants.DETEC_NMSC_STR.equalsIgnoreCase(checkType)) {
											alarmInfo.append(cpInfo);
										}
									}
								}
							} catch (Exception e) {
								String s = "详细数据部分解析失败"+e.getMessage();
								logger.warn(s);
							}
						}
						
						detectInfo[DetectInfo.SHOWNUMLIST] = (showNumList);
						detectInfo[DetectInfo.PLEVELLIST] = (plevelList);
						detectInfo[DetectInfo.ALARMLIST] = (alarmList);

						if(endNum ==0){
							break details;
						}
					}
					if(dsinfo.startsWith("$@$") && dsinfo.length()>3) {
						dsinfo = dsinfo.substring(3, dsinfo.length());
					}
				}
			}
		}
		if(state == -1){//监测执行失败，是最高级别的告警
			//NMSC 监测失败状态 程序设定为为紧急
			if(checkType.equalsIgnoreCase(Constants.DETEC_NMSC_STR)){
				pLevel = Constants.DETECT_FAIL_NMSC_POLICE_LEVEL;
				urgentLevel = Constants.DETECT_FAIL_NMSC_POLICE_EMERGENT;
			}else {
				pLevel = Constants.DETECT_FAIL_NON_NMSC_POLICE_LEVEL;
				urgentLevel = Constants.DETECT_FAIL_NON_NMSC_POLICE_EMERGENT;				
			}
		}
		
		//--状态信息（描述信息），
		if(StringUtils.isNotEmpty(dsinfo)){
			dsinfo = dsinfo.replaceAll("</br>", "\n");// add by zg 增加对</br>的处理 begin
			if(dsinfo.getBytes().length>Constants.VARCHAR_MAX_LENGTH){
				dsinfo = StringUtil.substring(dsinfo,Constants.VARCHAR_MAX_LENGTH);
			}
		}
		
		detectInfo[DetectInfo.STATE] = (state);
		detectInfo[DetectInfo.DSINFO] = (dsinfo);
		detectInfo[DetectInfo.PLEVEL] = (pLevel);
		detectInfo[DetectInfo.ALARMINFO] = (alarmInfo.toString());//告警信息，发送邮件的时候需要用
		detectInfo[DetectInfo.URGENTLEVEL] = (urgentLevel);//状态是否改变会影响这个告警级别
		detectInfo[DetectInfo.DELYFLAG] = (delyFlag);//根据这个参数，决定是否保存详细信息
		detectInfo[DetectInfo.DETAILS] = (detaiList);//用于批量入库详细信息
		
		//特殊追加信息解析--systeminfo-disk、net
		//-- 特殊信息保存整理
//		logger.debug("新格式解析 第七步 特殊追加信息解析"+(Constants.DETEC_SYSTEMINFO_STR.equalsIgnoreCase(checkType)));
		if(Constants.DETEC_SYSTEMINFO_STR.equalsIgnoreCase(checkType) ) {
			while (strsIte.hasNext()) {
				String [] detailsArr = strsIte.next();	//取出 
				if(detailsArr == null || detailsArr.length ==0){	//空行不解析
					continue;
				}
				if(detailsArr.length != 2){	//不是[details:0]格式无法解析
					break;
				}

				if("disk".equalsIgnoreCase(detailsArr[0])){
					List<Map<String, String>> infoList = new ArrayList<Map<String, String>>();
					int endNum = StringUtils.isEmpty(detailsArr[1])?0:Integer.parseInt(detailsArr[1]);
					disk:while (strsIte.hasNext()) {
						endNum--;
						String [] detailsArr0 = strsIte.next();	//取出
						int len = detailsArr0.length;
						Map<String, String> diskInfo = new HashMap<String, String>();
						diskInfo.put("DISK_RANG", len>0 ? detailsArr0[0]:"");//盘符
						diskInfo.put("DISK_SIZE", len>1 ? detailsArr0[1]:"");//大小
						diskInfo.put("DATA_CHECK_TIME_DIGITAL", checkTime+"");//监测时间（long）
						diskInfo.put("DATA_CHECK_TIME", format.format(new Date(checkTime)));//监测时间（date）
						diskInfo.put("DATA_ARRIVE_TIME_DIGITAL", arriveTime.getTimeInMillis()+"");////录入记录时间（当前时间 long）
						diskInfo.put("DATA_ARRIVE_TIME", format.format(arriveTime.getTime()));////录入记录时间（当前时间 date）
						diskInfo.put("DETECTION_SET_INFO_ID", setInfoId);//
						diskInfo.put("SEQ_ID", seqId);
						diskInfo.put("DETECTIONED_STATE", state+"");						
						infoList.add(diskInfo);
						if(endNum==0){
							logger.debug("disk解析完成 跳出循环");
							break disk;
						}
					}
					if(infoList.size()>0) {
						detectInfo[DetectInfo.DISKINFOLIST] = (infoList);//插入操作批量执行
					}
				}else if("net".equalsIgnoreCase(detailsArr[0])) {
					
					List<Map<String, String>> infoList = new ArrayList<Map<String, String>>();
					int endNum = StringUtils.isEmpty(detailsArr[1])?0:Integer.parseInt(detailsArr[1]);
					net:while (strsIte.hasNext()) {
						endNum--;
						String [] netInfoTmp = strsIte.next();	//取出
						int len = netInfoTmp.length;
						Map<String, String> netInfo = new HashMap<String, String>();
						netInfo.put("NET_NAME", len>0 ? netInfoTmp[0]:"");//网卡名称
						netInfo.put("NET_STATE", len>1 ? netInfoTmp[1]:"");//网卡状态
						netInfo.put("NET_SPEED", len>2 ? netInfoTmp[2]:"");//网卡带宽
						netInfo.put("NET_IP", len>3 ? netInfoTmp[3]:"");//ip
						netInfo.put("NET_SUBMASK", len>4 ? netInfoTmp[4]:"");//子网掩码
						netInfo.put("NET_GATEWAY", len>5 ? netInfoTmp[5]:"");//网关
						netInfo.put("NET_MAC", len>6 ? netInfoTmp[6]:"");//NET_MAC
						netInfo.put("DATA_CHECK_TIME", format.format(new Date(checkTime)));
						netInfo.put("DATA_ARRIVE_TIME", format.format(arriveTime.getTime()));//录入记录时间（当前时间 date）
						netInfo.put("DATA_CHECK_TIME_DIGITAL",  checkTime+"");//监测时间（long）
						netInfo.put("DATA_ARRIVE_TIME_DIGITAL", arriveTime.getTimeInMillis()+"");//录入记录时间（当前时间 long）
						netInfo.put("DETECTION_SET_INFO_ID", setInfoId);// id
						netInfo.put("SEQ_ID", seqId);
						netInfo.put("DETECTIONED_STATE", state+"");	
						infoList.add(netInfo);
						if(endNum ==0){
							break net;
						}
					}
					if(infoList.size()>0) {
						detectInfo[DetectInfo.NETINFOLIST] = (infoList);//插入操作批量执行
					}
				}
			}
		}
		if(detectInfo[DetectInfo.STATE] == null){
			detectInfo[DetectInfo.STATE] = -1;//state
		}
		if(detectInfo[DetectInfo.PLEVEL] == null){
			detectInfo[DetectInfo.PLEVEL] = 99;//pLevel
		}
		if(detectInfo[DetectInfo.DELYFLAG] == null){
			detectInfo[DetectInfo.DELYFLAG] = false;//delyFlag
		}
		if(detectInfo[DetectInfo.URGENTLEVEL] == null){
			detectInfo[DetectInfo.URGENTLEVEL] = 0;//urgentLevel
		}
		if(detectInfo[DetectInfo.SENDEMAILFLAG] == null){
			detectInfo[DetectInfo.SENDEMAILFLAG] = false;//sendEmailFlag
		}
		if(detectInfo[DetectInfo.STATECHANGEFLAG] == null){
			detectInfo[DetectInfo.STATECHANGEFLAG] = false;//stateChangeFlag
		}
		if(detectInfo[DetectInfo.STATUSCHANGTIME] == null){
			detectInfo[DetectInfo.STATUSCHANGTIME] = -1L;//statusChangeTime
		}
		return detectInfo;
	}
	
	/**
	 * 保存到硬盘
	 * @param data
	 */
	private void saveByteToFile(byte[] data) {
		String filePath = "";
		try {
			filePath = Constants.OVERRUN_DETEC_FILE_DIR + "/" + Common.getDateDirName() + "/"
					+ Calendar.getInstance().getTimeInMillis() + "_" + ((int)Math.random()*1000000 +1) + ".csv";
			FileUtils.wirteBytesToFile(data, filePath);
		} catch (Exception e) {
			logger.error("When there is too much monitoring data ,the data is stored on the hard disk exception",e);
		}
	}
	
}
