package com.eactive.eai.adapter.ftp;

import java.io.File;
import java.io.IOException;
import java.net.Socket;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPFile;

import com.eactive.eai.adapter.socket.config.ConfigurationContext;
import com.eactive.eai.adapter.socket.service.SocketService;
import com.eactive.eai.batch.common.CalendarUtil;
import com.eactive.eai.batch.common.LogUtil;
import com.eactive.eai.batch.common.StringUtil;
import com.eactive.eai.batch.doc.BatchDoc;
import com.eactive.eai.batch.ftp.FTPUtil;
import com.eactive.eai.batch.running.BatchRunningJobManager;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.Logger;

/**
 * 한국조폐공사(KMS) 연동
 * Java 1.7에서 jsch로 연동 불가하여 sshj 사용
 * Bandwith 삭제함
 * SFTP 송수신 중단 안됨
 */


public class FTPKM extends Transfer implements SocketService{

    private static final String PROP_GROUP_NAME_PREFIX = "TelegramInfo";
    private static final String SEND_REMOTE_PATH = "send.remote.path";
    private static final String SEND_DELAY_SEC   = "send.delay.sec";
    private static final String RECV_REMOTE_PATH = "recv.remote.path";
    private static final String REQ_FILE_NAME    = "req.file.name";

	public void sendFile(BatchDoc batchDoc) throws Exception {
		logger.info("[FTPKM] ■ FEP → 대외기관파일 송신 시작...... [" + batchDoc.getBatchMsg().getHeader().getUUID()+ "]");

		firstActivity = System.currentTimeMillis();
		setLastActivity();
		BatchRunningJobManager.getInstance().addRunningJobInfo( batchDoc.getBatchMsg().getHeader().getUUID(), this, batchDoc);
		//Shell 명령어를 Runtime 으로 실행
		try {
			String ipaddress = batchDoc.getBatchMsg().getHeader().getRemoteIP();
			int    port      = Integer.parseInt(batchDoc.getBatchMsg().getHeader().getPort());
			String userid    = batchDoc.getBatchMsg().getHeader().getUserID();
			String passwd    = batchDoc.getBatchMsg().getHeader().getUserPassword();
	        String propName = PROP_GROUP_NAME_PREFIX + "{" +
                    batchDoc.getBatchMsg().getHeader().getProcessCode() +
                    "_" +
                    batchDoc.getBatchMsg().getHeader().getInstitutionCode() + "}";
	        PropManager pmanager = PropManager.getInstance();

	        String authType = pmanager.getProperties(propName).getProperty(AUTH_TYPE);
	        if (StringUtils.isBlank(authType)) {
	        	authType = AUTH_TYPE_ID; // id
	        }
	        
			String remotePath = pmanager.getProperties(propName).getProperty(SEND_REMOTE_PATH);
			if ( remotePath == null ){
				throw new Exception("해당 기관에 전송 경로가 지정되어 있지 않습니다. -propName:" + propName + "," + SEND_REMOTE_PATH);
			}
			if ( !remotePath.endsWith("/") )
				remotePath = remotePath + "/";
			
			long delaySec = 60 * 1000;
			try {
				delaySec = Long.parseLong(pmanager.getProperties(propName).getProperty(SEND_DELAY_SEC));
				Thread.sleep(delaySec * 1000);
			}catch ( Exception e){}
			
			String sendFileName = batchDoc.getBatchMsg().getHeader().getFilePath() + "/" + batchDoc.getBatchMsg().getHeader().getRenamedFileName();
			//String remoteFileName = remotePath + batchDoc.getBatchMsg().getHeader().getFileName();
			String remoteFileName = batchDoc.getBatchMsg().getHeader().getFileName();
			
			setFileHeaderAndTrailer(batchDoc, new File(sendFileName));
			
			batchDoc.getBatchMsg().getBody().setPhaseStartTime(CalendarUtil.getCurrentTimeNoDash());
			LogUtil.setLogFileStart(batchDoc);
			
			FTPUtil.store(ipaddress, port, userid, passwd, remotePath + remoteFileName, sendFileName, true, batchDoc.getLogger(Logger.LOGGER_ADAPTER), authType);
//			FTPUtil.store(batchDoc, ipaddress, port, userid, passwd, remotePath, remoteFileName, sendFileName,  
//					 connTimeout,  setTimeout,  true,  bandWidth,  batchDoc.getLogger(ElinkLogger.LOGGER_ADAPTER), authType);
			
			batchDoc.getBatchMsg().getBody().setPhaseEndTime(CalendarUtil.getCurrentTimeNoDash());
			LogUtil.setLogFileEnd(batchDoc);

		} catch(Exception ex) {
            String[] msgArgs = new String[1];
            msgArgs[0] = batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIFJI002";
            String errMsg = ExceptionUtil.getErrorCode (ex, errCode, msgArgs);
			batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            batchDoc.getBatchMsg().getBody().setPhaseEndTime(CalendarUtil.getCurrentTimeNoDash());
            LogUtil.setErrorLog(batchDoc, ex.getMessage());
            logger.error( errMsg, ex );
            throw ex;
		} finally {
			BatchRunningJobManager.getInstance().removeRunningJobInfo( batchDoc.getBatchMsg().getHeader().getUUID());
			this.disconnect();
        }
		logger.info("[FTPKM] ■ FEP → 대외기관 파일 송신 완료. [" + batchDoc.getBatchMsg().getHeader().getUUID()+ "]");
	}

