package com.nms.server.thread.overrunData;

import java.io.File;
import java.io.FileInputStream;
import java.util.Calendar;
import java.util.LinkedList;
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.thread.InitServerThread;
import com.nms.server.thread.alarmData.AlarmDataResoveThread;
import com.nms.server.thread.detecData.NewDetecDataResoveThread;
import com.nms.server.util.FileUtils;

/**
 * 本地暂时无法入库数据（监测数据、告警数据、任务结果）的解析入库线程
 * 
 * @author HYX
 * 
 */
public class DataFileReaderManagerThread implements Runnable {
	Logger logger = Logger.getLogger(DataFileReaderManagerThread.class);
	
	boolean stop = false;
	
	/**
	 * 若硬盘数据解析线程正在运行，则退出，否则，根据路径解析文件，存入缓存list，再调用相应的入库线程，最后清理一下临时文件
	 */
	public void run() {
		
		// 为当前线程命名，用与日志友好输出。
//		Thread.currentThread().setName("硬盘数据（监测数据、告警数据、任务结果：由于数据量过大，暂时无法入库，而存放在硬盘上的数据）解析入库管理线程");
		Thread.currentThread().setName("Hard Disk Data (Monitoring Data, Alarm data, Task results: Data stored on hard disk because data is too large, temporarily inaccessible, and stored on the hard disk)");
		
		//判断数据库连接是否可用
		if(!Common.isDbConnected()){
			logger.info("数据库连接不可用，操作结束");
			return ;
		}
		
		try {
			//要不要配置是否定时操作？？？？？
			readDetectFile();
			//readDetectDataFile();
			readWarningDataFile();
			readResultDataFile();
			
		} catch (Exception e) {
			logger.error("",e);
		}
	}
	
	/**
	 * 读取保存硬盘的监测数据
	 */
	public void readDetectFile(){
		try {
			
			int size = Common.getAllDeteDataNum();
			if(size > Constants.MAX_DETECT_DATA_RESOVE_LIMIT_NUM){
				logger.warn("内存缓存监测数据过多，size ：" + size );
				return;
			}
			logger.info("文件夹路径 :>" + Constants.OVERRUN_DETEC_FILE_DIR);
			File driFile = new File(Constants.OVERRUN_DETEC_FILE_DIR);
			
			if(driFile.exists()) {
				size = Constants.MAX_DETECT_DATA_RESOVE_LIMIT_NUM - size;

				// 获取目录下的.csv文件集合
				File[] filesTmp = FileUtils.listAllFilesEndWith(driFile, "csv");
				File[] files = FileUtils.sortByFileNameASC(filesTmp); // 按文件名称 升序排序
				
				// 解析文件数为0时，终止该计划任务
				if(files==null || files.length==0){
					return;
				}
				
				int count =0;
				for(File f : files){
					if(count > size){
						break;
					}
					int len = (int)f.length();
					if(len <1){
						continue;
					}
					FileInputStream fis = null ;
					try {
						fis = new FileInputStream(f);
						byte[] dsb = new byte[len];
						fis.read(dsb);
						Common.addDeteData(dsb);
						
						count ++;
					} catch (Exception e) {
						FileUtils.copyFile(f, new File(Constants.ERROR_DETEC_FILE_DIR+"/"+f.getName()));
						logger.error("Hard disk data (monitoring data) file reading error："+Constants.ERROR_DETEC_FILE_DIR+"/"+f.getName(),e);
					} finally {
						if(fis != null){
							fis.close();
						}
						boolean delete = f.delete();
					}
				}
				logger.info("本次共从硬盘读取  " + count + " 个文件");
			}		
		} catch (Exception e) {
			logger.error("",e);
		}
	}
	
	
	/**
	 * 
	 * 硬盘监测数据 解析入库
	 * @author Administrator Feb 21, 2013
	 * @version 1.0 
	 */
	public void readDetectDataFile() {
		try {
			
			long sTime = System.currentTimeMillis();
			Future<?> future = Common.getFutureMap().get(Constants.OVRERUN_DETEC_DATA_RESOVE);
			//线程不存在 创建和注册
			if(future != null && !future.isCancelled() && !future.isDone()){
				logger.info("硬盘监测数据 解析入库线程 运行中 不再启动新线程");
				return ;
			}else {

				logger.info("文件夹路径 :>" + Constants.OVERRUN_DETEC_FILE_DIR);
				File driFile = new File(Constants.OVERRUN_DETEC_FILE_DIR);
				
				if(driFile.exists()) {
					// 获取目录下的.csv文件集合
					File[] filesTmp = FileUtils.listAllFilesEndWith(driFile, "csv");
					File[] files = FileUtils.sortByFileNameASC(filesTmp); // 按文件名称 升序排序
					
					// 解析文件数为0时，终止该计划任务
					if(files==null || files.length==0){
//					Common.cancelRunnableAtOnce(Constants.OVERRUN_DATA_RESOVE_MANAGER);//???
						return;
					}
					
					logger.debug("文件夹路径 :>" + driFile.getAbsolutePath() + " 下 "  + files.length + "个文件，解析开始");
					int max = 1000,i=0;
					long l = Calendar.getInstance().getTimeInMillis();
					if (files != null && files.length > 0) {
						LinkedList<byte[]> dataList = new LinkedList<byte[]>();
						
						for (File file : files) {
							i++;
							if(i>max){
								break;
							}
							if(file.length()>0){
								try {
									FileInputStream fis = new FileInputStream(file);
									
									int fileLength = (int) file.length();		//大小
									int len = 0;
									byte[] buff = new byte[fileLength];
									if(fileLength>0){
										len = fis.read(buff);
									}
									if(buff.length==0){continue;}
									
									dataList.add(buff);
									fis.close();
									file.delete();
								} catch (Exception e) {//???????
									FileUtils.copyFile(file, new File(Constants.ERROR_DETEC_FILE_DIR+"/"+file.getName()));
									logger.error("Hard disk data (monitoring data) file reading error："+Constants.ERROR_DETEC_FILE_DIR+"/"+file.getName(),e);
								}
							}
						}
						
						if(dataList!=null&&dataList.size()>0) {
							//监测数据
//							future = Common.dataResoveService.submit(new NewDetecDataResoveThread("硬盘监测数据解析执行线程 启动",dataList));
							future = Common.dataResoveService.submit(new NewDetecDataResoveThread("Hard Disk Monitoring Data Parsing Execution Thread Startup",dataList));
							//注册
							Common.getFutureMap().put(Constants.OVRERUN_DETEC_DATA_RESOVE, future);
							
						}
						
					}
					logger.debug(driFile.getAbsolutePath()+" 解析csv文件完成耗时：>"+(Calendar.getInstance().getTimeInMillis()-sTime));
					
					//清理文件
					files = FileUtils.sortByFileNameASC(FileUtils.listAllFilesEndWith(driFile, "tp")); // 按文件名称 升序排序
					if(files!=null && files.length>0){
						for(File file : files){
							file.delete();
						}
					}
					logger.debug("临时文件清理完成");
				}
			}
			
		} catch (Exception e) {
			logger.error("",e);
		}
	}
	
