package com.nms.server.thread.mission;

import java.io.File;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.concurrent.Future;

import org.apache.log4j.Logger;

import com.nms.server.bean.MissionResult2;
import com.nms.server.common.Common;
import com.nms.server.common.Constants;
import com.nms.server.dao.CommonDao;
import com.nms.server.util.ExceptionPrintUtils;
import com.nms.server.util.FileUtils;

public class MissionResultManagerThread implements Runnable{
	private Logger logger = Logger.getLogger(MissionResultManagerThread.class);
	private int testNum = 0;//尝试运行线程Constants.ALARM_DATA_RESOVE的次数
	
	@Override
	public void run() {
		//将线程运行程序，尽可能的catch捕获异常
		try {
//			Thread.currentThread().setName("任务结果入库管理线程");
		Thread.currentThread().setName("Task Result Library Management Thread");
		boolean runFlag = true;
		
		//- 检查线程运行状态  运行中无操作
		Future<?> future = Common.getFutureMap().get(Constants.MISSION_RESULT_RESOVE);
		if(future != null && !future.isCancelled() && !future.isDone()){	//运行中
			runFlag = false;
			logger.info("任务结果入库线程 运行中 不再启动新线程");
		}
		
		
		//测试数据库连接
		runFlag = Common.isDbConnected();
		
		
		/*
		 * 连续超过Constants.CHECK_WARNING_DATA_OVERRUN次数时，将数据存入硬盘中
		 * 否则 正常执行数据解析线程
		 * */
		if(!runFlag){	//判断并结束线程
			testNum = (testNum%Constants.CHECK_RESULT_DATA_OVERRUN);
			testNum++;
			if(testNum==Constants.CHECK_RESULT_DATA_OVERRUN) {
				if(Constants.FLAG_TASK_RLT_SAVE_DISK_RESOVE==1) {
					/*
					 * 连续多个周期仍未解析完成
					 * 说明list里存有大量的数据，则先将当前未解析的数据列表存入硬盘，
					 * 然后停掉解析线程，将正在解析的数据列表中的剩余数据存入硬盘
					 * */
					logger.warn("Create a database connection failure data to write to the hard disk");
					saveResultDataToDisk();
				}
			}
			return;
		}else{		//重置计数器 程序继续执行
			testNum = 1;
		}
		
		//- 非升级操作判断
		if(Common.SERVER_UN_UPGRADE_FLAG){
			logger.info("任务结果入库线程  空闲中 启动新解析线程");
			
			//-- 获取线程执行 需进行主动告警和邮件通知等相关操作，待考虑
//			future = Common.service.submit(new MissionResultThread("任务结果入库线程"));
			future = Common.service.submit(new MissionResultThread("Task Result Database Thread"));
			//注册
			Common.getFutureMap().put(Constants.MISSION_RESULT_RESOVE, future);

		}
		
		logger.info("执行结束");
		} catch (Exception e) {
			logger.error(ExceptionPrintUtils.printExceptionStack(e));
		}
	}
	
	/**
	 * 数据库是否可连接判断
	 * @time Mar 7, 2013-2:22:42 PM
	 * @return
	 */
	public boolean dbTest() {
		/*
		 * 数据库是否可连接判断
		 * 是：进行数据解析
		 * 否：否进行数据处理解析
		 * */
		CommonDao dao = null;
		try {
//			if(!false)throw new Exception("强制异常");
			dao = new CommonDao();
			logger.debug("尝试获取数据库连接成功");
			return true;
		} catch (Exception e) {
			logger.error("Try to get a database connection failure", e);
			/* 告警 */
			return false;
		}finally{
			if(dao!=null){
				dao.close();
				dao=null;
			}
		}
	}
	
