package com.nms.server.thread.monitor;

import java.math.BigDecimal;
import java.math.RoundingMode;
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.Map.Entry;
import java.util.concurrent.CountDownLatch;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.snmp4j.mp.SnmpConstants;

import com.nms.server.bean.SetInfo;
import com.nms.server.bean.TableColumnsModel;
import com.nms.server.common.Common;
import com.nms.server.common.Constants;
import com.nms.server.dao.CommonDao;
import com.nms.server.service.CommonService;
import com.nms.server.service.ThreadService;
import com.nms.server.thread.InitServerThread;
import com.nms.server.thread.monitor.test.DPSwitchProt64Data;
import com.nms.server.util.BoneCPPool;
import com.nms.server.util.CSVUtils;
import com.nms.server.util.MathUtil;
import com.nms.server.util.SNMP4JUtils;

public class SwitchPortThread implements Runnable{
	private Logger logger = Logger.getLogger(SwitchPortThread.class);
	private Long startTime = Calendar.getInstance().getTimeInMillis();
	private String name;
	private int port = Constants.SNMP_CLIENT_PORT;
	private SetInfo info ;
	private String hostIp;

	private List<String> checkTypeList;
	private CountDownLatch downLatch;
	/**
	 * 构造方法 
	 * @param name		线程名称
	 * @param host		目标Ip
	 * @param info		监测设置信息
	 */
	public SwitchPortThread(String name, String hostIp, SetInfo info,Long startTime,List<String> checkTypeList,CountDownLatch downLatch) {
		this.name = name;
		this.hostIp = hostIp;
		this.info = info;
		this.startTime = startTime;
		this.checkTypeList = checkTypeList;
		this.downLatch = downLatch;
	}
	public SwitchPortThread(String name, String hostIp, SetInfo info,Long startTime) {
		this.name = name;
		this.hostIp = hostIp;
		this.info = info;
		this.startTime = startTime;
		this.checkTypeList = checkTypeList;
		this.downLatch = downLatch;
	}
	public SwitchPortThread() {
		
	}	
	

