package com.nms.server.thread.alarmData;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
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.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.apache.log4j.Logger;

import com.nms.server.common.Common;
import com.nms.server.common.Constants;
import com.nms.server.dao.CommonDao;
import com.nms.server.service.CommonService;

/**
 * 告警数据解析线程
 * 
 * @author ZGGG3
 * 
 */
public class AlarmDataResoveThread implements Callable<Object> {
	private Logger logger = Logger.getLogger(AlarmDataResoveThread.class);
	volatile boolean stop = false;//线程是否被取消标志
	private String name; // 自定义Thread Name
	private LinkedList<String []> adList;
	
	public AlarmDataResoveThread(String name,LinkedList<String []> adList) {
		this.name = name;
		this.adList = adList;
	}

	/*
	 * 线程操作
	 * 
	 * 依次解析urlList中仍存在的Files
	 * 
	 * 实现了依次解析Files，由于后期实现多线程解析操作
	 */
	public Object call() {
		// 为当前线程命名 ，用与开发阶段友好输出。
		Thread.currentThread().setName(name);
		
		//-- 空数据集合 结束操作
		if(adList == null || adList.size() == 0 ){
			return null;
		}
		
		logger.debug(" 解析数量 "+adList.size());
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		CommonDao dao = null;
		try {
			dao = new CommonDao();
			CommonService service = new CommonService(dao);
			int totalCount = adList.size();
			long sTime = System.currentTimeMillis();
			logger.debug("缓存告警数据 " + (totalCount)+ "条，解析开始");
			
			//-- 遍历解析
			Iterator<String []> adIte = adList.iterator();
			while (adIte.hasNext()&& !stop) {//线程未被中断
				try {
					
					String [] alarms = adIte.next();
					
					if(alarms!=null && alarms.length>0){
						
						String dateTime = null;
						if(alarms.length>6){
							dateTime = format.format(Long.parseLong(alarms[5]));
						}
						
						logger.debug("告警数据 监测时间》"+dateTime+"  内容》"+Arrays.toString(alarms));
						service.resoveAlarms(alarms);
					}
					
					//解析入库一条数据，从list中remove一条数据
					adIte.remove();
				}catch (InterruptedException e) {
					logger.error("Alarm data parsing threads are interrupted",e);
					stop = true;
				} 
				//判断当前线程是否被中断
				if (Thread.currentThread().isInterrupted()) {
					// 线程中断状态，不会改变中断状态的值
					logger.info("告警数据解析线程 被中断");
					stop = true;
				}
			}
			
			//将告警数据入库后，需要检查新入库的数据是否为无效（处理告警数据的有效性标志）
			updateDetectWarningDataValid(dao);
			
			long eTime = System.currentTimeMillis();
			long curTime = eTime-sTime;
			int m=(int)curTime/1000/60;
			int s=(int)((long)(curTime/1000)%60);
			int ms=(int)curTime%1000;
			logger.debug((totalCount)+ "条，解析完成 耗时："+(m)+"分 "+(s)+"秒 "+(ms)+"毫秒");

		}catch (Exception e) {
			logger.error("Running exception",e);
		}finally{
//			adList.clear();
			if(dao!=null){
				dao.close();
				dao=null;
			}
			logger.debug("数据清理 解析完成");
		}
		return null;
	}
	
	//检查入库的告警数据中是否有无效的数据,有则置为无效
	public void updateDetectWarningDataValid(CommonDao dao) throws Exception{
		CommonService service = new CommonService(dao);		
		Map<String,String> detectSetSeqIdMap = service.getDetectSetInfo();//查询有效监测设置对应的seqid
		Map<String,String[]> detectWarnDataSeqIdMap = service.getDetectSeq(Constants.DETECTION_WARNING_TABLE_NAME);//统计 告警数据 表: 监测设置<->已有有效数据的seqid
		Iterator detectWarnDateSeqIte = detectWarnDataSeqIdMap.entrySet().iterator();
		String invalidSeqIds = "";
		List<String> sqls = new ArrayList<String>();
		while(detectWarnDateSeqIte.hasNext()) {
			invalidSeqIds = "";
			Entry en = (Entry)detectWarnDateSeqIte.next();
			String setId = (String)en.getKey();
			String seqIdsValid = detectSetSeqIdMap.get(setId);//得到监测设置当前有效的seqids：1,2,3
//			System.out.println("有效key:value="+setId+":"+seqIdsValid);
			if(seqIdsValid!=null) {//如果有效的监测设置内没有此监测设置，则不予处理
				seqIdsValid = "," + seqIdsValid + ",";
				String[] seqIds = (String[])en.getValue();
				for(String seqIdTmp:seqIds) {
//					System.out.println("告警数据seqId="+seqIdTmp);
					if(seqIdTmp!=null && !"".equals(seqIdTmp)) {
						if(!seqIdsValid.contains(","+seqIdTmp+",")) {//不在有效范围内，则更新为无效
							invalidSeqIds = invalidSeqIds + seqIdTmp + ",";
						}
					}
				}
				if(invalidSeqIds.endsWith(",")) {
					invalidSeqIds = invalidSeqIds.substring(0,invalidSeqIds.length()-1);				
					sqls.add("update "+Constants.DETECTION_WARNING_TABLE_NAME+" t set valid=0 where t.valid=1  and t.detection_set_info_id="+setId+" and t.seq_id in ("+invalidSeqIds+")");
				}
			}
		}	
		dao.dbUpdateByBatch(sqls);
		
	}
	
/*	public static void main(String[] args) {
		CommonDao dao = null;
		try {
			dao = new CommonDao();
			new AlarmDataResoveThread("xx",null).updateDetectWarningDataValid(dao);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}*/

	public static void main(String[] args) {
		CommonDao dao = null;
		try {
			dao = new CommonDao();
			CommonService service = new CommonService(dao);
//		boolean flag =  initCheck();
			//-- CheckType TableName Map Init（监测类别数据库表名映射结构信息）
			service.updateCheckTableInfo(Common.getInsertTable(), null);
			//-- Table Columns Map Init（数据库表结构信息）
			service.updateTableColumnsMap(Common.getTableMap(), null);
			//-- LoginIp nodeip Init（seq_id-物理节点信息）
			service.updateSimpleNodeByUUID(null);
			//--	（ClientIP-seq_id信息）
			service.updateSeqIdByNodeIp(Common.getIpSeqIdMap(),null);
			//alarm Ping Init（告警数据结构信息）
			service.updateAlarmInfo(Common.getAlarmInfoMap(),null);
			// init loop Mission info
			
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}finally{
			if(dao!=null){
				dao.close();
				dao=null;
			}
		}
		
		long l = Calendar.getInstance().getTimeInMillis();
		LinkedList<String []> adList = new LinkedList<String[]>();
		adList.add("141$@$143$@$cpu$@$detection288$@$1364280094312$@$1364280094312$@$1$@$0$@$总的使用率(%)12.5%大于告警值1%  不正常；".split(Constants.COMMON_DATA_SPLIT));
		Future<?> future = Common.service.submit(new AlarmDataResoveThread("",adList));
		try {
			future.get();
		} catch (InterruptedException e) {
//			 TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Common.service.shutdown();
		System.out.println(Calendar.getInstance().getTimeInMillis()-l);
	}
}
