//package com.eactive.eai.adapter.socket.service;
//
//import java.io.IOException;
//import java.net.InetAddress;
//import java.net.Socket;
//import java.nio.ByteBuffer;
//
//import com.eactive.eai.adapter.socket.common.CommonLib;
//import com.eactive.eai.adapter.socket.common.DiagLogger;
//import com.eactive.eai.adapter.socket.common.SocketAdapterException;
//import com.eactive.eai.adapter.socket.config.ConfigurationContext;
//import com.eactive.eai.adapter.socket.config.SocketAdapterManager;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//import java.net.InetSocketAddress;
//import java.nio.channels.SocketChannel;
//
//public class ReaderClient extends Thread implements SocketService {
//
//	private ConfigurationContext context;
//	private boolean				 active;
//	private NBChannel	 		 channel;
//
//	private int					 sendCount;
//	private int					 recvCount;
//    private long				 firstActivity;
//    private long				 lastActivity;
//
//	private boolean				 retryFlag;
//
//	private ByteBuffer			 incomingMessage;
//
//	private ByteBuffer			 lenBuffer;
//	private Logger               logger;
//	private static Logger        errLogger = SocketLogManager.getInstance().getErrLogger();
//
//    private WriterClient         writer;
//
//    public ReaderClient(ConfigurationContext context) {
//
//        String name = this.getName();
//        this.setName( context.getAdapterName() + "-CONNECTION-READER" + name.substring( name.lastIndexOf("-")) );
//
//    	this.context 	= context;
//        active			= true;
//        retryFlag		= true;
//
//        incomingMessage	= null;
//
//        lenBuffer		= ByteBuffer.allocate( this.context.getLlFieldLength() );
//        lenBuffer.clear();
//
//        sendCount		= 0;
//        recvCount		= 0;
//        firstActivity	= System.currentTimeMillis();
//        lastActivity	= firstActivity;
//
//        logger          = SocketLogManager.getInstance().getLogger( context.getAdapterGroupName() );
//
//    }
//
//    public void addSendCount() {
//        this.sendCount++;
//    }
//
//    public void setLastActivity(long lastAccess) {
//        this.lastActivity   = lastAccess;
//    }
//
//    public void shutdownWriter() {
//        // 2005.10.17 --
//        shutdown();
//        writer = null;
//    }
//
//    private int getTraceLevel() {
//    	return context.getTraceLevel();
//    }
//
//    private long getTimeout() {
//    	return ( this.context.getTimeout() * 1000L );
//    }
//
//    private boolean isSocketReuse() {
//    	return this.context.getSocketReuse().equals( ConfigurationContext.TRUE_FLAG );
//	}
//
//	/**
//	 * @return Returns the context.
//	 */
//	public ConfigurationContext getContext() {
//		return context;
//	}
//
////    private boolean isSyncMode() {
////    	return context.isSyncMode();
////    }
//
//    public void run() {
//
//        String  socketInfo = "";
//
//    	while ( retryFlag ) {
//
//	    	active = true;
//
//	    	try {
//	    		openChannel();
//                socketInfo = this.getSocketInfo( this.getCurrentSocket() );
//	        } catch(Exception e) {
//                String errMsg = CommonLib.getMessage("BECEAIASI002", new String[]{context.getAdapterName(), "openChannel", e.getMessage(), "", "" } );
//                logger.error( errMsg, e );
//
//	        	waitRecoverConnection();
//	        	continue;
//	        }
//
//            if ( getTraceLevel() >= DiagLogger.INFO ) {
//                logger.info( CommonLib.getMessage("BICEAIASI002", new String[]{ context.getAdapterName(), socketInfo , Thread.currentThread().getName() }) );
//            }
//
////	        int				msgLen = 0;
//
//            writer = new WriterClient( this.context, this.channel, this );
//            writer.start();
//
//        	while ( active ) {
//        		try {
//        			lenBuffer.clear();
//
//        			incomingMessage = ByteBuffer.allocate( readLength( lenBuffer ) );
//        			processReadMessage( incomingMessage );
//
//                    this.checkActivity();
//
//        			lastActivity	= System.currentTimeMillis();
//        			recvCount++;
//
//        			// 메시지수신
//        			if ( getTraceLevel() >= DiagLogger.DEBUG ) {
//                        logger.debug( CommonLib.getMessage("BDCEAIASI001", new String[]{context.getAdapterName(), "RECV", CommonLib.getTimestamp(), socketInfo, CommonLib.getDumpMessage(incomingMessage.array())}));
//                    }
//
//                    incomingMessage.clear();
//                    lenBuffer.clear();
//
//                    InboundControl	control = new InboundControl( context.getAdapterGroupName(), context.getAdapterName(), getTimeout() );
//                    control.setRequest( incomingMessage.array() );
//                    control.setResponseType( context.getResponseType() );
//
////        			byte[] rtnValue = null;
//
//                    try {
////                        rtnValue = 
//                        control.request();
//                    } catch( Exception e ) {
////                        rtnValue = 
////                        e.getMessage().getBytes();
//
//                        logger.error( e.getMessage(), e );
//                        logger.error( CommonLib.getMessage("BDCEAIASI001", new String[]{context.getAdapterName(), "RECV", CommonLib.getTimestamp(), socketInfo, CommonLib.getDumpMessage( control.getRequest() )}));
//
//                        if ( logger != errLogger ) {
//                            errLogger.error( e.getMessage(), e );
//                            errLogger.error( CommonLib.getMessage("BDCEAIASI001", new String[]{context.getAdapterName(), "RECV", CommonLib.getTimestamp(), socketInfo, CommonLib.getDumpMessage( control.getRequest() )}));
//                        }
//                    }
//
//                    if ( !isSocketReuse() ) {
//                        active = false;
//                        closeChannel();
//                    }
//        		} catch( Exception e ) {
//                    String errMsg = "";
//                    if ( lenBuffer.position() > 0 ) {
//                        errMsg = CommonLib.getMessage("BECEAIASI002", new String[]{context.getAdapterName(), "processReadMessage", e.getMessage(), "수신메시지", getReadingMessage() } );
//                    }
//
//                    if ( errMsg.length() > 0 ) {
//                        logger.error( errMsg , e);
//
//                        if ( logger != errLogger ) {
//                            errLogger.error( errMsg, e );
//                        }
//                    }
//
//                    active = false;
//                    writer.shutdown();
//
//                    waitRecoverConnection();
//                    lenBuffer.clear();
//                    continue;
//        		}
//        	}	// end of active
//    	}	// end of retry
//
//        try {
//            if ( writer != null ) {
//                writer.shutdown();
//            }
//        } catch( Throwable e ) {}
//
//        try {
//            closeChannel();
//        } catch( Throwable e ) {}
//
//    	SocketAdapterManager.getInstance().removeConnection( this );
//
//        if ( getTraceLevel() >= DiagLogger.INFO ) {
//            logger.info( CommonLib.getMessage("BICEAIASI003", new String[]{ context.getAdapterName(), socketInfo, Thread.currentThread().getName() }) );
//        }
//
//        interrupt();
//
//    } // end of startup ...
//
//    private String  getReadingMessage() {
//        String rMsg = "";
//        if ( incomingMessage != null && incomingMessage.position() > 0 ) {
//            byte[] dMsg = new byte[ incomingMessage.position() ];
//            System.arraycopy( incomingMessage.array(), 0, dMsg, 0, dMsg.length );
//            rMsg = CommonLib.getDumpMessage( dMsg );
//        }
//        return rMsg;
//    }
//
//    private String  getSocketInfo(Socket socket) {
//        StringBuffer connInfo = new StringBuffer();
//
//        connInfo.append("Local Address=");
//        connInfo.append( socket.getLocalAddress().getHostAddress()).append(":").append(socket.getLocalPort()).append(", ");
//        connInfo.append("Remote Address=");
//        connInfo.append( socket.getInetAddress().getHostAddress()).append(":").append(socket.getPort());
//
//        return connInfo.toString();
//    }
//
//    public boolean idle(long timeout) {
//        long idleTime   = System.currentTimeMillis() - this.lastActivity;
//
//        return ( idleTime > timeout );
//    }
//
//    public void setControl(Object control) {
//    }
//
//    public void notifyMessage() {
//    }
//
//    public int getCurrentState() {
//        return CommonLib.PROCESSING_PROTOCOL;
//    }
//
//    private void resetCount() {
//        this.recvCount = 0;
//        this.sendCount = 0;
//    }
//
//    public boolean isConnected() {
//        return true;
//    }
//
//    public String getRemoteIPAddress() {
//        return null;
//    }
//
//    public void checkActivity() {
//        long currentTime = System.currentTimeMillis();
//        if ( !CommonLib.getDate( this.lastActivity ).equals( CommonLib.getDate( currentTime )) ) {
//            this.resetCount();
//        }
//    }
//
//    /**
//     * Socket Recovery Manager에 의해 Connection Recovery가 되도록 기다린다.
//     *
//     */
//    public synchronized void waitRecoverConnection() {
//    	try {
//            if ( !retryFlag ) return;
//
//    		try { closeChannel(); } catch(Exception ie) {}
//            if ( retryFlag && SocketAdapterManager.getInstance().addError( this ) ) {
//                wait();
//            }
//    	} catch ( InterruptedException e ) {}
//    }
//
//    /**
//     * Socket Recovery Manager에 의해 recovery되면 Socket Recovery Manager에 의해 통지된다.     *
//     */
//
//    public synchronized void notifyRecoverConnection() {
//    	notify();
//    }
//
//    private int readLength( ByteBuffer buffer ) throws Exception {
//        int length = 0;
//
//        long waitTime	= ( getTimeout() <= 0 ) ? System.currentTimeMillis() : getTimeout();
//        long start		= 0;
//        long msecs		= waitTime;
//
//        while ( buffer.position() < buffer.capacity() ) {
//	        while ( buffer.position() < buffer.capacity() ) {
//	            length = channel.read( buffer );
//
//	            if ( start == 0L && buffer.position() > 0 ) {
//	            	start = System.currentTimeMillis();
//	            } else if ( start > 0 ) {
//	            	waitTime = msecs - (System.currentTimeMillis() - start);
//	            }
//
//	            if ( waitTime <= 0 ) {
//                    byte[] lmsg = new byte[ buffer.position() ];
//                    System.arraycopy( buffer.array(), 0, lmsg, 0, lmsg.length );
//                    String errMsg = CommonLib.getMessage("BECEAIASI006", new String[]{context.getAdapterName(), getSocketInfo(getCurrentSocket()), Long.toString(getTimeout()), "수신",  "X'" + CommonLib.byte2Hex( lmsg )+ "'"  });
//
//                    logger.error( errMsg );
//
//                    if ( logger != errLogger ) {
//                        errLogger.error( errMsg );
//                    }
//                    throw new Exception( errMsg );
//	            }
//	            if ( length < 1 ) break;
//	        }
//	        //* 2005.10.17
//            //if ( !active ) throw new Exception("어뎁터중지명령에 의해 CLOSED되었습니다.");
//            // *정상적인 Normal Shutdown을 위한 확인...
//
//            if ( length == 0 && buffer.position() == 0 && !retryFlag ) {
//                String errMsg = CommonLib.getMessage("BICEAIASI004", new String[]{context.getAdapterName(), getSocketInfo(getCurrentSocket())});
//                if ( getTraceLevel() >= DiagLogger.INFO ) {
//                    logger.info( errMsg );
//                }
//                throw new Exception( errMsg  );
//            }
//
//            if(length == -1) {
//                if ( buffer.position() > 0 ) {
//                    throw new Exception( CommonLib.getMessage("BECEAIASI003", new String[]{context.getAdapterName(), getSocketInfo(getCurrentSocket())}) );
//                } else {
//                    String errMsg = CommonLib.getMessage("BICEAIASI004", new String[]{context.getAdapterName(), getSocketInfo(getCurrentSocket())});
//                    if ( getTraceLevel() >= DiagLogger.INFO ) {
//                        logger.info( errMsg );
//                    }
//                    throw new Exception( errMsg  );
//                }
//            }
//
//	        if ( buffer.position() == buffer.capacity() ) {
//	        	length = checkLengthField( buffer );
//	        }
//
//        }
//
//        return length;
//    }
//
//
//    private void processReadMessage( ByteBuffer buffer ) throws Exception {
//        int i = 0;
//        boolean isDone = false;
//        buffer.clear();
//
//        long waitTime	= ( getTimeout() <= 0 ) ? System.currentTimeMillis() : getTimeout();
//        long start		= System.currentTimeMillis();
//        long msecs		= waitTime;
//
//        while ( !isDone ) {
//
//	        while ( buffer.position() < buffer.capacity() ) {
//	            i = channel.read( buffer );
//
//	            waitTime = msecs - (System.currentTimeMillis() - start);
//
//	            if ( waitTime <= 0 ) {
//                    String errMsg = CommonLib.getMessage("BECEAIASI006", new String[]{context.getAdapterName(), getSocketInfo(getCurrentSocket()), Long.toString(getTimeout()), "수신",  getReadingMessage() });
//
//                    logger.error( errMsg );
//
//                    if ( logger != errLogger ) {
//                        errLogger.error( errMsg );
//                    }
//                    throw new Exception( CommonLib.getMessage("BECEAIASI006", new String[]{context.getAdapterName(), getSocketInfo(getCurrentSocket()), Long.toString(getTimeout()), "",  "" }) );
//	            }
//
//                if ( i < 1 ) break;
//	        }
//
//	        if(i == -1) {
//	            throw new Exception( CommonLib.getMessage("BECEAIASI003", new String[]{context.getAdapterName(), getSocketInfo(getCurrentSocket())}) );
//	        } else if ( buffer.position() == buffer.capacity() ) {
//	            isDone = true;
//	        }
//        } // end of while
//    } // end of readData
//
//    private int checkLengthField(ByteBuffer buffer) throws SocketAdapterException {
//    	int length = 0;
//
//        if ( buffer.capacity() == 2 ) {
//    		length = ( buffer.getShort(0) & 0xFFFF );
//    	} else if ( buffer.capacity() == 4 ) {
//    		length = ( buffer.getInt(0) );
//            if ( length < 0 ) {
//    			throw new SocketAdapterException( CommonLib.getMessage("BECEAIASI009", new String[]{context.getAdapterName(), getSocketInfo(getCurrentSocket()), CommonLib.byte2Hex( buffer.array() ) }) );
//            }
//    	} else {
//    		String lenStr = new String( buffer.array() );
//    		try {
//    			length = Integer.parseInt( lenStr );
//    		} catch ( NumberFormatException e ) {
//    			throw new SocketAdapterException( CommonLib.getMessage("BECEAIASI009", new String[]{context.getAdapterName(), getSocketInfo(getCurrentSocket()), CommonLib.byte2Hex( buffer.array() ) }) );
//    		}
//    	}
//    	return length;
//
//    }
//
//    public boolean isActive() {
//        return retryFlag;
//    }
//
//    public synchronized void shutdown() {
//
//        active    = false;
//        retryFlag = false;
//
//        try {
//            notify();
//        } catch( Exception e ) {}
//
//        //* 2005.10.17
//        try {
//            this.channel.wakeup();
//        } catch( Throwable e ) {}
//
//        /*
//        try {
//            writer.shutdown();
//        } catch( Exception e ) {}
//        */
//
//        // to gracefully shutdown the thread
//        try {
//            closeChannel();
//        } catch (Exception e) {}
//        //interrupt();
//    }
//
//    public Socket getCurrentSocket() {
//    	return channel.getSocket();
//    }
//
//    public boolean connect() {
//    	if ( !retryFlag ) return true;
//
//    	try {
//    		openChannel();
//    		return true;
//    	} catch ( Exception e ) {
//    		return false;
//		}
//    }
//
//    public void disconnect() {
//    	shutdown();
//    }
//
//    private synchronized void openChannel() throws IOException {
//
//    	if ( channel == null || !channel.isOpen() ) {
//    		// Sleep Time조정.... HotDeploy시 Multi Connection 현상방지...
//    		//try {
//    		//	Thread.sleep( 1000L );
//    		//} catch( InterruptedException e ) {
//            //    if ( !retryFlag ) return;
//            //}
//    		if ( !retryFlag ) return;
//
//	        SocketChannel socketChannel = SocketChannel.open();
//	        //if ( context.getLocalHostName() != null && !context.getLocalHostName().equals("") && context.getLocalPortNumber() > 1024 ) {
//	        if ( context.getLocalHostName() != null && !context.getLocalHostName().equals("") ) {
//	        	socketChannel.socket().bind( new InetSocketAddress( InetAddress.getAllByName(context.getLocalHostName())[0], context.getLocalPortNumber() ) );
//                socketChannel.connect( new InetSocketAddress( context.getHostName(), context.getPortNumber() ) );
//                //socket = new Socket(context.getHostName(), context.getPortNumber(), InetAddress.getAllByName(context.getLocalHostName())[0], context.getLocalPortNumber() );
//	        } else {
//                socketChannel.connect( new InetSocketAddress( context.getHostName(), context.getPortNumber() ) );
//	        	//socket = new Socket(context.getHostName(), context.getPortNumber());
//	        }
//
//            socketChannel.socket().setTcpNoDelay(true);
//            socketChannel.configureBlocking(false);
//
//            if ( isSocketReuse() ) {
//	        	socketChannel.socket().setSoLinger(true, 0);
//	        }
//
//	        channel			= new NBChannel( socketChannel, getTimeout() );
//
//            // Connection 시 통계자료 RESET
//            this.firstActivity  = System.currentTimeMillis();
//            this.lastActivity   = this.firstActivity;
//            this.sendCount      = 0;
//            this.recvCount      = 0;
//
//            try {
//                Thread.sleep( 300L );
//            } catch( Exception e ) {}
//
//            if ( !this.isConnected() ) {
//                throw new IOException("Closed by Server");
//            }
//
//            if ( retryFlag ) {
//                //
//                SocketAdapterManager.getInstance().addConnection( this );
//            } else {
//                closeChannel();
//            }
//
//    	}
//    }
//
//    private synchronized void closeChannel() throws IOException {
//
//        if(channel != null ) {
//            channel.close();
//        }
//        channel = null;
//    } //
//
//    // 1. Connection 리스트정보 - AdapterGroupName,AdapterName,업무코드,INBOUND, CLIENT, SYNC, LocalIP:Port, RemoteIP:Port, 송신건수, 수신건수, 상태, 최초연결시각, 최종사용시각
//    public String toString() {
//        boolean status = true;
//        StringBuffer strBuff = new StringBuffer();
//        strBuff.append(context.getAdapterGroupName()).append(",");
//        strBuff.append(context.getAdapterName()).append(",");
//        strBuff.append(context.getBwkClsCd()).append(",").append(context.getBoundUsage()).append(",");
//        strBuff.append(context.getSocketType()).append(",");
//        strBuff.append(context.getResponseType()).append(",");
//        try {
//            strBuff.append( getCurrentSocket().getLocalAddress().getHostAddress()).append(":").append(getCurrentSocket().getLocalPort()).append(",");
//        } catch( Throwable e ) {
//            status = false;
//            strBuff.append("?:?,");
//        }
//
//        try {
//            strBuff.append( getCurrentSocket().getInetAddress().getHostAddress()).append(":").append(getCurrentSocket().getPort()).append(",");
//        } catch( Throwable e ) {
//            status = false;
//            strBuff.append("?:?,");
//        }
//        strBuff.append(this.sendCount).append(",");
//        strBuff.append(this.recvCount).append(",");
//        strBuff.append( status ).append(",");
//        strBuff.append( CommonLib.getCurrentTime( this.firstActivity )).append(",");
//        strBuff.append(CommonLib.getCurrentTime( this.lastActivity ));
//
//        return strBuff.toString();
//    }
//    
//    public void setLastActivity() {
//    }
//
//    public long getFirstActivity() {
//        return firstActivity;
//    }
//
//    public long getLastActivity() {
//        return lastActivity;
//    }
//}