	/**
	 * 
	 * 硬盘告警数据 解析入库
	 * @author Administrator Feb 21, 2013
	 * @version 1.0 
	 */
	public void readWarningDataFile() {
		try {
			
			
			Future<?> future = Common.getFutureMap().get(Constants.OVRERUN_WARNING_DATA_RESOVE);
			//线程不存在 创建和注册
			if(future != null && !future.isCancelled() && !future.isDone()){
				logger.info("硬盘告警数据 解析入库线程 运行中 不再启动新线程");
				return ;
			}else {
				
				logger.info("文件夹路径 :>" + Constants.OVERRUN_WARNING_FILE_DIR);
				File driFile = new File(Constants.OVERRUN_WARNING_FILE_DIR);
				
				if(driFile.exists()) {
					// 获取目录下的.csv文件集合
					File[] filesTmp = FileUtils.listAllFilesEndWith(driFile, "csv");
					File[] files = FileUtils.sortByFileNameASC(filesTmp); // 按文件名称 升序排序
					
					// 解析文件数为0时，终止该计划任务
					if(files==null || files.length==0){
//					Common.cancelRunnable(Constants.OVERRUN_DATA_RESOVE_MANAGER);//???
						return;
					}
					logger.debug("文件夹路径 :>" + driFile.getAbsolutePath() + " 下 "  + files.length + "个文件，解析开始");
					int max = 500,i=0;
					long l = Calendar.getInstance().getTimeInMillis();
					if (files != null && files.length > 0) {
						LinkedList<String[]> dataList = new LinkedList<String[]>();
						
						for (File file : files) {
							i++;
							if(i>max){
								break;
							}
							if(file.length()>0){
								try {
									String[] warnStr = FileUtils.readFileToString(file).split(Constants.COMMON_DATA_SPLIT);
									
									dataList.add(warnStr);
									file.delete();
								} catch (Exception e) {//???????
									FileUtils.copyFile(file, new File(Constants.ERROR_DETEC_FILE_DIR+"/"+file.getName()));
									logger.error("Hard disk data (alarm data) file reading error："+Constants.ERROR_DETEC_FILE_DIR+"/"+file.getName(),e);
								}
							}
						}
						
						if(dataList!=null&&dataList.size()>0) {
							//告警数据
//							future = Common.service.submit(new AlarmDataResoveThread("硬盘告警数据解析执行线程 启动",dataList));
							future = Common.service.submit(new AlarmDataResoveThread("Hard disk alarm data parsing execution thread startup",dataList));
							//注册
							Common.getFutureMap().put(Constants.OVRERUN_WARNING_DATA_RESOVE, future);
						}
						
					}
					logger.debug(driFile.getAbsolutePath()+" 解析完成耗时：>"+(Calendar.getInstance().getTimeInMillis()-l));
					
					//清理文件
					files = FileUtils.sortByFileNameASC(FileUtils.listAllFilesEndWith(driFile, "tp")); // 按文件名称 升序排序
					if(files!=null && files.length>0){
						for(File file : files){
							file.delete();
						}
					}
					logger.debug("临时文件清理完成");
				}
			}
			
		} catch (Exception e) {
			logger.error("",e);
		}
	}
	