	public void recvFile(BatchDoc batchDoc) throws Exception {
		logger.info("[FTPKM] ■ 대외기관→FEP 파일 수신 시작...... ");
		firstActivity = System.currentTimeMillis();
		setLastActivity();
		BatchRunningJobManager.getInstance().addRunningJobInfo( batchDoc.getBatchMsg().getHeader().getUUID(), this, batchDoc);
		//2. System FTP Shell 명령어를 Runtime 으로 실행
		try {
			
			String ipaddress = batchDoc.getBatchMsg().getHeader().getRemoteIP();
			int    port      = Integer.parseInt(batchDoc.getBatchMsg().getHeader().getPort());
			String userid    = batchDoc.getBatchMsg().getHeader().getUserID();
			String passwd    = batchDoc.getBatchMsg().getHeader().getUserPassword();
			
	        String propName = PROP_GROUP_NAME_PREFIX + "{" +
                    batchDoc.getBatchMsg().getHeader().getProcessCode() +
                    "_" +
                    batchDoc.getBatchMsg().getHeader().getInstitutionCode() + "}";
	        PropManager pmanager = PropManager.getInstance();

	        String remotePath = pmanager.getProperties(propName).getProperty(RECV_REMOTE_PATH);
			if ( remotePath == null ){
				throw new Exception("해당 기관에 전송 경로가 지정되어 있지 않습니다. -propName:" + propName + "," + RECV_REMOTE_PATH);
			}
			if ( !remotePath.endsWith("/") )
				remotePath = remotePath + "/";

	        String authType = pmanager.getProperties(propName).getProperty(AUTH_TYPE);
	        if (StringUtils.isBlank(authType)) {
	        	authType = AUTH_TYPE_ID; // id
	        }
	        
			logger.debug( "[FTPKM]FileName:" + batchDoc.getBatchMsg().getHeader().getFileName());
			String reqFileName = batchDoc.getBatchMsg().getHeader().getFileName();
			String bizCode = batchDoc.getBatchMsg().getHeader().getBizCode();
			if ( DatetimeUtil.isRightDate(reqFileName.substring(bizCode.length()))){
				reqFileName = pmanager.getProperties(propName).getProperty(REQ_FILE_NAME);
				batchDoc.getBatchMsg().getHeader().setFileName(reqFileName);
			}
			logger.debug( "[FTPKM]reqFileName:" + reqFileName );
			
            try {
    			FTPFile[] list = FTPUtil.listFiles(ipaddress, port, userid, passwd, remotePath, null, true, batchDoc.getLogger(Logger.LOGGER_ADAPTER), authType);
    			for ( int inx = 0 ; inx < list.length; inx++){
    				FTPFile file = list[inx];
    				if ( file.getName().equals(reqFileName) ){
    					batchDoc.getBatchMsg().getHeader().setFileSize(file.getSize());
    					batchDoc.getBatchMsg().getBody().setRecCnt(1);
    					batchDoc.getBatchMsg().getBody().setPhaseStartTime(CalendarUtil.getCurrentTimeNoDash());
    		            batchDoc.getBatchMsg().getHeader().setFileName(file.getName());
    					LogUtil.setLogFileStart(batchDoc);
    					FTPUtil.retrieve(ipaddress, port, userid, passwd, remotePath + "/" + file.getName(), batchDoc.getBatchMsg().getHeader().getFilePath(), true, 
    							batchDoc.getLogger(Logger.LOGGER_ADAPTER), authType);
    					
    					batchDoc.getBatchMsg().getHeader().setTotRecCnt(1);
    					String recvFile = batchDoc.getBatchMsg().getHeader().getFilePath() + File.separator +  file.getName();
    					File rcvRealFile = new File( recvFile );
    					File rcvChkFile = new File( StringUtil.realToRootDir(recvFile) );

    					try {
    						File rcvArchFile = new File( StringUtil.realToArchDir(recvFile) );
    			            if (rcvRealFile.exists() && rcvRealFile.length() == batchDoc.getBatchMsg().getHeader().getFileSize() ) {
    			                rcvRealFile.renameTo(rcvArchFile);
    			    			rcvChkFile.createNewFile();
    			            }else{
    			            	throw new Exception("파일수신에 실패하였습니다.");
    			            }
    		                //File 종료시간 설정
    		    			batchDoc.getBatchMsg().getBody().setPhaseEndTime(CalendarUtil.getCurrentTimeNoDash());
    						LogUtil.setLogFileEnd(batchDoc);
    					} catch (Exception e) {
    						throw e;
    					}
    				}
    			}
            }catch ( Exception e ){
            	if ( !e.getMessage().contains("No such file"))
            		throw e;
            }
			
		           
        } catch(Exception ex) {
            String[] msgArgs = new String[1];
            msgArgs[0] = batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIFJI002";
            String errMsg = ExceptionUtil.getErrorCode (ex, errCode, msgArgs);
            batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            LogUtil.setErrorLog(batchDoc, ex.getMessage());
            logger.error( errMsg, ex );
            throw ex;
		} finally {
			this.disconnect();
        }
		logger.info("[FTPKM] ■ VAN사 → FEP 파일 수신 완료.");		
	}

	@Override
	public void shutdown() {
		
	}

	@Override
	public Socket getCurrentSocket() {
		return null;
	}

	@Override
	public boolean connect() {
		return false;
	}

	@Override
	public ConfigurationContext getContext() {
		return null;
	}

	@Override
	public void setControl(Object control) {
		
	}

	@Override
	public void notifyMessage() {
		
	}

	@Override
	public boolean idle(long timeout) {
		return false;
	}

	@Override
	public int getCurrentState() {
		return 0;
	}

	@Override
	public boolean isConnected() throws IOException {
		return false;
	}

	@Override
	public boolean isActive() {
		return false;
	}

	@Override
	public void checkActivity() {
		
	}

	@Override
	public String getRemoteIPAddress() {
		return null;
	}

	@Override
	public void setLastActivity() {
		lastActivity = System.currentTimeMillis();
	}

	@Override
	public long getFirstActivity() {
		return firstActivity;
	}

	@Override
	public long getLastActivity() {
		return lastActivity;
	}
}