package com.eactive.eai.batch.common;

import java.io.DataOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;

public class SMSManager {

    private static SMSManager instance = new SMSManager();
    public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
    
    public static SMSManager getInstance() {
        return instance;
    }    
    private Socket socket = null;
    private DataOutputStream dout = null;
    
    public static final String SMSINFO   = "SMSInfo";
    public static final String IP        = "ip";
    public static final String PORT      = "port";
    public static final String SENDER    = "sender";
    public static final String PRIORITY  = "priority";



    private SMSManager(){
    }

    public boolean sendSMS( String telno, String msg ){

    	if ( socket != null){
    		return false;
    	}
    	
    	try {
        	if ( !connect()) {
        		return false;
        	}
        	
            dout = new DataOutputStream(socket.getOutputStream());
            byte[] reqData = new byte[137];
            for ( int inx=0; inx < reqData.length; inx++){
            	reqData[inx] = ' ';
            }
            
//            SEND_REQUEST(문자전송요청)
//            "01199714977  01199756577  가나다라마바사가나다라마바사가나다라마바사가나다라마바사가나다라마바사가나다라마 kbdbsvr1 120061107233027       "
//            받는이번호 (자릿수 13Byte Fix, 형태 “01199714977  “, Left Shift , space filling)
//            보낸이번호 (자릿수 13Byte Fix, 형태 “01199714977  “, Left Shift , space filling)
//            메시지       (자릿수 80Byte Fix, 형태:문자형, Left Shift , space filling)
//            호스트 명  (자릿수:15Byte Fix, 형태 “kbdbsvr1       “, Left Shift , space filling)
//            우선구분   (자릿수:1Byte Fix,  형태:0-보통,1-긴급,2-우선)
//            전송일시   (자릿수:14Byte Fix, 형태: yyyyMMddHHmmss(24h))
//            총 137 Byte Fix 


    		// 받는이 전화 번호
            System.arraycopy( telno.getBytes(), 0, reqData, 0, Math.min(telno.getBytes().length, 13));
    		
            // 보내는 사람 전화 번호 : Rule Property 에서 읽어 온다.
    		String sender = PropManager.getInstance().getProperty(SMSINFO, SENDER);
        	if (sender != null){
        		System.arraycopy( sender.getBytes(), 0, reqData, 13, Math.min(sender.getBytes().length, 13));
        	}

            // 메시지
            System.arraycopy( msg.getBytes(), 0, reqData, 26, Math.min(msg.getBytes().length, 80));

            // 호스트명
            String hostname = InetAddress.getLocalHost().getHostName();
            System.arraycopy( hostname.getBytes(), 0, reqData, 106, Math.min(hostname.getBytes().length, 15));

            // 우선구분 0을 디폴트로...
    		String priority = PropManager.getInstance().getProperty(SMSINFO, PRIORITY);
    		if ( priority == null ) priority = "0";
            System.arraycopy( priority.getBytes(), 0, reqData, 121, Math.min(priority.getBytes().length, 1));
            
            // 전송일시
            SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
            String curDate = formatter.format(Calendar.getInstance().getTime());
            System.arraycopy( curDate.getBytes(), 0, reqData, 122, 14);
            
            logger.debug( "SMS MESSAGE :" + new String (reqData));
            dout.write(reqData);


		} catch (Exception e) {
			logger.error( e.getMessage(), e);
			return false;
		} finally {
			if ( socket != null ){
				try {
					socket.close();
				} catch (Exception e) {}
			}
			socket = null;
		}
    	return true;
    }

    
    private boolean connect() throws Exception{

    	String ipAdress = PropManager.getInstance().getProperty(SMSINFO, IP);
    	if (ipAdress == null) 
    		throw new Exception("'SMS서버 IP정보' 프라퍼티가 없습니다. (PropGroupName:"+ SMSINFO +", PropName:"+ IP +")");

    	String port = PropManager.getInstance().getProperty(SMSINFO, PORT);
    	if (port == null) 
    		throw new Exception("'SMS서버 PORT정보' 프라퍼티가 없습니다. (PropGroupName:"+ SMSINFO +", PropName:"+ PORT +")");
    	int nPortNum = -1;
		try {
			nPortNum = Integer.parseInt(port);

		} catch (Exception ex) {
			String errMsg = ExceptionUtil.getErrorCode(ex, "BECEAIFJC002", new String[] {port});
			throw new Exception(errMsg);
		}

		socket = socketInit(ipAdress, nPortNum);
		if (socket == null) {
			String errMsg = ExceptionUtil.getErrorCode("BECEAIFJC003");
			throw new Exception(errMsg);
		}

    	return true;
    }
    
    private Socket socketInit(String remoteIP, int remotePort) throws Exception
    {
        try {
            return new Socket(remoteIP, remotePort);
        
        } catch (UnknownHostException ex) {
            String errMsg = ExceptionUtil.getErrorCode(ex, "BECEAIASC001", new String[] {remoteIP, Integer.toString(remotePort)});
            throw new Exception(errMsg);	//Socket 연결 에러 (IP: %1, Port: %2), 서버를 찾을 수 없습니다.
        
        } catch (Exception ex) {
            String errMsg = ExceptionUtil.getErrorCode(ex, "BECEAIASC002", new String[] {remoteIP, Integer.toString(remotePort)});
            throw new Exception(errMsg);	//Socket 연결 에러 (IP: %1, Port: %2), I/O Exception이 발생했습니다.
        }
    }

}
