package com.nms.server.thread.mission;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import com.nms.server.bean.MissionResult;
import com.nms.server.bean.MissionResult2;
import com.nms.server.bean.MissionStateTable;
import com.nms.server.common.Common;
import com.nms.server.common.Constants;
import com.nms.server.common.MissionConstants;
import com.nms.server.dao.CommonDao;
import com.nms.server.service.EmailService;
import com.nms.server.service.UpgradeService;
import com.nms.server.thread.socket.NMSWebBPDownload;
import com.socket.utils.FileComment;

/**
 * 任务加载管理线程
 *  每两分钟执行一次，或接收激活
 *  @date Nov 9, 2011 3:28:45 PM
 *	@author ZhangGang
 *
 */
public class InitRunningMissionThread implements Runnable{
	/* 线程基本属性 */
	private Logger logger = Logger.getLogger(InitRunningMissionThread.class);
	volatile boolean stop = false;	//线程中断标示
	
	/* 业务操作属性 */
	private CommonDao dao = null;			//数据库链接
	private UpgradeService service = null;	//
	private EmailService emailService = null;	//
	private String missIds = null;

	
	public InitRunningMissionThread(String missIdsTmp){
		missIds = missIdsTmp;
	}
	
	@Override
	public void run(){
//		Thread.currentThread().setName("任务载入线程");
		Thread.currentThread().setName("Task Loading Thread");
		
		try {
			/* 任务加载错开并发时间 等待 0-20秒 */
		/*	int waitTime = (int)(Math.random()*20000);
			Thread.sleep(waitTime);
			logger.debug("任务加载时间ms："+waitTime);*/
			
			dao = new CommonDao();			//数据库链接
			service = new UpgradeService(dao);	//专属Service
			emailService = new EmailService(dao);

			List<MissionStateTable> missionList = service.getStartMessionList(missIds);

			//- 任务校验及加载处理业务
			if(missionList != null && missionList.size()>0){
//				ml:for(MissionStateTable mission : missionList){
				ml:for(int i=0;i<missionList.size() && !stop;i++){	//!stop 判断线程是否中断退出
					MissionStateTable mission  = missionList.get(i);
					
					logger.debug("Mission_Run 开始执行任务：Id:>"+mission.getMissionId()+" "+mission.getMissionState());
					if(mission.getMissionState()==null){	//后续可增加任务告警
						continue;
					}

					/* 任务状态为3、4、7 无需执行 不会出现 */
//					if(mission.getMissionState().intValue() == 3 
//							||mission.getMissionState().intValue() == 4 
//							||mission.getMissionState().intValue() == 7 ){
//						logger.debug("Mission_Run 任务：Id:>"+mission.getMissionId()+" 3、4、7状态 执行结束");
//						continue;
//					}
					
					
					/* 判断当前DC是否需要执行 */
					List<MissionResult> mrList = null;
						
					if(mission.getLoopFlag()!=null && mission.getLoopFlag().longValue()==1l){	//周期任务
						
						//- 任务时间的有效性校验
						if(mission.getEndTime()==null || mission.getEndTime().getTime() < System.currentTimeMillis() ){
							if(mission.getMissionState().longValue() ==2l){
								SimpleDateFormat format = new SimpleDateFormat(Constants.COMMON_DATE_FORMAT);
//								service.clearTimeoutLoopMisssion(mission.getMissionId());//2013-10-30 hyx 以下修改主任务表的状态，未修改结果表和loop表的状态
//								service.updateMissionState(mission.getMissionId(), 3,format.format(System.currentTimeMillis())+" 已超过任务结束时间 任务执行结束");
//								emailService.sendEmailForMission(mission.getMissionId(),"任务执行失败"," 已超过任务结束时间 任务执行结束");
//								logger.warn("已超过任务结束时间 任务执行结束");
//								service.updateMissionState(mission.getMissionId(), 3,format.format(System.currentTimeMillis())+" The task has exceeded the end time and the task execution has ended");
//								emailService.sendEmailForMission(mission.getMissionId(),"Task execution failure"," The task has exceeded the end time and the task execution has ended");
								service.updateMissionState(mission.getMissionId(), 3,format.format(System.currentTimeMillis())+" i18n_server.InitRunningMissionThread.outEndTime_n81i");
								emailService.sendEmailForMission(mission.getMissionId(),"i18n_server.InitRunningMissionThread.missionFail_n81i"," i18n_server.InitRunningMissionThread.outEndTime_n81i");
								logger.warn("The task has exceeded the end time and the task execution has ended");
							}
							/***告警功能****/
							continue ;
						}
						
						if(mission.getMissionState() == 2l){
							mrList = service.getMissionResultsForLoopTask(mission.getMissionId(), mission.getMissionType().intValue(),3);
						}else if(mission.getMissionState() ==6l){
							mrList = service.getMissionResultsForLoopTask(mission.getMissionId(), mission.getMissionType().intValue(),5);
						}
					}else{
						mrList = service.getMissionResultsForTask(mission.getMissionId(), mission.getMissionType().intValue());
					}
					
					if(mrList == null || mrList.size() ==0){	//当前DC无需执行执行
						continue;
					}
					logger.debug("Mission_Run 任务：Id:>"+mission.getMissionId()+((mrList == null || mrList.size() ==0)?"当前DC不执行":"当前DC执行下发"));
					
					/* 校验并下载附件 */
					List<FileComment> missionFileList = null ;
					if(mission.getMissionType().intValue() == 1 
							||mission.getMissionType().intValue() == 6){
						
						missionFileList = service.getMissionFileInformations(mission.getMissionId());
						logger.debug("Mission_Run 任务：Id:>"+mission.getMissionId()+("当前DC有附件 数量："+missionFileList.size()));
					}else{
						logger.debug("Mission_Run 任务：Id:>"+mission.getMissionId()+("当前DC无附件 "));
						Common.assignMssion(mission);
						continue;
					}

					String hostIp = service.getHostIpBySystemId(mission.getSystemId());
					Integer port = Constants.WEB_SOCKET_PORT;
					if(missionFileList != null && missionFileList.size()>0){
//						ServerTable serverTable = Common.getServerTable();
//						if(hostIp.equals(serverTable.getServerIp())){	// 同IP机器，尝试本地复制
//							try {
//								for(FileComment fileComment: missionFileList){
//									fileComment.
//									FileUtils.copyFile(srcFile, destFile);
//								}
//							} catch (Exception e) {
//								logger.equals("文件复制失败");
//							}
//						}
						
						//断点续传下载fileList 的线程结果
						Future<Object> bpf = Common.getBpDownMissionFilesMap().get(mission.getMissionId());
						
						//-- MD5校验在NMSWebBPDownload中
						//-- 未创建下载
						if(bpf == null){
							bpf = createDownload(mission.getMissionId(),hostIp,port,missionFileList);
							if(bpf == null){
								logger.debug("Mission_Run 任务：Id:>"+mission.getMissionId()+(" 附件下载失败 3分后再执行"));
								Common.scheduled.schedule(new LoadNewMissionThread(mission.getMissionId()),3,TimeUnit.MINUTES);
								continue ml;
							}
						}
						
						//-- 下载线程未终止 继续下载中 无操作
						if(!bpf.isDone()){
							logger.debug("Mission_Run 任务：Id:>"+mission.getMissionId()+(" 附件下载未完成 3分后再执行"));
							Common.scheduled.schedule(new LoadNewMissionThread(mission.getMissionId()),3,TimeUnit.MINUTES);
							continue ml;
						}
						
						//-- dff.getBpDownFuture().isDone() == true 已存在下载结果 
						int result = (Integer)bpf.get(1,TimeUnit.SECONDS);
						
						//-- MD5校验在NMSWebBPDownload中
						//-- 下载失败 则重试 0 成功 -1 -2 重试 -3 失败
						if(result == -1 || result == -2){
							bpf = createDownload(mission.getMissionId(),hostIp,port,missionFileList);
							if(bpf == null || !bpf.isDone()){
								Common.scheduled.schedule(new LoadNewMissionThread(mission.getMissionId()),3,TimeUnit.MINUTES);
								continue ml;
							}
						}
						
						//-- 下载成功
						boolean missionDFFlag = true;		//任务下所有文件 下载完成标识 false未完成 true已完成
						String errorFileName = null;
						mfl:for(FileComment fileInfo : missionFileList){
							
							File file = new File(Constants.MISSION_FILE_DOWNLOAD_DIR+fileInfo.getFileName());
							if(!file.exists()){	// 文件不存在，下载失败
								missionDFFlag =false;
								errorFileName = fileInfo.getFileName();
								break mfl;
							}
						}
						
						if(!missionDFFlag){
//							List<MissionResult2> mr2List = new ArrayList<MissionResult2>();
							//nodeList
							for( MissionResult mr :  mrList){
								MissionResult2 result2 = new MissionResult2();
								//- 任务Id long
								result2.setMissionId(mr.getMissionId());
								//-- 任务类型 long
								result2.setMissionType(mission.getMissionType());
								//- UUID long
								result2.setUuid(mr.getUuid());
								//- 周期标识 long
								result2.setLoopFlag(mission.getLoopFlag());
								//- 开始执行时间 long
								result2.setStartTime(null);
								//- 结束时间 long
								result2.setEndTime(null);
								//- 配置截取文本 string
								result2.setText(null);
								//- 结果状态 long
								result2.setResult(1l);
								//- 结果描述 string
								result2.setDescription(errorFileName+" "+MissionConstants.ERROR_RESULT_FILE_DOWNLOAD_FAIL);
//								mr2List.add(result2);
								Common.addResultToResultList(result2);//DC下载文件失败
							}
//							service.updateMissionResult2ByBatch(mission.getMissionType().intValue(),mr2List);
						}
						
						//清理缓存 和废弃文件
						if(!missionDFFlag){
							for(FileComment fileInfo : missionFileList){
								File file = new File(Constants.MISSION_FILE_DOWNLOAD_DIR+fileInfo.getFileName());
								if(file.exists()){
									file.delete();
									logger.debug(file.getAbsolutePath()+"已删除！");
								}else {
									logger.debug(file.getAbsolutePath()+"不存在");
								}
							}
						}else{
							//--该任务 已无文件可下载， 执行文件下发操作
							Common.assignMssion(mission);
							continue;
						}
					}else{
						//--该任务 已无文件可下载， 执行文件下发操作
						Common.assignMssion(mission);
						continue;
					}
				}
			}
		}catch (InterruptedException e) {
			logger.warn("Thread interrupt operation, execute exit",e);
		}
		catch (Exception e) {
			logger.error("loadNewMission error ",e);
		}finally{
			if(dao!=null){
				dao.close();
				dao=null;
			}
		}
	
	}

	/**
	 * 创建下载线程
	 * @time Mar 20, 2012-4:12:42 PM
	 * @param missionFileList
	 * @return
	 */
	private Future<Object> createDownload(Long missionId ,String ip,Integer port,List<FileComment> missionFileList){
		try {
			Future<Object> bpf = Common.service.submit(new NMSWebBPDownload(ip,port,missionFileList,Constants.MISSION_FILE_DOWNLOAD_DIR,NMSWebBPDownload.TYPE_MISSION));
			bpf.get(Constants.MISSION_FILE_DOWNLOAD_DELAY, TimeUnit.SECONDS);
			if(!bpf.isDone()){
				Common.getBpDownMissionFilesMap().put(missionId, bpf);
			}
			return bpf;
		} catch (Exception e) {
			logger.error("Failure to create a download thread ",e);
			return null;
		}
	}
	
	
	public static void main(String [] args) {
		Common.service.submit(new InitRunningMissionThread(null));
	}
}
