package com.nms.server.thread.dataCollect;

import java.util.ArrayList;
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.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import com.nms.server.bean.DetectInfo;
import com.nms.server.bean.NodeModel;
import com.nms.server.bean.SetInfo;
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.thread.monitor.util.MonitorUtil;
import com.nms.server.thread.socket.SocketCMD;
import com.nms.server.util.BoneCPPool;
import com.nms.server.util.DateUtil;

//监测数据主动收集管理线程
public class NoDetectDataCollectManagerThread implements Runnable{
	private Logger logger = Logger.getLogger(NoDetectDataCollectManagerThread.class);
	private long startTime = Calendar.getInstance().getTimeInMillis();
	
	public void run() {
//		Thread.currentThread().setName("无监测数据节点 数据（监测数据、任务结果、回传文件）收集管理线程");
		Thread.currentThread().setName("No Monitoring Data Node Data (Monitoring data, Task results, Return files) Collect Management Threads");
		CommonDao dao = null;
		try {
			dao = new CommonDao();
			CommonService service = new CommonService(dao);
			
			//- 非升级操作判断
			if(Common.SERVER_UN_UPGRADE_FLAG && Common.noDetectDataNodeList.size()>0){
				//循环向自己管辖的Client端，收集数据
				List<String> ipList = new LinkedList<String>();
				ipList = service.getAllComputerIp();//当前DC管理范围内+有效节点+有效节点组+服务器节点
				/*
				 * 2013-7-29 hyx
				 * 获得所有握手监测的节点信息，若数据收集的节点在握手监测节点范围内，则收集数据的同时进行握手监测（传递true），确认一个，从握手监测中删除一个节点，最后未握手的节点则不在数据收集范围内（这种情况不应该存在）
				 */
				Map<String,SetInfo> nodeMap = getNmsclientNodeList(service);//ip:setinfo	
				
				//20160901 hyx 增加此代码的原因是：数据收集管理线程运行一段时间后，会出现获取数据库连接一直阻塞的情况，而此时其它线程是可以正常获取数据库连接的，一个原因可能是之前没有dao=null；另一个原因可能是，之后的数据收集及超时操作，可能由于各种原因，如异常节点较多，导致连接最后没能正常关闭，所以在连接不使用的时候，尽早关闭
				try {
					if(dao!=null){
						dao.close();
						dao=null;
					}
				} catch (Exception e)
				{
					logger.error("Data collection management thread early closing database connection exception", e);
				}
				
				List<String> list = Common.pingHandshake(Common.noDetectDataNodeList);
				String stateInfo = "";
				String failStartTime = "";
				String failEndTime = "";
				int ipSize = Common.noDetectDataNodeList.size();
				for(int i=0;i<ipSize;i++){
					String ip = Common.noDetectDataNodeList.get(i);
					logger.debug("ip:"+ip+"  i="+i);
					if(!ipList.contains(ip)){
						Common.noDetectDataNodeList.remove(ip);//判断当前ip是否在dc管辖范围内，如果不在就删除
						i--;
						ipSize--;
						continue;
					}
					if(nodeMap.get(ip)==null){continue;}//不需要握手的节点不用产生监测数据
					
					failStartTime = Calendar.getInstance().getTimeInMillis()+ "";
					DetectInfo detectInfo = new DetectInfo();
					if(!list.contains(ip)){ //ping不成功的节点  网络异常
//						stateInfo = "网络异常";
//						stateInfo = "Network Exception";
						stateInfo = "i18n_server.NoDetectDataCollectManagerThread.network_n81i";
						logger.info("ip ："+ip+" 异常信息：网络异常");
					}else{//ping成功的节点 进行ssh
						String sshResult = Constants.SUCCESS;
						if(1==Constants.FLAG_HANDWALK_SSH){
						    String[] userPwdInfo = Common.getIpUserPwdMap().get(ip);
							if (userPwdInfo!=null && 
									userPwdInfo.length>=3 && "1".equals(userPwdInfo[2])) {//应该判断nc的操作系统，不是dc的,1:linux; 2:windows; 3:other
								sshResult = Common.sshConnect(ip,userPwdInfo[0],userPwdInfo[1]);
							}
						}
						if(Constants.SUCCESS.equals(sshResult)){
							//ping和ssh都成功
							logger.debug("ip ："+ip+"恢复正常，从异常节点列表中删除");
							Common.noDetectDataNodeList.remove(ip);
							i--;
							ipSize--;
//							stateInfo = "开始" + DateUtil.getStringByLong(startTime)+" NMSClient握手" + DateUtil.getCurrentTime() + " 失败 ";
//							stateInfo = "Start" + DateUtil.getStringByLong(startTime)+" NMSClient Shakehand" + DateUtil.getCurrentTime() + " failed";
							stateInfo = "i18n_server.NoDetectDataCollectManagerThread.start_n81i" + DateUtil.getStringByLong(startTime)+" i18n_server.NoDetectDataCollectManagerThread.shakehand_n81i" + DateUtil.getCurrentTime() + " i18n_server.NoDetectDataCollectManagerThread.faild_n81i";
						}else{
							logger.debug("ip ："+ip+" 异常信息："+sshResult);
							stateInfo = sshResult;
						}
						failEndTime = Calendar.getInstance().getTimeInMillis()+ "";
						StringBuffer detailInfo = new StringBuffer();
						detailInfo.append(SocketCMD.CLIENT_REQ_HAND_SHAKE);// 发送信息
						detailInfo.append(MonitorUtil.SEPARATOR);// 分隔符
						detailInfo.append("");// 返回信息
						detailInfo.append(MonitorUtil.SEPARATOR);// 分隔符
						detailInfo.append("1");// 是否可达,0:可达，1：不可达
						detailInfo.append(MonitorUtil.SEPARATOR);// 分隔符
						detailInfo.append(failStartTime);// 发送时间
						detailInfo.append(MonitorUtil.SEPARATOR);// 分隔符
						detailInfo.append(failEndTime);// 返回时间
						detailInfo.append(MonitorUtil.SEPARATOR);// 分隔符
						detailInfo.append(DateUtil.getSecondsFromBeinToEnd(new Date(
								Long.parseLong(failStartTime)).getTime(), new Date(Long
										.parseLong(failEndTime)).getTime())+ "");// 延迟时间
						detectInfo.getDetailDatas().add(detailInfo.toString());
					}
					detectInfo.setDescInfo(stateInfo);
					Common.createNmsClientDetectData(nodeMap.get(ip),ip,detectInfo, startTime);//生成监测数据信息
				}
				
			}
		} catch (Exception e) {
			logger.error("Monitoring data collection management threads run abnormity",e);
		} finally {
			if(dao!=null){
				dao.close();
				dao=null;
			}
			logger.debug("执行结束");
		}
	}

