package com.nms.server.thread.change;

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

import net.sf.json.JSONObject;

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

import com.nms.server.bean.AlarmInfo;
import com.nms.server.bean.NodeModel;
import com.nms.server.bean.NodegroupModel;
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.ChangeService;
import com.nms.server.service.ThreadService;
import com.nms.server.thread.change.socket.ChangeSocketThread;

/**
 *  执行由节点或节点组状态的变更而变更的操作类
 *  @date Dec 23, 2011 1:58:04 PM
 *	@author ZhangGang
 *
 */
public class ChangeForNodeGroup implements Runnable{
	private final Logger logger = Logger.getLogger(ChangeForCheckType.class);
	private String [] data = null;
	private Long recordId;

	/**
	 * @param recordId	库表记录ID 可为空
	 * @param data	[groupId,nodeId]   [节点组Id:节点ID 节点Id为空时，即为节点组信息 ]
	 */
	public ChangeForNodeGroup(Long recordId,String [] data){
		this.recordId = recordId;
		this.data = data;
	}

	@Override
	public void run() {
//		Thread.currentThread().setName("节点状态变更");
		Thread.currentThread().setName("Node State Change");
		CommonDao dao = null;
			
		try {
			dao = new CommonDao();
			ChangeService service = new ChangeService(dao);
			/* 有效性判断 */
			if(data == null || StringUtils.isEmpty(data[0])){
				logger.warn("Not effective node state change information："+(data==null?null:Arrays.toString(data)));
				if(recordId!=null){
					service.deleteEventRecordByIds(recordId.toString());
				}
				return ;
			}
			/* 整理变更数据 最终以节点为主 */
			Long nodeGroupId = Long.parseLong(data[0]);
			NodegroupModel nodeGroup = service.getNodeGroupInfoById(nodeGroupId);//nodeGroup state 1有效 0无效
			if(nodeGroup == null ){logger.warn("No query to the end of the node group change operation groupId："+nodeGroupId);return;}
			String nodeIdStr = (data.length<=1?null:data[1]);
			List<NodeModel> nodeList = new ArrayList<NodeModel>();
			if(StringUtils.isNotEmpty(nodeIdStr)){	//节点不为空
				Long nodeId = Long.parseLong(nodeIdStr);
				NodeModel node = service.getNodeInfoById(nodeId);//node state 0有效 1无效
				if(node!= null && node.getNodeIp()!= null && Common.hasIpInIpSegment(node.getNodeIp())){
					nodeList.add(node);
				}
			}else{	//节点为空节点组判断
				nodeList = service.getNodeInfoByGroupId(nodeGroupId);
			}
			logger.debug(nodeGroup.getGroupId()+" "+nodeGroup.getGroupName()+" 影响的节点数为："+(nodeList==null?0:nodeList.size()));
			Iterator<NodeModel> ite = nodeList.iterator();
			/* 遍历各节点 处理相关setinfo */
			while (ite.hasNext()) {
				try {
					NodeModel node = (NodeModel) ite.next();
					boolean isPhysical = false;
					if (node == null) {
						continue;
					}
					
					//节点类型判断
					if(node.getNodeType() != null && node.getNodeType().longValue() != 0l ){
						logger.info("IP为："+node.getNodeIp()+"的节点 其节点类型不是服务器，变更无需下发,仅需更新DC的缓存信息");
						//更新缓存中节点的信息
						service.updateSeqIdByNodeIp(Common.getIpSeqIdMap(), node.getNodeIp());
						service.updateUserPwdByNodeIp(Common.getIpUserPwdMap(),node.getNodeIp());
						service.updateSimpleNodeByUUID(node.getSeqId());
						continue;
					}
					
					//-- 节点无效性继承自nodeGroup
					logger.debug("逻辑节点 id："+node.getNodeId()+" 自身状态："+(node.getNodeState()==0?"有效":"无效")+" 组状态："+(nodeGroup.getIsValid()==1?"有效":"无效")+" 最终状态："+((new Long(0).equals(nodeGroup.getIsValid())?1l:node.getNodeState()==null?null:node.getNodeState().longValue())==0l?"有效":"无效"));
					node.setNodeState(new Long(0).equals(nodeGroup.getIsValid())?1l:node.getNodeState());
					
					//-- 变更节点监测信息，分布走
					//--第一步，查询状态变更的节点ID和他的Seq_id （已完成）
					//--第二步，查询节点状态有效唯一的Id或者null （已完成）
					//--第三步，当第一步节点有效时：比较第一步的节点id和第二步的节点Id是有相等 或者 当第一步节点无效时：null（已完成）
					//--第四步，如果第三步为true，则作为物理节点处理，否则，逻辑节点处理
					List<SetInfo> setInfoList = null;
					if(service.checkUpdateNodeIsPhysicalNode(node)){	//是物理节点
						logger.debug(node.getNodeIp()+" 该节点可作为物理节点");
						isPhysical = true;
						setInfoList = service.selectSetInfoList(null, null, node.getSeqId(), null, null, null, null, null,false);
					}else{	//逻辑节点
						logger.debug(node.getNodeIp()+" 该节点仅为逻辑节点");
						setInfoList = service.selectSetInfoList(null, null, null, null, nodeGroupId+"", nodeGroup.getIsValid(), node.getNodeId()+"", null,false);
					}
					
					//更新缓存中节点的信息
					service.updateSeqIdByNodeIp(Common.getIpSeqIdMap(), node.getNodeIp());
					service.updateUserPwdByNodeIp(Common.getIpUserPwdMap(),node.getNodeIp());
					service.updateSimpleNodeByUUID(node.getSeqId());
					
					/** 更新其影响的监测设置的操作
					 * */
					logger.debug(node.getNodeIp()+" 影响变更的监测设置数量为："+(setInfoList==null?0:setInfoList.size()));
					if(setInfoList!=null && setInfoList.size()>0){
						
						for (int i = 0 ; i < setInfoList.size() ; i++) {
							try {
								SetInfo setInfo = setInfoList.get(i);
								//非物理节点，跳过全局
								if(!isPhysical && setInfo.getViewLevel()==4l){logger.debug(node.getNodeIp()+" 逻辑节点跳过全局监测:"+setInfo.getCheckTypeName());continue;}
								// 监测方式：0主动 1被动
								if("0".equals(setInfo.getCheckWay())){	 //主动监测状态，有NMSServer自己处理
									logger.debug("变更主动监测 "+setInfo.getCheckTypeName()+"跳过");
//									
									String runnableName = setInfo.getCheckTypeName()+"_"+setInfo.getProcessIden();
									if(!Common.isRunnableRegist(runnableName)){
										ThreadService service2 = new ThreadService();
										service2.updateThread(setInfo);
									}
//									//- 设置名称
//									String processIden = StringUtils.isEmpty(setInfo.getProcessIden())?"":setInfo.getProcessIden();
//									
//									//-- 监测设置  线程名称 typeName_processIden
//									String runnableName =  setInfo.getCheckTypeName()+"_"+processIden;
//									
//									//根据线程类别  线程对象
//									MonitorManagerThread managerThread = (MonitorManagerThread) Common.getMonitorRunnableFromMap(runnableName);
//									
//									if(managerThread!= null){
//										if(0l == node.getNodeState()){	//0有效
//											managerThread.addIp(node);
//										}else {	// 1无效
//											managerThread.removeIp(node.getNodeIp());
//										}
//									}else{
//										logger.warn("主动监测线程："+runnableName+" 不存在");
//									}
									
									setInfoList.remove(setInfo);
									i--;
								}else{	//被动状态，监测设置发送到NMSClient端
									logger.debug("变更被动监测 "+setInfo.getCheckTypeName());
									//监测设置的 无效性 继承自失败节点的状态
									logger.debug("监测设置 id："+setInfo.getId()+" 自身状态："+(setInfo.getCheckState().equals("1")?"有效":"无效")+" 节点状态："+(node.getNodeState().longValue()==0?"有效":"无效")+" 最终状态："+((new Long(1).equals(node.getNodeState())?"0":setInfo.getCheckState()).equals("1")?"有效":"无效"));
									setInfo.setCheckState(new Long(1).equals(node.getNodeState())?"0":setInfo.getCheckState());
									
								}
								
							} catch (Exception e) {
								logger.error("",e);
							}
						}
						
						//向node 下发所有被动监测监测设置信息
						if(setInfoList.size()>0){
							List<AlarmInfo> alarmInfoList = service.selectAlarmInfoBySetIfoList(setInfoList);
							//组织数据
							JSONObject jsonObj = new JSONObject();
							jsonObj.put("number", Calendar.getInstance().getTimeInMillis());
							jsonObj.put("setInfo", setInfoList);
							jsonObj.put("alarmInfo", alarmInfoList);
							Common.runChangeRunnable(new ChangeSocketThread(null,node.getNodeIp(),Constants.SSL_CLIENT_PORT,"char:updateConfig",jsonObj));
						}
					}
				} catch (Exception e) {
					logger.error("",e);
				}
			}
			
			/** 更新其影响的其他的操作
			 *  initTask
			 * */
			//删除变更记录
			if(recordId!=null){
				service.deleteEventRecordByIds(recordId.toString());
			}
		} catch (Exception e) {
			logger.error("",e);
		}finally{
			if(dao!=null){
				dao.close();
				dao=null;
			}
		}
	}
}
