//package com.eactive.eai.adapter.socket.service;
//
//import java.io.IOException;
//import java.net.Socket;
//import java.nio.ByteBuffer;
//import java.nio.channels.ClosedSelectorException;
//import java.nio.channels.SelectionKey;
//import java.nio.channels.Selector;
//import java.nio.channels.SocketChannel;
//import java.util.Iterator;
//
//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;
//
//public class AdminServer extends Thread implements SocketService {
//
//	private	ConfigurationContext context;
//	private SocketChannel 		 socketChannel;
//	private SocketServer 		 proxy;
//	private Selector             selector;
//    private SelectionKey         key;
//
//    private boolean				 active;
//
//    // 상태정보                      
//	private int					 sendCount;
//	private int					 recvCount;
//    private long				 firstActivity;
//    private long				 lastActivity;
//
//    // IO BUFFER                 
//    private ByteBuffer           incomingMessage;
//    private ByteBuffer           outgoingMessage;
//    private ByteBuffer           lenBuffer;
//
//    // Logger                    
//    private Logger               logger;
//    private String               remoteIPAddress;
//
//    public AdminServer(ConfigurationContext context, SocketChannel socketChannel, SocketServer proxy) {
//        String name = this.getName();
//        this.setName( context.getAdapterName() + "-CONNECTION-ADMIN" + name.substring( name.lastIndexOf("-")) );
//
//    	this.context 		= context;
//    	this.socketChannel 	= socketChannel;
//    	this.proxy 			= proxy;
//
//    	sendCount			= 0;
//        recvCount			= 0;
//        firstActivity		= System.currentTimeMillis();
//        lastActivity		= System.currentTimeMillis();
//
//		incomingMessage     = null;
//        outgoingMessage     = null;
//
//		lenBuffer = ByteBuffer.allocate( this.context.getLlFieldLength() );
//		lenBuffer.clear();
//
//        logger              = SocketLogManager.getInstance().getLogger( context.getAdapterGroupName());
//		remoteIPAddress     = this.socketChannel.socket().getInetAddress().getHostAddress();
//        active              = true;
//    }
//
//    private boolean isSyncMode() {
//    	return this.context.isSyncMode();
//    }
//
//    public String getRemoteIPAddress() {
//        return this.remoteIPAddress;
//    }
//
//    private long getTimeout() {
//    	return	( this.context.getTimeout() * 1000L );
//    }
//
//    private boolean isSocketReuse() {
//    	return this.context.getSocketReuse().equals( ConfigurationContext.TRUE_FLAG );
//	}
//
//    private int getTraceLevel() {
//    	return context.getTraceLevel();
//    }
//	/**
//	 * @return Returns the context.
//	 */
//	public ConfigurationContext getContext() {
//		return context;
//	}
//
//    public void run() {
//    	SocketAdapterManager.getInstance().addConnection( this );
//
//        String  socketInfo = this.getSocketInfo(this.socketChannel);
//
//        if ( getTraceLevel() >= DiagLogger.INFO ) {
//            logger.info( CommonLib.getMessage("BICEAIMSA034", new String[]{ context.getAdapterName(), socketInfo , Thread.currentThread().getName() }) );
//        }
//
//        try {
//            openSelector();
//        } catch(IOException e) {
//            String errMsg = CommonLib.getMessage("BECEAIMSA009", new String[]{context.getAdapterName(), "openSelector", e.getMessage(), "", "" } );
//            logger.error( errMsg, e );
//        	active = false;
//        }
//
//        Iterator<SelectionKey> iterator;
//        long    start = System.currentTimeMillis();
//        while( active ) {
//            try {
//                int selected = selector.select( getTimeout() );
//                if( selected == 0 ) {
//                    long waitTime = System.currentTimeMillis() - start;
//                	if ( lenBuffer.position() > 0 && waitTime >= getTimeout() ) {
//                        String errMsg = CommonLib.getMessage("BECEAIMSA024", new String[]{context.getAdapterName(), socketInfo, Long.toString(getTimeout()), "수신", getReadingMessage()  });
//                        logger.error( errMsg );
//                    	active = false;
//                	}
//                    continue;
//                }
//            } catch(IOException e) {
//                if ( lenBuffer.position() > 0 ) {
//                    String errMsg = CommonLib.getMessage("BECEAIMSA009", new String[]{context.getAdapterName(), "select", e.getMessage(), "수신메시지", getReadingMessage() } );
//                    logger.error( errMsg , e);
//                }
//                active = false;
//            } catch(ClosedSelectorException e ) {
//            	continue;
//            } catch(Exception e) {}
//
//            if ( selector == null || !selector.isOpen() ) continue;
//
//            iterator = selector.selectedKeys().iterator();
//
//            while( iterator.hasNext() ) {
//                key    = (SelectionKey)iterator.next();
//                iterator.remove();
//                socketChannel   = (SocketChannel)key.channel();
//                if(key.isReadable()) {   	// is Readable ? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                    try {
//
//                        start   = System.currentTimeMillis();
//                        if( processReadMessage() ) {    	    // Read Done
//                            byte[]	message  = incomingMessage.array();
//
//
//                            if ( getTraceLevel() >= DiagLogger.DEBUG ) {
//                                logger.debug( CommonLib.getMessage("BDCEAIMSA001", new String[]{context.getAdapterName(), "RECV", CommonLib.getTimestamp(), socketInfo, CommonLib.getDumpMessage(incomingMessage.array())}));
//                            }
//
//                            this.checkActivity();
//                            lastActivity	= System.currentTimeMillis();
//                			recvCount++;
//
//                			byte[] rtnValue = SocketAdapterManager.getInstance().executeCommand( new String(message) ).getBytes();
//
//                            incomingMessage.clear();
//                            lenBuffer.clear();
//
//                            start   = System.currentTimeMillis();
//
//                            if ( isSyncMode() ) {
//                            	// 동기, SYNC로 간주합니다.
//                            	makeFormat( rtnValue );
//                                socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
//                                //selector.wakeup();
//                            } else {
//                            	// 비동기, ASYNC로 간주합니다.
//                            	socketChannel.register(selector, SelectionKey.OP_READ);
//                                //selector.wakeup();
//                            }
//                        }
//                    } catch(Exception e) {
//                        if ( lenBuffer.position() > 0 ) {
//                            String errMsg = CommonLib.getMessage("BECEAIMSA009", new String[]{context.getAdapterName(), "processReadMessage", e.getMessage(), "수신메시지", getReadingMessage() } );
//                            logger.error( errMsg , e);
//                        }
//                        active = false;
//                    } finally {
//                        if(!active) continue;
//                    }
//                } // end of readable...
//
//                if( key.isWritable() ) { // is Writable ? - - - - - - - - - - - - - - - - - - - //
//                    try {
//                        if( processWriteMessage() ) {
//
//                        	sendCount++;
//
//                            if ( getTraceLevel() >= DiagLogger.DEBUG ) {
//                                logger.debug( CommonLib.getMessage("BDCEAIMSA001", new String[]{context.getAdapterName(), "SEND", CommonLib.getTimestamp(), socketInfo, getWritingMessage()}));
//                            }
//
//                            outgoingMessage.clear();
//                            lenBuffer.clear();
//
//                            socketChannel.register(selector, SelectionKey.OP_READ); // write end. so read only.
//                        }
//                    } catch(IOException e) {
//                        String errMsg = CommonLib.getMessage("BECEAIMSA009", new String[]{context.getAdapterName(), "processWriteMessage", e.getMessage(), "송신메시지", getWritingMessage() } );
//                        logger.error( errMsg , e);
//                        active = false;
//                    }
//                } // end of writables...
//            } // End of while(iterator.hasNext())
//
//            if ( !isSocketReuse() ) {
//            	active	= false;
//            }
//
//        } // enf of while - active
//
//        try {
//            closeSelector();
//        } catch(IOException e) {}
//
//
//        SocketAdapterManager.getInstance().removeConnection( this );
//
//        if ( getTraceLevel() >= DiagLogger.INFO ) {
//            logger.info( CommonLib.getMessage("BICEAIMSA035", new String[]{ context.getAdapterName(), socketInfo, Thread.currentThread().getName() }) );
//        }
//
//        proxy.quiesceShutdown(this);
//        interrupt();
//
//    }
//
//    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  getWritingMessage() {
//        String rMsg = "";
//        if ( outgoingMessage != null && outgoingMessage.position() > 0 ) {
//            byte[] debugMsg = new byte[ outgoingMessage.capacity() - lenBuffer.capacity() ];
//            System.arraycopy( outgoingMessage.array(), lenBuffer.capacity(), debugMsg, 0, debugMsg.length );
//            rMsg = CommonLib.getDumpMessage( debugMsg );
//        }
//        return rMsg;
//    }
//
//    private String  getSocketInfo(SocketChannel channel) {
//        StringBuffer connInfo = new StringBuffer();
//
//        connInfo.append("Local Address=");
//        connInfo.append( channel.socket().getLocalAddress().getHostAddress()).append(":").append(channel.socket().getLocalPort()).append(", ");
//        connInfo.append("Remote Address=");
//        connInfo.append( channel.socket().getInetAddress().getHostAddress()).append(":").append(channel.socket().getPort());
//
//        return connInfo.toString();
//    }
//
//    public boolean idle(long timeout) {
//        long idleTime   = System.currentTimeMillis() - this.lastActivity;
//        return ( idleTime > timeout );
//    }
//
//    public boolean isActive() {
//        return active;
//    }
//
//    public void shutdown() {
//        active    = false;
//        try {
//            closeSelector();
//        } catch( Exception e ) {}
//
//        interrupt();
//    }
//
//    public Socket getCurrentSocket() {
//    	return socketChannel.socket();
//    }
//
//    public boolean connect() {
//    	return true;
//    }
//
//    public void disconnect() {
//    	shutdown();
//        proxy.quiesceShutdown(this);
//    }
//
//    private void openSelector() throws IOException {
//
//    	if ( selector == null || !selector.isOpen() ) {
//    		selector = Selector.open();
//    	}
//        socketChannel.socket().setTcpNoDelay(true);
//        socketChannel.configureBlocking(false);
//        socketChannel.register(selector, SelectionKey.OP_READ);
//
//    }
//
//    private void closeSelector() throws IOException {
//        if(selector != null) {
//            selector.wakeup();
//
//            for(Iterator<SelectionKey> iterator = selector.keys().iterator(); iterator.hasNext();) {
//                try {
//                    key    = iterator.next();
//                    iterator.remove();
//                    socketChannel   = (SocketChannel)key.channel();
//                    key.cancel();
//                    if(socketChannel != null) {
//                        Socket socket = socketChannel.socket();
//                        if(socket != null) {
//                            socket.setSoLinger(false, 0);
//                            try { socket.close(); } catch(Exception e) {}
//                        }
//                        socketChannel.close();
//                    }
//                } catch(IOException ioexception) { }
//            }
//            selector.close();
//        }
//        selector = null;
//    }
//
//    public void setControl(Object control) {
//    }
//
//    public void notifyMessage() {
//    }
//
//
//    private boolean processReadMessage() throws Exception {
//
//        int     i = 0;
//        boolean flag = false;
//
//        while ( lenBuffer.position() < lenBuffer.capacity() ) {
//            i = socketChannel.read( lenBuffer );
//            if ( i <= 0 ) break;
//            flag = true;
//        }
//
//         if(i == -1) {
//            if ( lenBuffer.position() > 0 ) {
//                throw new SocketAdapterException( CommonLib.getMessage("BECEAIMSA010", new String[]{context.getAdapterName(), getSocketInfo(this.socketChannel)}) );
//            } else {
//                String errMsg = CommonLib.getMessage("BICEAIMSA036", new String[]{context.getAdapterName(), getSocketInfo(this.socketChannel)});
//                if(logger.isInfoEnabled()){
//                    logger.info( errMsg );
//                }
//                throw new SocketAdapterException( errMsg  );
//            }
//        }
//        if ( lenBuffer.position() != lenBuffer.capacity() )     return false;
//
//        int length = 0;
//
//        try {
//            if ( flag ) {
//                length = checkLengthField( lenBuffer );
//                incomingMessage = ByteBuffer.allocate( length );
//                incomingMessage.clear();
//            }
//        } catch(Exception le) {
//            throw le;
//        }
//
//        i = 0;
//        while ( incomingMessage.position() < incomingMessage.capacity()) {
//            i = socketChannel.read(incomingMessage);
//            if ( i <= 0 ) break;
//        }
//
//        if(i == -1) {
//            throw new SocketAdapterException( CommonLib.getMessage("BECEAIMSA010", new String[]{context.getAdapterName(), getSocketInfo(this.socketChannel)}) );
//        } else {
//              if ( incomingMessage.position() == incomingMessage.capacity() ) {
//                return true;
//            } else {
//                return false;
//            }
//        }
//    }
//
//    private boolean processWriteMessage() throws IOException {
//
//        outgoingMessage.flip();
//
//        while ( outgoingMessage.hasRemaining() && active ) {
//        	socketChannel.write(outgoingMessage);
//        }
//
//        return true;
//    }
//
//    // Writing전에 확인...
//    public boolean isConnected() throws IOException {
//    	return true;
//    }
//
//    public int getCurrentState() {
//        return CommonLib.PROCESSING_PROTOCOL;
//    }
//
//    private void resetCount() {
//        this.recvCount = 0;
//        this.sendCount = 0;
//    }
//
//    public void checkActivity() {
//        long currentTime = System.currentTimeMillis();
//        if ( !CommonLib.getDate( this.lastActivity ).equals( CommonLib.getDate( currentTime )) ) {
//            this.resetCount();
//        }
//    }
//
//    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("BECEAIMSA027", new String[]{context.getAdapterName(), getSocketInfo(this.socketChannel), CommonLib.byte2Hex( buffer.array() ) }) );
//            }
//    	} else {
//    		String lenStr = new String( buffer.array() );
//    		try {
//    			length = Integer.parseInt( lenStr );
//    		} catch ( NumberFormatException e ) {
//    			throw new SocketAdapterException( CommonLib.getMessage("BECEAIMSA027", new String[]{context.getAdapterName(), getSocketInfo(this.socketChannel), CommonLib.byte2Hex( buffer.array() ) }) );
//    		}
//    	}
//    	return length;
//    }
//
//    private byte[] makeLengthField(int length) {
//    	byte[] lenField = null;
//
//    	if ( lenBuffer.capacity() == 2 ) {
//            ByteBuffer tmpBuffer = ByteBuffer.allocate( lenBuffer.capacity() );
//            tmpBuffer.clear();
//    		tmpBuffer.putShort( (short) (length & 0xFFFF) );
//            lenField    = tmpBuffer.array();
//    	} else {
//    		String lenStr = CommonLib.getFormatString( length, lenBuffer.capacity() );
//    		lenField	= lenStr.getBytes();
//    	}
//
//    	return lenField;
//    }
//
//    private void makeFormat(byte[] data) throws SocketAdapterException {
//
//    	int i = data.length + lenBuffer.capacity();
//
//        if(outgoingMessage == null) {
//            outgoingMessage = ByteBuffer.allocate( data.length + lenBuffer.capacity() );
//        } else {
//            if( i != outgoingMessage.capacity() )
//                outgoingMessage = ByteBuffer.allocate( i );
//        }
//
//        outgoingMessage.clear();
//        outgoingMessage.put( makeLengthField( data.length ) );
//        outgoingMessage.put( data );
//    }
//
//	/**
//	 * @return Returns the socketchannel.
//	 */
//	public SocketChannel getSocketchannel() {
//		return socketChannel;
//	}
//	/**
//	 * @param socketchannel The socketchannel to set.
//	 */
//	public void setSocketchannel(SocketChannel socketchannel) {
//		this.socketChannel = socketchannel;
//	}
//
//    // 1. Connection 리스트정보 - AdapterGroupName,AdapterName,업무코드,INBOUND, CLIENT, 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( Exception e ) {
//            status = false;
//            strBuff.append("?:?,");
//        }
//
//        try {
//            strBuff.append( getCurrentSocket().getInetAddress().getHostAddress()).append(":").append(getCurrentSocket().getPort()).append(",");
//        } catch( Exception 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;
//    }
//}