	/**
	 * 
	 * 硬盘任务结果数据 解析入库
	 * @author Administrator Feb 21, 2013
	 * @version 1.0 
	 */
	public void readResultDataFile() {

//		try {
//			
//			
			Future<?> future = Common.getFutureMap().get(Constants.OVRERUN_RESULT_DATA_RESOVE);
			//线程不存在 创建和注册
			if(future != null && !future.isCancelled() && !future.isDone()){
				logger.info("硬盘任务结果数据 解析入库线程 运行中 不再启动新线程");
				return ;
			}else {
				logger.info("文件夹路径 :>" + Constants.OVERRUN_RESULT_FILE_DIR);
//				
//				//任务结果
//				future = Common.service.submit(new MissionResultFileResoveThread("硬盘任务数据解析执行线程 启动",Constants.OVERRUN_RESULT_FILE_DIR));
				future = Common.service.submit(new MissionResultFileResoveThread("Hard disk alarm data parsing execution thread startup",Constants.OVERRUN_RESULT_FILE_DIR));
//				//注册
				Common.getFutureMap().put(Constants.OVRERUN_RESULT_DATA_RESOVE, future);
//				
//				/**/
//				
//				
//				File driFile = new File(Constants.OVERRUN_RESULT_FILE_DIR);
//				
//				if(driFile.exists()) {
//					// 获取目录下的.csv文件集合
//					File[] filesTmp = FileUtils.listAllFilesEndWith(driFile, "result");
//					File[] files = FileUtils.sortByFileNameASC(filesTmp); // 按文件名称 升序排序
//					
//					// 解析文件数为0时，终止该计划任务
//					if(files==null || files.length==0){
////					Common.cancelRunnable(Constants.OVERRUN_DATA_RESOVE_MANAGER);//???
//						return;
//					}
//					
//					logger.debug("文件夹路径 :>" + driFile.getAbsolutePath() + " 下 "  + files.length + "个文件，解析开始");
//					int max = 1000,i=0;
//					long l = Calendar.getInstance().getTimeInMillis();
//					if (files != null && files.length > 0) {
//						
//						for (File file : files) {
//							i++;
//							if(i>max){
//								break;
//							}
//							if(file.length()>0){
//								try {
//									
//									MissionResult2 missObj = (MissionResult2)FileUtils.readObjFomFile(file);									
//									Common.addResultToResultList(missObj);
//									file.delete();
//								} catch (Exception e) {//???????
//									FileUtils.copyFile(file, new File(Constants.ERROR_DETEC_FILE_DIR+"/"+file.getName()));
//									logger.error("硬盘数据（监测数据）文件读取错误："+Constants.ERROR_DETEC_FILE_DIR+"/"+file.getName(),e);
//								}
//							}
//						}
//						
//						//任务结果
//						future = Common.service.submit(new MissionResultThread("硬盘任务数据解析执行线程 启动"));
//						//注册
//						Common.getFutureMap().put(Constants.OVRERUN_RESULT_DATA_RESOVE, future);
//						
//					}
//					logger.debug(driFile.getAbsolutePath()+" 解析完成耗时：>"+(Calendar.getInstance().getTimeInMillis()-l));
//					
//					//清理文件
//					files = FileUtils.sortByFileNameASC(FileUtils.listAllFilesEndWith(driFile, "tp")); // 按文件名称 升序排序
//					if(files!=null && files.length>0){
//						for(File file : files){
//							file.delete();
//						}
//					}
//					logger.debug("临时文件清理完成");
//				}
			}
//			
//		} catch (Exception e) {
//			logger.error("",e);
//		}
	}

	public static void main(String[] args) {
		CommonDao dao = null;
		try {
			dao = new CommonDao();
			InitServerThread init = new InitServerThread();
			init.initCommonInfo(dao);
			DataFileReaderManagerThread dt = new DataFileReaderManagerThread();
			dt.run();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if(dao!=null){
				dao.close();
				dao=null;
			}
		}
	}
}
