package com.nms.server.thread.monitor;

import java.text.SimpleDateFormat;
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 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.DateUtil;
import com.nms.server.util.socket.SocketUtils;

/**
 * 生成 服务器 的 握手监测
 * 
 * @author dell
 *
 */
public class ServerNMSCThread implements Runnable {
	private static Logger logger = Logger.getLogger(ServerNMSCThread.class);
	private String name;
	private SetInfo setInfo;
	private List<NodeModel> nodeList;
	private Long startTime;
	
	public ServerNMSCThread(String name,SetInfo info,Long startTime,List<NodeModel> nodeList) {
		this.name = name;
		this.setInfo = info;
		this.nodeList = nodeList;
		this.startTime = startTime;
	}
	
	@Override
	public void run() {
		Thread.currentThread().setName("ServerNMSCThread->" + name );
		try {
			// - 非升级操作判断
			if (Common.SERVER_UN_UPGRADE_FLAG) {// ---起什么作用？
				// 循环向自己管辖的Client端，收集数据
				for(NodeModel model:nodeList){
					if(model.getNodeType() != null && model.getNodeType().longValue() == 0l){//服务器节点
						String ip = model.getNodeIp();
						Boolean heartFlag = Common.getHbInfo(ip, "online");
						logger.debug( ip + ",heartbeat: " + heartFlag);
						if (heartFlag != null && heartFlag) {// 节点在线
							doNmsClientDetect(ip, setInfo);
						} else {// 握手失败,超过 15秒没有心跳，则判定握手失败
							handShakeFail(setInfo, ip);
						}
					
					}
				}
			}
		} catch (Exception e) {
			logger.error("", e);
		} 
	}

	/**
	 * 握手监测失败
	 */
	public void handShakeFail(SetInfo setInfo, String ip) {
		Long startTime = System.currentTimeMillis();
		String failStartTime = System.currentTimeMillis() + "";
		DetectInfo detectInfo = new DetectInfo();
		String stateInfo = "i18n_server.NoDetectDataCollectManagerThread.start_n81i"
				+ DateUtil.getStringByLong(startTime) + " i18n_server.NoDetectDataCollectManagerThread.shakehand_n81i"
				+ DateUtil.getCurrentTime() + " i18n_server.NoDetectDataCollectManagerThread.faild_n81i";
		/*String 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);
		detectInfo.setTestTimes(1);
		detectInfo.setCheckTime(System.currentTimeMillis());
		Common.createNmsClientDetectData(setInfo, ip, detectInfo, startTime);// 生成监测数据信息
	}

	// 收集数据前先进行握手监测通信
	public static void doNmsClientDetect(String ip, SetInfo setInfo) {
		logger.info("开始握手监测>" + ip);
		DetectInfo detectInfo = null;
		try {
			long dcTime = System.currentTimeMillis();
			// -- 信息保存到监测信息对象中
			detectInfo = new DetectInfo();
			StringBuffer nmsClientDetailDetectInfo = new StringBuffer();
			nmsClientDetailDetectInfo.append(SocketCMD.CLIENT_REQ_HAND_SHAKE);// 发送信息
			nmsClientDetailDetectInfo.append(MonitorUtil.SEPARATOR);// 分隔符
			nmsClientDetailDetectInfo
					.append(SocketUtils.SUCCESS + ":" + SocketCMD.CLIENT_REQ_HAND_SHAKE + "|" + dcTime);// 返回信息:DC端伪造的，因为也不需要NC回复信息了
			nmsClientDetailDetectInfo.append(MonitorUtil.SEPARATOR);// 分隔符
			nmsClientDetailDetectInfo.append("0");// 是否可达,0:可达，1：不可达
			nmsClientDetailDetectInfo.append(MonitorUtil.SEPARATOR);// 分隔符
			nmsClientDetailDetectInfo.append(dcTime);// 发送时间
			nmsClientDetailDetectInfo.append(MonitorUtil.SEPARATOR);// 分隔符
			nmsClientDetailDetectInfo.append(dcTime);// 返回时间
			nmsClientDetailDetectInfo.append(MonitorUtil.SEPARATOR);// 分隔符
			nmsClientDetailDetectInfo.append(
					DateUtil.getSecondsFromBeinToEnd(new Date(dcTime).getTime(), new Date(dcTime).getTime()) + "");// 延迟时间

			detectInfo.getDetailDatas().add(nmsClientDetailDetectInfo.toString());
			detectInfo.setDescInfo("i18n_server.Common.nmsShakeHandBegin_n81i"
					+ DateUtil.getStringByLongStr(dcTime + "") + " i18n_server.Common.nmsShakeHand_n81i"
					+ DateUtil.getStringByLongStr(dcTime + "") + " i18n_server.Common.nmsShakeHandSuccess_n81i ");
			Common.createNmsClientDetectData(setInfo, ip, detectInfo, System.currentTimeMillis());
		} catch (Exception e) {
			logger.error("Generating node：" + ip + "information anomaly", e);
		} finally {
		}
	}

	// 获得进行握手监测的所有节点：握手的条件：到首次监测时间+节点有效（节点组有效）+监测设置内的节点+监测设置有效
	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;
	}

}
