package com.eactive.eai.rms.onl.common.service;

import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;

import com.eactive.eai.rms.common.util.CommonUtil;
import com.eactive.eai.rms.onl.dashboard.service.Dashboard2RepositoryService;

public class DashboardHostAliveJob implements Job{

    /**
     * Logger for this class
     */
    private static final Logger logger = Logger.getLogger(DashboardHostAliveJob.class);

    @Autowired
    @Qualifier("dashboard2RepositoryService")
    Dashboard2RepositoryService repositoryService;

    private int checkStep = 0 ;

    // every three minutes
    //@ScheduleMethod(type = ScheduleType.CRON, cronExpression = "0/30 * * * * ?")
    @Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
        //JobKey jobKey = context.getJobDetail().getKey();

 		ApplicationContext appContext = null;
 		try {
 			appContext = (ApplicationContext)context.getScheduler().getContext().get("applicationContext");
 		} catch (SchedulerException e) {
 			logger.error("applicationContext get module error",e);
 			return ;
 		}  
 		repositoryService = (Dashboard2RepositoryService)appContext.getBean("dashboard2RepositoryService");	
 		run();
	}    
    
    
    // 30초로 주기를 변경한다.
    //@ScheduleMethod(repeatInterval = 30000, type = ScheduleType.TIMER)
    public void run() { 
    	
    	checkStep++ ;
    	
//    	if( true ) return ;
    	
    	// 초기화 되지 않았을 경우 초기화 한다.
    	repositoryService.initHostAlive();
    	
    	boolean debug = logger.isDebugEnabled();
    	
    	List<String> list = repositoryService.getHostIPList();
    	for( String ip_port : list ) {
    		
    		// 최초 1초 동안 시도해 보고, 실패할 경우 5초동안 3번 시도하여 모두 실패할 경우
    		// 서버 다운 으로 간주한다.
    		
    		String arrTmp[] = ip_port.split(":");
    		if( arrTmp == null || arrTmp.length < 2 ) {
    			logger.error( "IP_PORT 값이 잘못지정되어 있습니다. =>" + arrTmp );
    			continue;
    		}
    		
    		String ip = arrTmp[0];
    		String sPort = arrTmp[1];
    		int    port = CommonUtil.getInt(sPort);    		
    		
    		if( checkStep > 1 ) {
    			// dead 상태인 것들만 체크한다.
    			if( repositoryService.isHostAlive(ip, sPort) ) {
    				continue;
    			}
    		} else {
    			// 전체 체크
    		}
    		
    		
    		boolean alive = false ;
    		if( CommonUtil.checkNode(ip, port, 2000)) {
    			if( debug ) {
    				logger.debug( "첫번째 시도 성공 : " + ip ) ;
    			}
    			alive = true;
    		} else {
    			// 실패했을 경우 시간을 길게 하여 다시 시도한다.
    			// 참고 : 서버 설정이 잘못된 경우, 시간이 많이 소요될 수 있다.
    			//       따라서 향후, 모니터링 대상에서 제외할 리스트를 관리하는 프라퍼티가 필요하다.
    			for( int i = 0 ; i < 3 ; i++ ) {
    				if( CommonUtil.checkNode(ip, port, 5000)) {
    					if( debug ) {
    						logger.debug( "두번째 재시도 (" + i + ") 성공 : " + ip );
    					}
    					alive = true ;
    					break ;
    				} else {
    					logger.error( "두번째 재시도 (" + i + ") 실패 !!! : " + ip );
    				}
    			}			
    		}
    		
    		repositoryService.setHostAlive(ip, sPort, alive);
    	}
    	
    	if( checkStep >= 6 ) {
    		checkStep = 0 ;
    	}
    }


}