	//获得进行握手监测的所有节点：握手的条件：到首次监测时间+节点有效（节点组有效）+监测设置内的节点+监测设置有效
	private Map<String,SetInfo> getNmsclientNodeList(CommonService service){
		List<NodeModel> nodeList = new ArrayList<NodeModel>();
		Map<String,SetInfo> nodeMap = new HashMap<String,SetInfo>();
		try
		{
			if(Constants.FLAG_NMSC==1){
				List<SetInfo> setList =  service.getDrivingSetInfo(Constants.DETEC_NMSC_STR);//获得checkType类型的所有监测设置
				if(setList!=null && setList.size()>0){
					List<NodeModel> nodeTmpList = new ArrayList<NodeModel>();
					for (Iterator setIte = setList.iterator(); setIte.hasNext();) {
						SetInfo setInfo = (SetInfo) setIte.next();
						//如果首次监测时间没到，则不用查询节点
						//- 计算启动后第一次检测时间 默认即时启动
						long initialDelay = 0l;
						if(setInfo.getPlanCheckTime()!=null){
							initialDelay = setInfo.getPlanCheckTime().longValue() - (new Date().getTime());
							initialDelay = initialDelay > 0l ? initialDelay : 0l;
						}
						
						if(initialDelay<=0) {//到首次监测时间了，查询进行握手监测的节点		
							//节点可能存在重复的情况
							nodeTmpList = service.getNodeModelListBySetInfo(setInfo);
							nodeList.addAll(nodeTmpList);
						}else {
							logger.info("握手监测，未到首次监测时间，距离首次监测时间还有："+initialDelay/1000/60+"分钟");
						}
						
						for(NodeModel node:nodeTmpList) {
							nodeMap.put(node.getNodeIp(), setInfo);
						}
					}					
					
					logger.debug("本次服务器握手监测的节点数为："+nodeMap.size());
				}
			}else {
				logger.info("未开启握手监测标识");
			}
		} catch (Exception e)
		{
			logger.error("Obtaining a node exception for handshake monitoring", e);
		}
		return nodeMap;
	}
	