	/* 
	 * 通过SNMP4J GET获取
	 */
	public void run() {
		Thread.currentThread().setName("交换机监测 " + hostIp);
		try {
			/* 准备公共信息 */
			
			//-- 校验ifXTable 对应名称（忽略大小写处理）
			String ifxtableName = Constants.DETEC_IFXTABLE_STR;
			if(Common.getCheckTypeNameMape().get(ifxtableName)==null){
				Iterator<String> ite = Common.getCheckTypeNameMape().keySet().iterator();
				while (ite.hasNext()) {
					String checkTypeName = (String) ite.next();
					if(ifxtableName.equalsIgnoreCase(checkTypeName)){
						ifxtableName = checkTypeName;
					}
				}
			}
			
			//- 通过 CloumnsMap 获取 oids
			List<String> oidList = getOidListByCheckTypeName(info.getCheckTypeName());//获取 oids			
			List<String> oidIfXTabList = getOidListByCheckTypeName(ifxtableName);//ifXTable:应该循环checkTypeList列表?	
			
			//- 版本
			int version = Common.getSnmpVerByUUID(Common.getIpSeqIdMap().get(hostIp));
		
			//-- 执行和解析 即获取详细数据
			int retries = info.getCheckMaxTimes()==null?3:info.getCheckMaxTimes().intValue();
			int timeout = info.getCheckOutTime() == null?20000:info.getCheckOutTime().intValue()*1000;
			int state = -1;//detection_info表的DETECTIONED_STATE状态，-1执行不成功；0不正常；1正常

			StringBuffer stateInfo = new StringBuffer();
			List<List<String>> snmpDatasList1 = new LinkedList<List<String>>();//为了入库，不包含oid，通过get(i)获取
			List<List<String>> snmpDatasList2 = new LinkedList<List<String>>();
			List<Map<String, String>> datasMapList1 = new ArrayList<Map<String,String>>();//一个端口有多种属性值，一个端口一个map，多个端口map的list：List<Map<oid,value>>
			List<Map<String, String>> datasMapList2 = new ArrayList<Map<String,String>>();//为了计算，包含oid
			String rootOid = Common.getInsertTable().get(info.getCheckTypeName()).getOid();
			logger.info("rootOid :"+rootOid);
			//ifXTable
			Map<String,Map<String, String>> ifXTabdatasMapList1 = new HashMap<String,Map<String,String>>();
			Map<String,Map<String, String>> ifXTabdatasMapList2 = new HashMap<String,Map<String,String>>();
			String ifXTabRootOid = Common.getInsertTable().get(ifxtableName).getOid();
			logger.info("ifXTabRootOid :"+ifXTabRootOid);
			Map<String, String> mapForDPIfXTab = DPSwitchProt64Data.mapForDPIfXTable();
			
			/* 执行二次监测 */
			int waitTime = 30;
			long stime32 = 0;
			long stime64 = 0;
			long etime32 = 0;
			long etime64 = 0;
			boolean dataFlag64 = true;
			double value64 = (1d+Long.MAX_VALUE)*2;
			double value32 = (1d+Integer.MAX_VALUE)*2;
			try {
				//第一次取值
				//32位数据
				snmpDatasList1 = resoveVersion(datasMapList1,oidList,rootOid,version,retries,timeout,stateInfo);
				stime32 = System.currentTimeMillis();
				//64位数据
				resoveIfXTabVersion(ifXTabdatasMapList1,oidIfXTabList,ifXTabRootOid,version,retries,timeout,stateInfo);
				stime64 = System.currentTimeMillis();
				//间隔时间
				Thread.sleep(waitTime*1000);
				
				//第二次取值
				snmpDatasList2 = resoveVersion(datasMapList2,oidList,rootOid,version,retries,timeout,stateInfo);
				etime32 = System.currentTimeMillis();
				resoveIfXTabVersion(ifXTabdatasMapList2,oidIfXTabList,ifXTabRootOid,version,retries,timeout,stateInfo);
				etime64 = System.currentTimeMillis();
//				dataFlag64 = false;
				if(ifXTabdatasMapList2.size()>0 && ifXTabdatasMapList1.size()>0 && dataFlag64){
					dataFlag64 = true;
					waitTime = new BigDecimal((etime64 - stime64)/1000+0.49d).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
					//替换snmpDatasList2的数据
					logger.info("采用64位的数据，开始替换：将32位数据替换为64位数据");
					replaceValueByKeyMapForListData(snmpDatasList1,info.getCheckTypeName(),rootOid,datasMapList1, mapForDPIfXTab, ifXTabdatasMapList1);
					replaceValueByKeyMapForListData(snmpDatasList2,info.getCheckTypeName(),rootOid,datasMapList2, mapForDPIfXTab, ifXTabdatasMapList2);
				}else{//64位没取成功，则按32的进行计算，不用替换
					dataFlag64 = false;
					waitTime = new BigDecimal((etime32 - stime32)/1000+0.49d).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
					logger.info("采用32位的数据");
				}
				logger.debug("dataFlag64 value "+(dataFlag64));
				logger.debug("waitTime value "+(waitTime)+" s");
				state = 1;
			} catch (Exception e) {
				state = -1;
				stateInfo.append(e.getMessage());
				logger.error((version == SnmpConstants.version3?"version3":"version2c")+" GET失败", e);
			}
		

			
			/** 
			 * 二次计算
				平均输入速率=△ifInOctets/T
			    平均输出速率=△ifOutOctets/T
			    //输入利用率=（△ifInOctets*8）/（ifSpeed*T）*100%
			    //输出利用率=（△ifOutOctets*8）/（ifSpeed*T）*100%
			    平均收包速率=（△ifInUcastPkts+△ifInNucastPkts）/T
			    平均发包速率=（△ifOutUcastPks+△ifOutNucastPks）/T
			    输入丢包率=△ifInDiscards/（△ifInUcastPkts+△ifInNucastPkts）*100%
			    输出丢包率=△ifOutDiscards/（△ifOutUcastPks+△ifOutNucastPks）*100%
			    输入差错率=△ifInErrors/（△ifInUcastPkts+△ifInNucastPkts）*100%
			    输出差错率=△ifOutErrors/（△ifOutUcastPkts+△ifOutNucastPkts）*100%
			    //输入吞吐量=（△ifInOctets-△ifInDiscards-△ifInErrors）/T
			    //输出吞吐量=（△ifOutOctets-△ifOutDiscards-△ifOutErrors）/T
			     * 
			     *0319 计算变更
			     *丢包数：无需计算
			     *
			 */
			
			
			
			//索取字段OID：
			 /*
			  
			  ifInOctets      NUMBER       ;  -- 输入字节数  1.3.6.1.2.1.2.2.1.10
			  ifInUcastPkts     NUMBER       ; -- 单点输入总包数  1.3.6.1.2.1.2.2.1.11
			  ifInNucastPkts     NUMBER       ; -- 输出字节数   1.3.6.1.2.1.2.2.1.12
			  ifInDiscards     NUMBER       ; -- 输出字节数   1.3.6.1.2.1.2.2.1.13
			  ifInErrors      NUMBER       ;  -- 输入错包数  1.3.6.1.2.1.2.2.1.14
			  
			  
			  ifOutOctets     NUMBER       ; -- 输出字节数   1.3.6.1.2.1.2.2.1.16
			  ifOutUcastPkts     NUMBER       ; -- 输出字节数   1.3.6.1.2.1.2.2.1.17
			  ifOutNucastPkts     NUMBER      ; -- 输出输出总包数  1.3.6.1.2.1.2.2.1.18
			  ifOutDiscards     NUMBER       ; -- 输出字节数  1.3.6.1.2.1.2.2.1.19
			  ifOutErrors     NUMBER       ; -- 输出错包数   1.3.6.1.2.1.2.2.1.20
			  
			  
			  

			*/
			
			if(datasMapList1.size()>0 && datasMapList2.size()>0){
				//循环每行数据
				Double defaultVal = 0d;
				for(int i = 0 ; i<datasMapList2.size() ; i++){//一个端口一条记录，每个端口都计算值
					Map<String, String> dm2 =  datasMapList2.get(i);
					Double ifInOctets_n = StringUtils.isBlank(dm2.get("1.3.6.1.2.1.2.2.1.10"))?defaultVal : Double.parseDouble(dm2.get("1.3.6.1.2.1.2.2.1.10"));
					Double ifInUcastPkts_n = StringUtils.isBlank(dm2.get("1.3.6.1.2.1.2.2.1.11"))?defaultVal : Double.parseDouble(dm2.get("1.3.6.1.2.1.2.2.1.11"));
					Double ifInNucastPkts_n = StringUtils.isBlank(dm2.get("1.3.6.1.2.1.2.2.1.12"))?defaultVal : Double.parseDouble(dm2.get("1.3.6.1.2.1.2.2.1.12"));
					Double ifInDiscards_n = StringUtils.isBlank(dm2.get("1.3.6.1.2.1.2.2.1.13"))?defaultVal : Double.parseDouble(dm2.get("1.3.6.1.2.1.2.2.1.13"));
					Double ifInErrors_n = StringUtils.isBlank(dm2.get("1.3.6.1.2.1.2.2.1.14"))?defaultVal : Double.parseDouble(dm2.get("1.3.6.1.2.1.2.2.1.14"));
					
					Double ifOutOctets_n = StringUtils.isBlank(dm2.get("1.3.6.1.2.1.2.2.1.16"))?defaultVal : Double.parseDouble(dm2.get("1.3.6.1.2.1.2.2.1.16"));
					Double ifOutUcastPkts_n = StringUtils.isBlank(dm2.get("1.3.6.1.2.1.2.2.1.17"))?defaultVal : Double.parseDouble(dm2.get("1.3.6.1.2.1.2.2.1.17"));
					Double ifOutNucastPkts_n = StringUtils.isBlank(dm2.get("1.3.6.1.2.1.2.2.1.18"))?defaultVal : Double.parseDouble(dm2.get("1.3.6.1.2.1.2.2.1.18"));
					Double ifOutDiscards_n = StringUtils.isBlank(dm2.get("1.3.6.1.2.1.2.2.1.19"))?defaultVal : Double.parseDouble(dm2.get("1.3.6.1.2.1.2.2.1.19"));
					Double ifOutErrors_n = StringUtils.isBlank(dm2.get("1.3.6.1.2.1.2.2.1.20"))?defaultVal : Double.parseDouble(dm2.get("1.3.6.1.2.1.2.2.1.20"));
					
					Map<String, String> dm1 =  datasMapList1.get(i);
					Double ifInOctets_o = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.2.2.1.10"))?defaultVal : Double.parseDouble(dm1.get("1.3.6.1.2.1.2.2.1.10"));
					Double ifInUcastPkts_o = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.2.2.1.11"))?defaultVal : Double.parseDouble(dm1.get("1.3.6.1.2.1.2.2.1.11"));
					Double ifInNucastPkts_o = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.2.2.1.12"))?defaultVal : Double.parseDouble(dm1.get("1.3.6.1.2.1.2.2.1.12"));
					Double ifInDiscards_o = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.2.2.1.13"))?defaultVal : Double.parseDouble(dm1.get("1.3.6.1.2.1.2.2.1.13"));
					Double ifInErrors_o = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.2.2.1.14"))?defaultVal : Double.parseDouble(dm1.get("1.3.6.1.2.1.2.2.1.14"));
					
					Double ifOutOctets_o = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.2.2.1.16"))?defaultVal : Double.parseDouble(dm1.get("1.3.6.1.2.1.2.2.1.16"));
					Double ifOutUcastPkts_o = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.2.2.1.17"))?defaultVal : Double.parseDouble(dm1.get("1.3.6.1.2.1.2.2.1.17"));
					Double ifOutNucastPkts_o = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.2.2.1.18"))?defaultVal : Double.parseDouble(dm1.get("1.3.6.1.2.1.2.2.1.18"));
					Double ifOutDiscards_o = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.2.2.1.19"))?defaultVal : Double.parseDouble(dm1.get("1.3.6.1.2.1.2.2.1.19"));
					Double ifOutErrors_o = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.2.2.1.20"))?defaultVal : Double.parseDouble(dm1.get("1.3.6.1.2.1.2.2.1.20"));
					//既然上面为空，则下面使用之前需进行判空处理
					
					//打印日志 2014-2-18 hyx------------------------------------------------------------------------------
					String curTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
					String desc = dm1.get("1.3.6.1.2.1.2.2.1.2");
					Double ifSpeedTmp = 0d;
					Double ifHigeSpeedTmp = 0d;
					Double speedTmp = 0d;
					try
					{
						ifSpeedTmp = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.2.2.1.5"))?defaultVal : Double.parseDouble(dm1.get("1.3.6.1.2.1.2.2.1.5"));
						ifHigeSpeedTmp = StringUtils.isBlank(dm1.get("1.3.6.1.2.1.31.1.1.1.15.1.1000000"))?null : Double.parseDouble(dm1.get("1.3.6.1.2.1.31.1.1.1.15.1.1000000"));
						if(ifHigeSpeedTmp!=null) {
							speedTmp = ifHigeSpeedTmp*1000*1000;
						}else {
							speedTmp = ifSpeedTmp;							
						}
					} catch (Exception e)
					{
						logger.error("获取ifSpeed 或者 ifHighSpeed 异常", e);
					}
					logger.info("ifSpeed："+ifSpeedTmp+"    ifHighSPeed:"+ifHigeSpeedTmp+"   speed:"+speedTmp);
					
					/* 平均输入速率=△ifInOctets/T 单位：bps */
					double dInOctetsL = (ifInOctets_n - ifInOctets_o);			
					
					logger.info(hostIp+"-"+desc+"-"+curTime+"-输入字节数之差:"+dInOctetsL+"="+ifInOctets_n+"-"+ifInOctets_o);
					
					//非负数处理
					BigDecimal ifInOctetsSpeed = null;
					if(dInOctetsL<0){
						double dInOctetsLTmp = dInOctetsL;
						if(dataFlag64){	//64位数据
							dInOctetsL = dInOctetsLTmp + value64;
							logger.info(hostIp+"-"+desc+"-"+curTime+"-输入字节数之差小于0,64位:"+dInOctetsL+"="+dInOctetsLTmp+"+"+value64);
							ifInOctetsSpeed = new BigDecimal(dInOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
							//如果按64位进行计算，得到的速度大于带宽，则按32位计算
							if(speedTmp>0d && ifInOctetsSpeed.doubleValue()>speedTmp) {//ifHigeSpeedTmp的单位为Mbps
								dInOctetsL = dInOctetsLTmp + value32;
								logger.info(hostIp+"-"+desc+"-"+curTime+"-输入字节数之差小于0,按64位算，得到的速度大于带宽，改按32位计算:"+dInOctetsL+"="+dInOctetsLTmp+"+"+value32);
								ifInOctetsSpeed = new BigDecimal(dInOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
								if(ifInOctetsSpeed.doubleValue()>speedTmp) {//如果改按32位计算，还是大，
									logger.info(hostIp+"-64位改为32为计算，输入速度还是大于带宽");
								}
							}
						}else{	//32位数据
							dInOctetsL += value32;
							logger.info(hostIp+"-"+desc+"-"+curTime+"-输入字节数之差小于0,32位:"+dInOctetsL+"="+dInOctetsLTmp+"+"+value32);
							ifInOctetsSpeed = new BigDecimal(dInOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
							if(speedTmp>0d && ifInOctetsSpeed.doubleValue()>speedTmp) {//ifSpeedTmp的单位为bps
								dInOctetsL = dInOctetsLTmp + value64;
								logger.info(hostIp+"-"+desc+"-"+curTime+"-输入字节数之差小于0,按32位算，得到的速度大于带宽，改按64位计算:"+dInOctetsL+"="+dInOctetsLTmp+"+"+value64);
								ifInOctetsSpeed = new BigDecimal(dInOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
								if(ifInOctetsSpeed.doubleValue()>speedTmp) {//如果改按64位计算，还是大，
									logger.info(hostIp+"-32位改为64为计算，输入速度还是大于带宽");
								}
							}
						}
					}else {
						ifInOctetsSpeed = new BigDecimal(dInOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
					}
//					BigDecimal ifInOctetsSpeed = new BigDecimal(dInOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
					
					logger.info(hostIp+"-"+desc+"-"+curTime+"-输入速度（位速度）:"+ifInOctetsSpeed);
					
					//------------------------------------------------------------------------------------------------------
					/* 平均输出速率=△ifOutOctets/T 单位：bps */
					double dOutOctetsL= (ifOutOctets_n - ifOutOctets_o);
					logger.info(hostIp+"-"+desc+"-"+curTime+"-输出字节数之差:"+dOutOctetsL+"="+ifOutOctets_n+"-"+ifOutOctets_o);
					
					//非负数处理
					BigDecimal ifOutOctetsSpeed = null;
					if(dOutOctetsL<0){
						double dOutOctetsLTmp = dOutOctetsL;
						if(dataFlag64){	//64位数据
							dOutOctetsL += value64;
							logger.info(hostIp+"-"+desc+"-"+curTime+"-输出字节数之差小于0,64位:"+dOutOctetsL+"="+dOutOctetsLTmp+"+"+value64);							
							ifOutOctetsSpeed = new BigDecimal(dOutOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
							
							//如果按64位进行计算，得到的速度大于带宽，则按32位计算
							if(speedTmp>0d && ifOutOctetsSpeed.doubleValue()>speedTmp) {//ifHigeSpeedTmp的单位为Mbps
								dOutOctetsL = dOutOctetsLTmp + value32;
								logger.info(hostIp+"-"+desc+"-"+curTime+"-输出字节数之差小于0,按64位算，得到的速度大于带宽，改按32位计算:"+dOutOctetsL+"="+dOutOctetsLTmp+"+"+value32);
								ifOutOctetsSpeed = new BigDecimal(dOutOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
								if(ifOutOctetsSpeed.doubleValue()>speedTmp) {//如果改按32位计算，还是大，
									logger.info(hostIp+"-64位改为32为计算，输出速度还是大于带宽");
								}
							}
						}else{//32位数据
							dOutOctetsL += value32;
							logger.info(hostIp+"-"+desc+"-"+curTime+"-输出字节数之差小于0,32位:"+dOutOctetsL+"="+dOutOctetsLTmp+"+"+value32);							
							ifOutOctetsSpeed = new BigDecimal(dOutOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
							
							if(speedTmp>0d && ifOutOctetsSpeed.doubleValue()>speedTmp) {//ifSpeedTmp的单位为bps
								dOutOctetsL = dOutOctetsLTmp + value64;
								logger.info(hostIp+"-"+desc+"-"+curTime+"-输出字节数之差小于0,按32位算，得到的速度大于带宽，改按64位计算:"+dOutOctetsL+"="+dOutOctetsLTmp+"+"+value64);
								ifOutOctetsSpeed = new BigDecimal(dOutOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
								if(ifOutOctetsSpeed.doubleValue()>speedTmp) {//如果改按64位计算，还是大，
									logger.info(hostIp+"-32位改为64为计算，输出速度还是大于带宽");
								}
							}
						}
					}else {
						ifOutOctetsSpeed = new BigDecimal(dOutOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
					}
//					BigDecimal ifOutOctetsSpeed = new BigDecimal(dOutOctetsL).multiply(new BigDecimal(8)).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
					
					logger.info(hostIp+"-"+desc+"-"+curTime+"-输出速度（位速度）:"+ifOutOctetsSpeed);
					
					
					/* 平均收包速率=（△ifInUcastPkts+△ifInNucastPkts）/T 单位：pps */
					double iupks = ifInUcastPkts_n - ifInUcastPkts_o;//输入单向包
					if(iupks <0){
						if(dataFlag64){	//64位数据
							iupks += value64;
						}else{	//32位数据
							iupks += value32;
						}
					}
					
					double inupks = ifInNucastPkts_n - ifInNucastPkts_o;//输入非单向包
					if(inupks <0){
						if(dataFlag64){	//64位数据
							inupks += value64;
						}else{	//32位数据
							inupks += value32;
						}
					}
					
					double dInPks= (iupks)+(inupks);
					
//					BigDecimal inPksSpeed = new BigDecimal(dInPks).divide(new BigDecimal(waitTime),2, RoundingMode.HALF_UP);
//					BigDecimal inPksSpeed = new BigDecimal(dInPks).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
					BigDecimal inPksSpeed = new BigDecimal(dInPks).divide(new BigDecimal(waitTime),0, RoundingMode.UP);//平均收包速率，向上取整
					
					/* 平均发包速率=（△ifOutUcastPks+△ifOutNucastPks）/T 单位：pps */
					double oupks = ifOutUcastPkts_n - ifOutUcastPkts_o;
					if(oupks <0){
						if(dataFlag64){	//64位数据
							oupks += value64;
						}else{	//32位数据
							oupks += value32;
						}
					}
					
					double onupks = ifOutNucastPkts_n - ifOutNucastPkts_o;
					if(onupks <0){
						if(dataFlag64){	//64位数据
							onupks += value64;
						}else{	//32位数据
							onupks += value32;
						}
					}
					
					double dOutPks= (oupks)+(onupks);
					
//					BigDecimal outPksSpeed = new BigDecimal(dOutPks).divide(new BigDecimal(waitTime),2, RoundingMode.HALF_UP);
//					BigDecimal outPksSpeed = new BigDecimal(dOutPks).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
					BigDecimal outPksSpeed = new BigDecimal(dOutPks).divide(new BigDecimal(waitTime),0, RoundingMode.UP);////平均发包速率，向上取整
					
					/* 输入丢包率=△ifInDiscards/（△ifInUcastPkts+△ifInNucastPkts）*100% */
					BigDecimal inDiscardsPerc = new BigDecimal(0);
					if(dInPks != 0){
						inDiscardsPerc = new BigDecimal(ifInDiscards_n - ifInDiscards_o).divide(new BigDecimal(dInPks),2, RoundingMode.HALF_UP);
					}
					
					
					/* 输出丢包率=△ifOutDiscards/（△ifOutUcastPks+△ifOutNucastPks）*100% */
					BigDecimal outDiscardsPerc = new BigDecimal(0);
					if(dOutPks != 0){
						outDiscardsPerc = new BigDecimal(ifOutDiscards_n - ifOutDiscards_o).divide(new BigDecimal(dOutPks),2, RoundingMode.HALF_UP);
					}
					
					
					/* 输入差错率=△ifInErrors/（△ifInUcastPkts+△ifInNucastPkts）*100% */
//					BigDecimal ifInErrorsPerc = new BigDecimal(ifInErrors_n - ifInErrors_o).divide(new BigDecimal(waitTime),2, RoundingMode.HALF_UP);
					BigDecimal ifInErrorsPerc = new BigDecimal(ifInErrors_n - ifInErrors_o).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
					
					/* 输出差错率=△ifOutErrors/（△ifOutUcastPkts+△ifOutNucastPkts）*100% */
//					BigDecimal ifOutErrorsPerc = new BigDecimal(ifOutErrors_n - ifOutErrors_o).divide(new BigDecimal(waitTime),2, RoundingMode.HALF_UP);
					BigDecimal ifOutErrorsPerc = new BigDecimal(ifOutErrors_n - ifOutErrors_o).divide(new BigDecimal(waitTime),2, RoundingMode.UP);
					
					//-- 计算输入输出速度
					
					double ifinoctetsspeed_a = ifInOctetsSpeed.doubleValue();  //--单位bps
					double ifoutoctetsspeed_a = ifOutOctetsSpeed.doubleValue();  //--单位bps
					
					double inPksSpeed_a = inPksSpeed.doubleValue();  //--单位pps
					double outPksSpeed_a = outPksSpeed.doubleValue();  //--单位pps
					
					double ifOutDiscards_a = outDiscardsPerc.doubleValue();  //--单位
					double ifInDiscards_a = inDiscardsPerc.doubleValue();  //--单位
					
					double ifInErrors_a = ifInErrorsPerc.doubleValue();  //--单位
					double ifOutErrors_a = ifOutErrorsPerc.doubleValue();  //--单位
					
					
//					logger.debug("ifinoctetsspeed_a:"+ifinoctetsspeed_a);
//					logger.debug("inPksSpeed_a:"+inPksSpeed_a);
//					logger.debug("ifInDiscards_a:"+ifInDiscards_a);
//					logger.debug("ifInErrors_a:"+ifInErrors_a);
//					
//					logger.debug("ifoutoctetsspeed_a:"+ifoutoctetsspeed_a);
//					logger.debug("outPksSpeed_a:"+outPksSpeed_a);
//					logger.debug("ifOutDiscards_a:"+ifOutDiscards_a);
//					logger.debug("ifOutErrors_a:"+ifOutErrors_a);
					
					//
					
					snmpDatasList2.get(i).remove((23-1));	//list中多余的数据
					snmpDatasList2.get(i).add((23-1),ifinoctetsspeed_a<0?"":ifinoctetsspeed_a+"");
					snmpDatasList2.get(i).remove((24-1));
					snmpDatasList2.get(i).add((24-1),inPksSpeed_a<0?"":inPksSpeed_a+"");
					snmpDatasList2.get(i).remove((25-1));
					snmpDatasList2.get(i).add((25-1),ifInDiscards_a<0?"":ifInDiscards_a+"");
					snmpDatasList2.get(i).remove((26-1));
					snmpDatasList2.get(i).add((26-1),ifInErrors_a<0?"":ifInErrors_a+"");
					
					snmpDatasList2.get(i).remove((27-1));
					snmpDatasList2.get(i).add((27-1),ifoutoctetsspeed_a<0?"":ifoutoctetsspeed_a+"");
					snmpDatasList2.get(i).remove((28-1));
					snmpDatasList2.get(i).add((28-1),outPksSpeed_a<0?"":outPksSpeed_a+"");
					snmpDatasList2.get(i).remove((29-1));
					snmpDatasList2.get(i).add((29-1),ifOutDiscards_a<0?"":ifOutDiscards_a+"");
					snmpDatasList2.get(i).remove((30-1));
					snmpDatasList2.get(i).add((30-1),ifOutErrors_a<0?"":ifOutErrors_a+"");
					
					//zhui加1的数据--t1的测试用的值
					snmpDatasList2.get(i).remove((31-1));
					snmpDatasList2.get(i).add((31-1),ifInOctets_o+"");
					snmpDatasList2.get(i).remove((32-1));
					snmpDatasList2.get(i).add((32-1),ifInUcastPkts_o+"");
					snmpDatasList2.get(i).remove((33-1));
					snmpDatasList2.get(i).add((33-1),ifInNucastPkts_o+"");
					snmpDatasList2.get(i).remove((34-1));
					snmpDatasList2.get(i).add((34-1),ifOutOctets_o+"");
					snmpDatasList2.get(i).remove((35-1));
					snmpDatasList2.get(i).add((35-1),ifOutUcastPkts_o+"");
					snmpDatasList2.get(i).remove((36-1));
					snmpDatasList2.get(i).add((36-1),ifOutNucastPkts_o+"");
					snmpDatasList2.get(i).remove((38-1));
					snmpDatasList2.get(i).add((38-1),(dataFlag64?1:0)+"");
					
					//计算存在小于0的值时，输出
					if(ifinoctetsspeed_a<0
							|| inPksSpeed_a<0
							|| ifInDiscards_a<0
							|| ifInErrors_a<0
							|| ifoutoctetsspeed_a<0
							|| outPksSpeed_a<0
							|| ifOutDiscards_a<0
							|| ifOutErrors_a<0){
						logger.info("Exception SwitchPortInfo Old:> "+Arrays.toString(snmpDatasList1.get(i).toArray()));
						logger.info("Exception SwitchPortInfo New:> "+Arrays.toString(snmpDatasList2.get(i).toArray()));
					}
					
				}
			}
			
			//- 监测数据集合
			List<String> pubDatas = new ArrayList<String>(); // 拼写数据格式

			//- DetecDatas 拼写 Header
			pubDatas.add(Common.getIpSeqIdMap().get(hostIp)+"");// uuid，
			pubDatas.add(info.getId() + "");// 监测设置ID，
			pubDatas.add(info.getCheckTypeName());// 监测类别，
			pubDatas.add(info.getProcessIden());// 进程名称（检查类别设置名称），
			pubDatas.add(startTime + "");// 监测服务启动时间，
			pubDatas.add(timeout+"");// 检测时延（秒）
			//- 当前检测时间
			Calendar checkTime = Calendar.getInstance();
			pubDatas.add(checkTime.getTimeInMillis() + "");// 本次检测时间，
			pubDatas.add(retries + "");// 尝试次数，
			//- 下次检测时间
			Calendar nextTime = Calendar.getInstance();
			nextTime.add(Calendar.MINUTE, info.getCheckGap().intValue());
			pubDatas.add(nextTime.getTimeInMillis() + "");// 下次计划监测时间，
			
			//- DetecDatas 拼写 Body
			List<List<String>> pubDatasList = new ArrayList<List<String>>();
			if(state != -1){//执行成功了
				pubDatasList = datasBody(retries,stateInfo.toString(),state,snmpDatasList2);
				
				//64位获取失败告警
				if(!dataFlag64){
					state=0;
					stateInfo.insert(0, "获取64位数据失败，使用32位数据计算\n");
				}
			}
			
			pubDatas.add(state+""); // 执行状态--detection_info表的监测状态
			pubDatas.add(stateInfo.toString()); // 状态信息（描述信息），
			pubDatas.add(""); // 性能数据，
			
			if(pubDatasList.size()>0){
				pubDatasList.add(0,Arrays.asList(new String[]{"details",pubDatasList.size()+""}));
			}
			pubDatasList.add(0,pubDatas);
			
			//- 存入缓存
			if(pubDatasList!=null && pubDatasList.size()>0){
				try {
					//添加监测数据到缓存，等待监测数据解析线程的解析入库
					Common.addDeteData(CSVUtils.csvFilePrinter(pubDatasList, Constants.COMMON_TEXT_CODING));
					logger.debug("监测数据以 CSV格式 保存完成");
				} catch (Exception e) {
					logger.error("监测数据以 CSV格式 保存异常", e);
				}
			}
		} catch (Exception e) {
			String[] alarm = Common.alarmExceptionInfo(info.getId(), hostIp, info.getCheckTypeName(), info.getProcessIden(), startTime, 1,Constants.DETECTION_INFO_ALARM_WRONG, e.getMessage());
			Common.addAlarmData(alarm);
			logger.error("程序错误 未知", e);
		}finally{
			if(downLatch != null){
				downLatch.countDown();
			}
		}
	}
	
	//返回监测类别checkTypeName的List<oid>
	private List<String> getOidListByCheckTypeName(String checkTypeName){
//		Map<String,String> oidFiledNameMap= new HashMap<String,String>();
		List<String> oidList = new ArrayList<String>();
		Map<Integer,TableColumnsModel> CloumnsMap = Common.getTableMap().get(checkTypeName);//Integer是metadata表里的shouNum（组合cvs文件时字段的顺序）--解析字段的顺序
		if(CloumnsMap!=null && CloumnsMap.size()>0){
			Iterator<Entry<Integer, TableColumnsModel>> entryIte = CloumnsMap.entrySet().iterator();
			while (entryIte.hasNext()) {
				Entry<Integer, TableColumnsModel> cloumnEntry = (Entry<Integer, TableColumnsModel>) entryIte.next();
				String oid = cloumnEntry.getValue().getOid();
//				String name = cloumnEntry.getValue().getFiledName();
				if (StringUtils.isNotEmpty(oid)){
//					oidFiledNameMap.put(oid, name);
					oidList.add(oid);
				}
			}
		}
		return oidList;
	}
	
	/**
	 * 将oldmap里的值，替换成subMap对应的value。
	 *       keyMap:为oldMap和subMap的key的对应关系,Map<oldOid,subOid>
	 *       oldMap:List<Map<oid,value>>
	 *       subMap:Map<index,<Map<oid,value>>
	 *       aimMap:oldMap替换后的值List<Map<oid,value>>
	 */
	private void replaceValueByKeyMapForListData(List<List<String>> snmpDateList,String checkTypeName,String rootOid,List<Map<String, String>>  oldMap,Map<String, String> keyMap,Map<String,Map<String, String>> subMap) {//List<Map<String, String>>
		
		//循环keyMap
		if(keyMap!=null && keyMap.size()>0){
			logger.info(hostIp+"-开始进行64位数据和32位数据的替换");
			logger.info(hostIp+"-替换前32的数据");
			if(oldMap!=null && oldMap.size()>0) {
				for(Map<String,String> tmpMa:oldMap) {
					Iterator<Entry<String, String>> oi = tmpMa.entrySet().iterator();
					while(oi.hasNext()) {
						Entry<String, String> en2 =oi.next();
						logger.info(hostIp+"-替换前32的值："+en2.getKey()+":"+en2.getValue());
					}
					logger.info("======"+hostIp+"=====");
				}
			}
			
			logger.info(hostIp+"-替换前64的数据");
			Iterator<Entry<String,Map<String, String>>> oiSum =  subMap.entrySet().iterator();
			while(oiSum!=null && oiSum.hasNext()) {
				Entry<String,Map<String, String>> oi = oiSum.next();
				Map<String,String> mapTmp = oi.getValue();
				Iterator<Entry<String, String>> oi2 = mapTmp.entrySet().iterator();
				logger.info("key:"+oi.getKey()+"---");
				while(oi2.hasNext()) {
					Entry<String, String> en2 =oi2.next();
					logger.info(hostIp+"-替换前64的值："+en2.getKey()+":"+en2.getValue());
				}
				logger.info("======"+hostIp+"=====");
			}
			
			Map<Integer, TableColumnsModel> columnsMap = Common.getTableMap().get(checkTypeName);
			Iterator<Entry<String, String>> entryIte = keyMap.entrySet().iterator();
			Iterator<Entry<Integer, TableColumnsModel>> tcIte = null;
			while (entryIte.hasNext()) {
				Entry<String, String> oidToNewOidEntry = (Entry<String, String>) entryIte.next();
				String oldOid = oidToNewOidEntry.getKey();//32位：原oid
				String newOid = oidToNewOidEntry.getValue();//64位：对应oid
				
				//获取数据表结构
				tcIte = columnsMap.entrySet().iterator();
				logger.info(hostIp+"-tcIte:"+tcIte+"(switchport对应的metadata表的信息)");
				int showNum = 0;
				while (tcIte.hasNext()) {
					Entry<Integer, TableColumnsModel> elem = tcIte.next();
					if(elem !=null && elem.getValue()!=null && elem.getValue().getOid()!=null){
						if(elem.getValue().getOid().equals(oldOid)){
							showNum = elem.getKey();
							break;
						}
					}
				}
//				logger.debug("showNum"+showNum);
				
				for(int i = 0 ; i<snmpDateList.size();i++){
					if(oldMap.size()>i){
						Map<String, String> tmpMap = oldMap.get(i);//一个口的所有oid：  oid：value
//						logger.debug("tmpSubMap size "+Arrays.toString(tmpMap.keySet().toArray()));
						String ifIndex = tmpMap.get(rootOid+".1");//某个端口的ifIndex属性的值，即端口的编号
						logger.info("转换Unsigned前端口index ："+ifIndex);
						try {
							if(StringUtils.isNotBlank(ifIndex) && Integer.valueOf(ifIndex.trim()) < 0) {
								String ifIndexTmp = "";
								ifIndexTmp = MathUtil.getUnsignedIntt(Integer.valueOf(ifIndex.trim()))+"";
								ifIndex = ifIndexTmp;
								logger.info("转换Unsigned后端口index："+ifIndex);
							}
						} catch (Exception e)
						{
							logger.error("Transform the Unsigned port index ："+ifIndex+" exception", e);
						}
//						logger.debug("ifIndex "+ifIndex);
						List<String> snmpData  = snmpDateList.get(i);
						Map<String,String> tmpSubMap = subMap.get(ifIndex);
//						logger.debug("ifIndex "+(ifIndex));
//						logger.debug("tmpSubMap "+(JSONArray.fromObject(tmpSubMap).toString()));
//						logger.debug("tmpSubMap "+(tmpSubMap==null?null:(Arrays.toString(tmpSubMap.keySet().toArray()))));
						if(tmpSubMap!=null && tmpSubMap.size()>0) {
							String newVal = tmpSubMap.get(newOid);
							//tmpMap.put(oldOid, newVal);
//							String vaString = oldOid+" Map["+tmpMap.get(oldOid)+" vs "+newVal+"] ";
//							vaString+="snmpData["+snmpData.get(showNum-1)+"]";
//							logger.debug(vaString);
							snmpData.remove(showNum-1);
							snmpData.add(showNum-1,newVal);
							tmpMap.put(oldOid,newVal);
							logger.info(hostIp+"-"+ifIndex+"-替换过程中的值："+oldOid+":"+newVal);
						}else {//如果匹配不上，打印信息
							logger.info("端口："+ifIndex+"在64位数据里无对应值");
						}
					}
				}				
				
			}
			for(Map<String,String> tmpMa:oldMap) {
				Iterator<Entry<String, String>> oi = tmpMa.entrySet().iterator();
				while(oi.hasNext()) {
					Entry<String, String> en2 =oi.next();
					logger.info(hostIp+"-替换后的值oldOid:newValue："+en2.getKey()+":"+en2.getValue());
				}
				logger.info("======"+hostIp+"替换后=====");
			}
		}
	
		
	}
	private void pl(Object obj){
		System.out.println(obj==null?null:obj.toString());
	}
	
	/**
	 * 将oldMap里的值，替换成subMap对应的value。
	 *       keyMap:为oldMap和subMap的key的对应关系,Map<oldOid,subOid>
	 *       oldMap:List<Map<oid,value>>
	 *       subMap:Map<index,<Map<oid,value>>
	 *       aimMap:oldMap替换后的值List<Map<oid,value>>
	 */
	private void replaceValueByKeyMap(List<Map<String, String>> oldMap,Map<String, String> keyMap,Map<String,Map<String, String>> subMap,String rootOid) {//List<Map<String, String>>
		//循环keyMap
		if(keyMap!=null && keyMap.size()>0){
			Iterator<Entry<String, String>> entryIte = keyMap.entrySet().iterator();
			while (entryIte.hasNext()) {
				Entry<String, String> oidToNewOidEntry = (Entry<String, String>) entryIte.next();
				String oldOid = oidToNewOidEntry.getKey();//32位：原oid
				String newOid = oidToNewOidEntry.getValue();//64位：对应oid
				
				for(Map<String, String> tmpMap:oldMap) {//oid:value
					String ifIndex = tmpMap.get(rootOid+".1");//某个端口的ifIndex属性的值，即端口的编号					
					Map<String,String> tmpSubMap = subMap.get(ifIndex);
					if(tmpSubMap!=null && tmpSubMap.size()>0) {
						String newVal = tmpSubMap.get(newOid);					
						tmpMap.put(oldOid, newVal);						
					}
				}				
			}
		}
	}
	
	public static void main(String[] args) {
		
		CommonDao dao = null;
		try {
			BoneCPPool.initPool();
			dao = new CommonDao();
			CommonService commonService = new CommonService(dao);
			ThreadService service = new ThreadService();
			
			new InitServerThread().initCommonInfo(dao);
			long startTimeTmp = Calendar.getInstance().getTimeInMillis();
			
			
			
			//--获取checkType 监测配置并启动监测任务
			List<SetInfo> setList =  commonService.getDrivingSetInfo(Constants.DETEC_SWITCH_STR);//获得checkType类型的所有监测设置
			System.out.println("检查主动监测类别："+Constants.DETEC_SWITCH_STR+" 关联监测设置："+(setList==null?0:setList.size())+"个");
			//-- checkType 监测任务启动 和 客户端启动监测任务启动
			SetInfo si = null;
			if(setList!=null && setList.size()>0){
				for (Iterator setIte = setList.iterator(); setIte.hasNext();) {
//					if(Constants.DETEC_SNMP_STR.equalsIgnoreCase(checkType)){
//						if(Constants.DETEC_SWITCH_STR.equalsIgnoreCase(si.getCheckTypeName())){
//							continue;
//						}
//					}
//					service.updateThread(si);
					
					si = (SetInfo) setIte.next();
					break;
				}
			}
			Common.service.submit(new SwitchPortThread("254","10.0.6.254",si,startTimeTmp));
//		
//		
//		
//		
//			Map<String, String> mapForDPIfXTab = new HashMap<String,String>();
//			mapForDPIfXTab.put("1.3.2", "aa");
//			mapForDPIfXTab.put("1.3.3", "bb");
//			mapForDPIfXTab.put("1.3.4", "cc");
//			mapForDPIfXTab.put("1.3.1", "ifIndex");
//			
//			List<Map<String, String>> datasMapList1 = new ArrayList<Map<String,String>>();
//			Map<String,String> tmpMap = new LinkedHashMap<String,String>();
//			tmpMap.put("1.3.2", "11");
//			tmpMap.put("1.3.3", "12");
//			tmpMap.put("1.3.4", "13");
//			tmpMap.put("1.3.1", "1");
//			Map<String,String> tmpMap2 = new LinkedHashMap<String,String>();
//			tmpMap2.put("1.3.2", "21");
//			tmpMap2.put("1.3.3", "22");
//			tmpMap2.put("1.3.4", "23");
//			tmpMap2.put("1.3.1", "2");
//			Map<String,String> tmpMap3 = new LinkedHashMap<String,String>();
//			tmpMap3.put("1.3.2", "31");
//			tmpMap3.put("1.3.3", "32");
//			tmpMap3.put("1.3.4", "33");
//			tmpMap3.put("1.3.1", "3");
//			datasMapList1.add(tmpMap);
//			datasMapList1.add(tmpMap2);
//			datasMapList1.add(tmpMap3);
//			
//			List<List<String>>  snmpDatasList = new LinkedList<List<String>>();
//			List<String> snmpTmpList = new LinkedList<String>();
//			snmpTmpList.add("11");
//			snmpTmpList.add("12");
//			snmpTmpList.add("13");
//			snmpTmpList.add("1");
//			snmpDatasList.add(snmpTmpList);
//			
//			List<String> snmpTmpList2 = new LinkedList<String>();
//			snmpTmpList2.add("21");
//			snmpTmpList2.add("22");
//			snmpTmpList2.add("23");
//			snmpTmpList2.add("2");
//			snmpDatasList.add(snmpTmpList2);
//			
//			List<String> snmpTmpList3 = new LinkedList<String>();
//			snmpTmpList3.add("31");
//			snmpTmpList3.add("32");
//			snmpTmpList3.add("33");
//			snmpTmpList3.add("3");
//			snmpDatasList.add(snmpTmpList3);
//			
//			
//			for(Map<String,String> tmpMa:datasMapList1) {
//	    		Iterator<Entry<String, String>> oi = tmpMa.entrySet().iterator();
//	    		while(oi.hasNext()) {
//	    			Entry<String, String> en2 =oi.next();
//	    			System.out.print(en2.getKey()+":");
//	    			System.out.print(en2.getValue());
//	    			System.out.println();
//	    			
//	    		}
//	    		System.out.println("===========");
//	    	}
//			
//			
//			Map<String,Map<String, String>> ifXTabdatasMapList1 = new HashMap<String,Map<String,String>>();
//			Map<String,String> tmpMap11 = new LinkedHashMap<String,String>();
//			tmpMap11.put("aa", "111");
//			tmpMap11.put("bb", "112");
//			tmpMap11.put("cc", "113");
//			tmpMap11.put("ifIndex", "1");
//			Map<String,String> tmpMap22 = new LinkedHashMap<String,String>();
//			tmpMap22.put("aa", "221");
//			tmpMap22.put("bb", "222");
//			tmpMap22.put("cc", "223");
//			tmpMap22.put("ifIndex", "2");
//			Map<String,String> tmpMap33 = new LinkedHashMap<String,String>();
//			tmpMap33.put("aa", "331");
//			tmpMap33.put("bb", "332");
//			tmpMap33.put("cc", "333");
//			tmpMap33.put("ifIndex", "3");
//			ifXTabdatasMapList1.put("1", tmpMap11);
//			ifXTabdatasMapList1.put("2", tmpMap22);
//			ifXTabdatasMapList1.put("3", tmpMap33);
//			
//			
//	//		new SwitchPortThread().replaceValueByKeyMap(datasMapList1,mapForDPIfXTab,ifXTabdatasMapList1);
//			new SwitchPortThread().replaceValueByKeyMapForListData(snmpDatasList, "switchport", "1.3", datasMapList1, mapForDPIfXTab, ifXTabdatasMapList1);
//			
//			for(Map<String,String> tmpMa:datasMapList1) {
//	    		Iterator<Entry<String, String>> oi = tmpMa.entrySet().iterator();
//	    		while(oi.hasNext()) {
//	    			Entry<String, String> en2 =oi.next();
//	    			System.out.print(en2.getKey()+":");
//	    			System.out.print(en2.getValue());
//	    			System.out.println();
//	    			
//	    		}
//	    		System.out.println("===========");
//	    	}
	//    	
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if(dao!=null){
				dao.close();
				dao=null;
			}
		}
	}
	

	/**
	 * 执行监测 获取Switch Port 数据
	 * @time Jan 30, 2013-4:50:25 PM
	 * @return
	 */
	public List<Map<String, String>> detectionSwitchDataOnce(List<List<String>> snmpDatasList,List<String> oids,String rootOid,StringBuffer stateInfo,int version ,int retries,int timeout,int state){
		List<Map<String, String>> snmpDatas = new LinkedList<Map<String, String>>();
		try {
			
			snmpDatasList = resoveVersion(snmpDatas,oids,rootOid,version,retries,timeout,stateInfo);
			state = 1;
		} catch (Exception e) {
			state = -1;
			stateInfo.append(e.getMessage());
			logger.error((version == SnmpConstants.version3?"version3":"version2c")+" GET failed", e);
		}
		return snmpDatas;
	}
	private List<List<String>> resoveVersion(List<Map<String, String>> datasMapList,List<String> oids,String oid,int version ,int retries,int timeout,StringBuffer stateInfo) throws Exception{

		List<List<String>> snmpDatasList = new LinkedList<List<String>>();
		logger.debug("SNMP4J 》》》》"+oid+" "+hostIp+" "+port+" "+Constants.SNMP_COMMUNITY+" "+retries+" "+timeout+" "+ version);		
		SNMP4JUtils.snmpTree(datasMapList, oids,oid, hostIp, port+"", Constants.SNMP_COMMUNITY,retries,timeout,version);			
//		logger.debug("datasMapList size "+datasMapList.size());
		//- 获取表字段结构
		Map<Integer,TableColumnsModel> cloumnsList = Common.getTableMap().get(info.getCheckTypeName());
//		logger.debug("cloumnsList size "+cloumnsList.size());
		//- 存值
		if(cloumnsList!=null && cloumnsList.size() > 0 && datasMapList!=null && datasMapList.size()>0){
			for(Map<String, String> datasMap : datasMapList){
				List<String> snmpDatas = new LinkedList<String>();
				for (int i = 1; i <= cloumnsList.size(); i++) {
					TableColumnsModel cloumn = cloumnsList.get(i);
					String oid0 = cloumn.getOid();
					snmpDatas.add(datasMap.get(oid0));
					if(oid0.equals(oid+".1")){
//						stateInfo.append(oid0+":"+datasMap.get(oid0)+"\n");
					}
				}
				snmpDatasList.add(snmpDatas);
			}
		}
		return snmpDatasList;
	}
	
	private void resoveIfXTabVersion(Map<String,Map<String, String>> datasMapList,List<String> oids,String oid,int version ,int retries,int timeout,StringBuffer stateInfo) throws Exception{
		
//		List<List<String>> snmpDatasList = new LinkedList<List<String>>();
		logger.debug("SNMP4J 》》》》"+oid+" "+hostIp+" "+port+" "+Constants.SNMP_COMMUNITY+" "+retries+" "+timeout+" "+ version);		
		//2013-3-20 hyx add  for ifXTable
//		SNMP4JUtils.checkTypeName = ifxtableName;
		SNMP4JUtils.snmpIfXTabTree(datasMapList, oids,oid, hostIp, port+"", Constants.SNMP_COMMUNITY,retries,timeout,version);
//		SNMP4JUtils.checkTypeName = "";
//		logger.debug("datasMapList size "+datasMapList.size());
		//- 获取表字段结构
//		Map<Integer,TableColumnsModel> cloumnsList = Common.getTableMap().get(info.getCheckTypeName());
//		logger.debug("cloumnsList size "+cloumnsList.size());
		//- 存值
//		if(cloumnsList!=null && cloumnsList.size() > 0 && datasMapList!=null && datasMapList.size()>0){
//			Iterator<Entry<String, Map<String,String>>> entryIte = datasMapList.entrySet().iterator();
//			while (entryIte.hasNext()) {
//				Entry<String, Map<String,String>> dataEntry = (Entry<String, Map<String,String>>) entryIte.next();
////			}
////			for(Map<String, String> datasMap : datasMapList){
//				List<String> snmpDatas = new LinkedList<String>();
//				for (int i = 1; i <= cloumnsList.size(); i++) {
//					TableColumnsModel cloumn = cloumnsList.get(i);
//					String oid0 = cloumn.getOid();
//					snmpDatas.add(dataEntry.getValue().get(oid0));
//					if(oid0.equals(oid+".1")){
////						stateInfo.append(oid0+":"+datasMap.get(oid0)+"\n");
//					}
//				}
//				snmpDatasList.add(snmpDatas);
//			}
//		}
//		return snmpDatasList;
	}
	
	//拼写监测信息的详细信息：对于switchport，就是每个端口的监测信息
	private List<List<String>> datasBody(int times,String stateInfo,int state,List<List<String>> snmpDatas2)throws Exception{

//		List<List<String>> pubDatasList = new LinkedList<List<String>>();

		logger.debug("监测数据主体拼写 state "+state+" size"+(snmpDatas2==null ? -1 :snmpDatas2.size()));

		if(snmpDatas2!=null && snmpDatas2.size()!=0){
		for (List<String> snmpDatas : snmpDatas2) {
//			List<String> pubDatas0 = new LinkedList<String>();
//		执行状态是否成功是否正常,	第三方脚本监测任务执行结果（用于报警 -1执行失败 0不正常，1正常）-1时可保留后续数据为空，但是数据个数需要对应
				// -- 执行状态是否成功，记录的状态是否正常（用于报警），
				String [] datas0 =  new String[0];
				datas0 = snmpDatas.toArray(datas0);
//			logger.debug("snmpDatas>>>> "+Arrays.toString(snmpDatas.toArray(datas0)));
//			logger.debug("Common.getAlarmInfoMap()>>>> "+Common.getAlarmInfoMap().size());
				String[] pArray = Common.getAlarmState(Common.getAlarmInfoMap().get(info.getId()+""), datas0);
//			logger.debug("pArray>>>> "+Arrays.toString(pArray));
				if (pArray == null || pArray.length==0) {//无告警信息
					snmpDatas.add(0, "");//插入后，列表之后的信息顺序往后移
					snmpDatas.add(1, "");
					snmpDatas.add(2, "");
				} else {//有告警信息
					state = 0;//只要有一个端口有告警信息，则整个监测的状态为0
					snmpDatas.add(0, pArray == null ? "" : pArray[0]);
					snmpDatas.add(1, pArray == null ? "" : pArray[1]);
					snmpDatas.add(2, pArray == null ? "" : pArray[2]);
					stateInfo+=Common.getStateInfo(info.getCheckTypeName(),Common.getAlarmInfoMap().get(info.getId()+""), datas0);
				}
//			logger.debug("pArray>>>> "+Arrays.toString(pubDatas0.toArray()));
		}
		}
		return snmpDatas2;
		
	}
	/*
	class Switch{
		
		ifIndex
		ifDescr
		ifType
		ifMtu
		ifSpeed
		ifPhysAddress
		ifAdminStatus
		ifOperStatus
		ifLastChange
		ifInOctets
		ifInUcastPkts
		ifInNUcastPkts
		ifInDiscards
		ifInErrors
		ifInUnknownProtos
		ifOutOctets
		ifOutUcastPkts
		ifOutNUcastPkts
		ifOutDiscards
		ifOutErrors
		ifOutQLen
		ifSpecific
		INOCTETSSPEED
		INERRORSSCALE
		OUTOCTETSSPEED
		OUTERRORSSCALE
		test
		test2
		private Double DETECTION_INFO_ID	;	//检测信息ID
		private Double IFINDEX	;	//接口表惟一的索引项，索引值为1~ ifNumber范围
		private String IFDESCR	;	//接口的描述，制造商名，产品名和版本等
		private Double IFTYPE	;	//接口的类型,用一个整数表示,表示物理层和数据链路层协议确定的接口类型
		private Double IFMTU	;	//表示该接口上可以发送或接收的最大协议数据单元大小(位组数)
		private Double IFSPEED	;	//指定一个接口的传输速率，单位为“位/秒”（bps）
		private String IFPHYSADDRESS	;	//接口的物理地址
		private Double IFADMINSTATUS	;	//用于配置接口的管理状态，up(1) down(2) testing(3)
		private Double IFOPERSTATUS	;	//提供一个接口的当前操作状态， up(1) down(2) testing(3)
		private String IFLASTCHANGE	;	//接口进入当前状态的时间
		private Double IFINOCTETS	;	//接口收到的总字节数
		private Double IFINUCASTPKTS	;	//单点发送到一种高层协议上的包的总数目
		private Double IFINNUCASTPKTS	;	//发往高层协议的非单播包数（广播和多播）
		private Double IFINDISCARDS	;	//接口丢弃的输入包数
		private Double IFINERRORS	;	//由于错误导致接收的错误包数
		private Double IFINUNKNOWNPROTOS	;	//由于未知或不支持的协议而被抛弃的输入包数
		private Double IFOUTOCTETS	;	//接口发送的总字节数
		private Double IFOUTUCASTPKTS	;	//高层协议请求传输的单播包数
		private Double IFOUTNUCASTPKTS	;	//高层协议请求的非单播（广播和多播）包数
		private Double IFOUTDISCARDS	;	//由于资源局限而导致丢弃的发出包的总数目
		private Double IFOUTERRORS	;	//由于错误而导致丢弃的发出包的总数目
		private Double IFOUTQLEN		;	//"输出包队列中包的总数(输出队列长度)"
		private String IFSPECIFIC	;	//指向MIB中特定介质的定义
		private Date DATA_CHECK_TIME	;	//检测时间
		private Date DATA_ARRIVE_TIME	;	//数据入库时间
		private Double DATA_CHECK_TIME_DIGITAL	;	//检测时间（毫秒）
		private Double DATA_ARRIVE_TIME_DIGITAL	;	//数据入库时间（毫秒）
		private Double INOCTETSSPEED	;	//		
		private Double INERRORSSCALE	;	//
		private Double OUTOCTETSSPEED	;	//
		private Double OUTERRORSSCALE	;	//	
	}*/
}