	//2013-2-19 hyx ：当任务结果数据量过大时，将数据先存放到硬盘，再定时入库（由单独的定时线程实现）
	public void saveResultDataToDisk() {
		try {
			
			//终止正在解析告警数据的线程，并将正在解析的list里未解析的数据存入硬盘
			Future<?> future = Common.getFutureMap().get(Constants.MISSION_RESULT_RESOVE);
			if(future != null && !future.isCancelled() && !future.isDone()){	//运行中
				future.cancel(true);//停解析任务结果数据入库线程
			}
			
			for(int i=1 ;i<=6 ; i++){				
				//-- 获取结果集合
				LinkedList<MissionResult2> result = Common.getResultListClone(i);
				
				//-- 集合不为空则进行解析 存在removeList情况 ，优化方式可参考 监测数据解析的实现方式
				if(result!=null && result.size()>0){
					//将未在解析的list存放到硬盘上
					saveMissObjToFile(result,i);
					result.clear();	//清除mr2List
				}
			}			
			
		}catch(IndexOutOfBoundsException e) {
			logger.error("When the result data is too much, the data is stored in the hard disk exception",e);
		}catch (Exception e) {
			logger.error(ExceptionPrintUtils.printExceptionStack(e));
		}
			
	}
	
	//写一个任务对象到一个文件后，清除列表里的这个任务对象
	public void saveMissObjToFile(LinkedList<MissionResult2> missObjList,int missionType) {
		String filePath = "";
		int missObjSize = missObjList.size();//如果不按此时的size来操作，则list里的数据可能会一直在增加，就会一直循环下去？
		try {
			String parPath = Constants.OVERRUN_RESULT_FILE_DIR.substring(0,Constants.OVERRUN_RESULT_FILE_DIR.length()-1);
			LinkedList<MissionResult2> tmpList = new LinkedList<MissionResult2>();
			for(int j=0;j<missObjSize;j++) {
				MissionResult2 result= missObjList.get(j);
				filePath = parPath+"/missionResult"+missionType+"/"+Common.getDateDirName()+"/"+Calendar.getInstance().getTimeInMillis()+"_"+j+".result";
				File file = new File(filePath);
				FileUtils.writeObjToFile(result, file);
				
				//在Common中删除掉已保存到硬盘的任务结果(其实就一个任务结果对象)
				tmpList.add(result);
				Common.removeResultsFormList(missionType, tmpList);
				tmpList.clear();
				
				logger.info("任务结果数据过多，已保存至"+filePath);
			}
			
		}catch(Exception e) {
			logger.error("When the result data is too much, the data is stored in the hard disk exception",e);
		}
	}
	
	
	public static void main(String[] args) {
		LinkedList<MissionResult2> ml = new LinkedList<MissionResult2>();
		MissionResult2 m1 = new MissionResult2();
		m1.setUuid(1l);
//		m1.setDescription("描述1-desc");
//		m1.setDescription("Description 1-desc");
		m1.setDescription("i18n_server.MissionResultManagerThread.desc_n81i 1-desc");
		m1.setMissionType(1l);
		MissionResult2 m2 = new MissionResult2();
		m2.setUuid(2l);
//		m2.setDescription("描述2-desc");
//		m2.setDescription("Description 2-desc");
		m2.setDescription("i18n_server.MissionResultManagerThread.desc_n81i 2-desc");
		m2.setMissionType(1l);
		MissionResult2 m3 = new MissionResult2();
		m3.setUuid(3l);
//		m3.setDescription("描述3-desc");
//		m3.setDescription("Description 3-desc");
		m3.setDescription("i18n_server.MissionResultManagerThread.desc_n81i 3-desc");
		m3.setMissionType(1l);
		
//		ml.add(m1);
//		ml.add(m2);
//		ml.add(m3);
//		new MissionResultManagerThread().saveMissObjToFile(result,1);
		
		Common.addResultToResultList(m1);
		Common.addResultToResultList(m2);
		Common.addResultToResultList(m3);
		
		LinkedList<MissionResult2> result = Common.getResultListClone(1);
		//-- 集合不为空则进行解析 存在removeList情况 ，优化方式可参考 监测数据解析的实现方式
		if(result!=null && result.size()>0){
			//将未在解析的list存放到硬盘上
			new MissionResultManagerThread().saveMissObjToFile(result,1);
//			Common.removeResultsFormList(1, result);	//在Common中删除掉已保存到硬盘的任务结果
			result.clear();	//清除mr2List
		}
	}

}
