//package com.eactive.eai.adapter.socket.service;
//
//import java.io.IOException;
//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 org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//public class WriterClient extends Thread implements SocketService {
//
//	private ConfigurationContext context;
//	private boolean				 active;
//	private NBChannel	 		 channel;
//
//	private Exception			 lastError;
//
//	private ByteBuffer           outgoingMessage;
//    private ByteBuffer			 lenBuffer;
//
//    private Logger               logger;
//    private static Logger        errLogger = SocketLogManager.getInstance().getErrLogger();
//
//	private OutboundControl		 control;
//    private ReaderClient         proxy;
//    private boolean              shutdownFlag;
//
//    public WriterClient(ConfigurationContext context, NBChannel channel, ReaderClient proxy ) {
//        String name = this.getName();
//    	this.setName( context.getAdapterName() + "-CONNECTION-WRITER" + name.substring( name.lastIndexOf("-")) );
//
//    	this.context 		= context;
//        active				= true;
//
//        outgoingMessage     = null;
//        lenBuffer			= ByteBuffer.allocate( this.context.getLlFieldLength() );
//        lenBuffer.clear();
//
//        this.control        = null;
//        this.proxy          = proxy;
//        this.channel        = channel;
//        this.shutdownFlag   = false;
//
//        logger              = SocketLogManager.getInstance().getLogger( this.context.getAdapterGroupName());
//    }
//
//    public boolean isActive() {
//        return active;
//    }
//
//    private int getTraceLevel() {
//    	return context.getTraceLevel();
//    }
//	/**
//	 * @return Returns the context.
//	 */
//	public ConfigurationContext getContext() {
//		return context;
//	}
//
////    private boolean isSyncMode() {
////    	return context.isSyncMode();
////    }
//
//    private long getTimeout() {
//    	return ( this.context.getTimeout() * 1000L );
//    }
//
//    private boolean isSocketReuse() {
//    	return this.context.getSocketReuse().equals( ConfigurationContext.TRUE_FLAG );
//	}
//
//    public void run() {
//
//        OutboundChannelManager.getInstance().addConnection(context.getAdapterGroupName(), this);
//        String  socketInfo = "";
//
//        while ( active ) {
//            try {
//            	openChannel();
//                if ( !socketInfo.equals( getSocketInfo(this.getCurrentSocket()) ) ) {
//                    socketInfo = getSocketInfo( this.getCurrentSocket() );
//                    if ( getTraceLevel() >= DiagLogger.INFO ) {
//                        logger.info( CommonLib.getMessage("BICEAIASO001", new String[]{ context.getAdapterName(), socketInfo , Thread.currentThread().getName() }) );
//                    }
//                }
//
//            	onMessage();
//
//                if ( control == null ) continue;
//
//            	doRequest();
//                if ( !isSocketReuse() ) {
//                    active = false;
//                }
//            } catch (Exception e) {
//                String errMsg = CommonLib.getMessage("BECEAIASO001", new String[]{context.getAdapterName(), "openChannel", e.getMessage(), "", "" } );
//                logger.error( errMsg, e );
//                active = false;
//            }
//        }
//
//        OutboundChannelManager.getInstance().removeConnection(context.getAdapterGroupName(), this);
//
//        if ( getTraceLevel() >= DiagLogger.INFO ) {
//            logger.info( CommonLib.getMessage("BICEAIASO002", new String[]{ context.getAdapterName(), socketInfo, Thread.currentThread().getName() }) );
//        }
//
//        if ( !shutdownFlag ) {
//            proxy.shutdownWriter();
//        }
//
//        interrupt();
//    }
//
////    private String  getWritingMessage() {
////        String rMsg = "";
////        if ( outgoingMessage != null ) {
////            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(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();
//    }
//
//    private synchronized void onMessage() {
//    	try {
//            this.wait( );
//            this.lastError = null;
//    	} catch ( InterruptedException ie ) {}
//    }
//
//    public void wakeup() {
//    	this.control.setLastError( this.lastError );
//        this.control.wakeup();
//        this.control = null;
//        // 사용한 Connection 반납한다.
//        if ( active ) {
//            OutboundChannelManager.getInstance().addConnection(context.getAdapterGroupName(), this );
//        }
//    }
//
//    public synchronized void notifyMessage() {
//        this.notify();
//    }
//
//    public synchronized void setControl(Object control) {
//        this.control = (OutboundControl) control;
//    }
//
//    // RESPONSE MODE의 경우
//    private void doRequest() {
//
//        this.checkActivity();
//        proxy.setLastActivity( System.currentTimeMillis() );
//
//        try {
//
//        	processWriteMessage( this.control.getRequest() );
//
//        	proxy.addSendCount();
//
//        	if ( getTraceLevel() >= DiagLogger.DEBUG) {
//                logger.debug( CommonLib.getMessage("BDCEAIASO001", new String[]{context.getAdapterName(), "SEND", CommonLib.getTimestamp(), this.getSocketInfo( getCurrentSocket() ), CommonLib.getDumpMessage(this.control.getRequest())}));
//        	}
//
//            wakeup();
//
//        } catch( Exception  e) {
//            String errMsg = "";
//            errMsg = CommonLib.getMessage("BECEAIASO001", new String[]{context.getAdapterName(), "processWriteMessage", e.getMessage(), "송신메시지", CommonLib.getDumpMessage( this.control.getRequest() ) } );
//            logger.error( errMsg , e);
//            if ( logger != errLogger ) {
//                errLogger.error( errMsg, e );
//            }
//
//            lastError   = new SocketAdapterException( errMsg );
//        	active      = false;
//        	wakeup();
//        }
//    } // end of doRequest()
//
//    /**
//     * Socket Recovery Manager에 의해 Connection Recovery가 되도록 기다린다.
//     */
//    public boolean idle(long timeout) {
//        return false;
//    }
//
//    public int getCurrentState() {
//        return proxy.getCurrentState();
//    }
//
////    private void resetCount() {
////    }
//
//    public boolean isConnected() {
//        return proxy.isConnected();
//    }
//
//    public void checkActivity() {
//        proxy.checkActivity();
//    }
//
//    private void processWriteMessage( byte[] data ) throws IOException {
//
//        outgoingMessage  	= ByteBuffer.allocate( data.length + lenBuffer.capacity() );
//        outgoingMessage.clear();
//    	outgoingMessage.put( makeLengthField( data.length ) );
//    	outgoingMessage.put( data );
//    	outgoingMessage.flip();
//
//        long writeStart     = System.currentTimeMillis();
//
//        int  expectedWrite  = outgoingMessage.capacity();
//        int  writtenByte    = channel.write( outgoingMessage );
//
//        if ( expectedWrite != writtenByte ) {
//            ByteBuffer buf = null;
//            while ( writtenByte < expectedWrite ) {
//                buf = ByteBuffer.allocate( expectedWrite - writtenByte );
//                buf.clear();
//                buf.put( outgoingMessage.array(), writtenByte, buf.capacity() );
//                writtenByte += channel.write( buf );
//                if ( expectedWrite == writtenByte ) return;
//                long  waitTime = System.currentTimeMillis() - writeStart;
//                if ( waitTime >= getTimeout() ) {
//                    throw new IOException("메시지 송신 타임아웃");
//                }
//            }
//        }
//
//    }
//
//    private byte[] makeLengthField(int length) {
//    	byte[] lenField = new byte[ lenBuffer.capacity() ];
//
//    	if ( lenField.length == 2 ) {
//    		lenBuffer.clear();
//    		lenBuffer.putShort( (short) (length & 0xFFFF) );
//    		lenField = lenBuffer.array();
//    	} else if ( lenField.length == 4 ) {
//    		lenBuffer.clear();
//    		lenBuffer.putInt( length );
//    		lenField = lenBuffer.array();
//    	} else {
//    		String lenStr = CommonLib.getFormatString( length, lenField.length );
//    		lenField	= lenStr.getBytes();
//    	}
//
//    	return lenField;
//    }
//
//    public synchronized void shutdown() {
//
//        active       = false;
//        // 2005.10.17
//        shutdownFlag = true;
//
//        try {
//            notify();
//        } catch( Exception e ) {}
//
//        //* 2005.10.17
//        try {
//            this.channel.wakeup();
//        } catch( Throwable e ) {}
//        // interrupt();
//    }
//
//    public Socket getCurrentSocket() {
//    	return channel.getSocket();
//    }
//
//    public boolean connect() {
//    	return false;
//    }
//
//    public void disconnect() {
//    }
//
//    private synchronized void openChannel() throws IOException {
//
//        try {
//            if ( channel !=null && !channel.isConnected() ) {
//                throw new Exception("");
//            }
//        } catch(Exception e) {
//            throw new IOException("Connection Closed in openChannel");
//        }
//    }
//
//    public String getRemoteIPAddress() {
//        return null;
//    }
//
////    private synchronized void closeChannel() throws IOException {
////    } // end of closeChannel...
//    
//    public void setLastActivity() {
//    }
//
//    public long getFirstActivity() {
//        return 0;
//    }
//
//    public long getLastActivity() {
//        return 0;
//    }
//}