	public static void main(String[] args) throws Exception {

		CommonDao dao = null;
		ScheduledFuture<?> future = null;
		Object rlt = null;
		try
		{
			Thread.sleep(3000);
			BoneCPPool.initPool();
			Thread.sleep(3000);
//			DataCollectManagerThread runThread = new DataCollectManagerThread();
//			Thread thread = new Thread(runThread);
//			thread.start();
			dao = new CommonDao();
			CommonService service = new CommonService(dao);
			
			// 初始化自身信息(失败情况下会由Web唤醒)
			if(!service.initServerParams()){
				return;
			}
			
			future = Common.scheduled.scheduleWithFixedDelay(new NoDetectDataCollectManagerThread(), 0, 300, TimeUnit.SECONDS);
			Common.registRunnable(Constants.DATA_COLLECT_MANAGER, future);
			Thread.sleep(7000);
			System.out.println(future==null?"null3":future.isDone());
			System.out.println(future==null?"null4":future.isCancelled());
			System.out.println("***************=====结束了？");
			rlt = future.get();
			Thread.sleep(5000);
//          future.cancel(true);
			//发生异常未捕捉后：
			System.out.println("future="+future);
			System.out.println(future==null?"null55":future.isDone());
			System.out.println(future==null?"null55":future.isCancelled());
			System.out.println("==============结束了？55");
			System.out.println("rlt="+rlt);
			
			
			
		} catch (Exception e)
		{
			System.out.println("catch*******************");
			System.out.println("eeeeeeeefuture="+future);
			System.out.println(future==null?"eeeeeeeeenull55":future.isDone());
			System.out.println(future==null?"eeeeeeeeeenull55":future.isCancelled());
			System.out.println("eeeeeeeeee==============结束了？55");
			System.out.println("eeeeeeeerlt="+rlt);
			
			System.out.println("数据收集线程是否注册-catch-done"+Common.getFutureMap().get(Constants.DATA_COLLECT_MANAGER).isDone());
			System.out.println("数据收集线程是否注册-catch-cancel"+Common.getFutureMap().get(Constants.DATA_COLLECT_MANAGER).isCancelled());
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(dao!=null){
				dao.close();
				dao=null;
			}
			System.out.println("finally**********************************");
//			Common.scheduled.shutdown();//关闭线程池
//			System.out.println(Common.scheduled.isTerminated());//?????????
//			System.out.println(Common.scheduled.isShutdown());
			System.out.println("数据收集线程是否注册-catch-done"+Common.getFutureMap().get(Constants.DATA_COLLECT_MANAGER).isDone());
			System.out.println("数据收集线程是否注册-catch-cancel"+Common.getFutureMap().get(Constants.DATA_COLLECT_MANAGER).isCancelled());
//			System.out.println("关闭线程池");
			
		}
	}
}
