package com.eactive.eai.adapter.socket2.protocol.fixedheader.ack;

import com.eactive.eai.adapter.socket2.protocol.ByteMessage;
import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter;
import org.apache.mina.common.IoSession;


public class AckClientFilter extends AckFilter {
	public AckClientFilter(ISocketAdapter adapter) {
		super(adapter);
	}	
	
	@Override
    public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception {
		FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY);
		
//		WriteFuture future = session.write(new ByteMessage(context.getResponseType()));
		session.write(new ByteMessage(context.getResponseType()));
		//future.join(context.getTimeout() * 1000L);

		if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) {
			logger.debug(context.getAdapterName() + " | AckClientFilter | <SEND> " + context.getResponseType());
		}

		filterState.state = State.STATE_HANDSHAKE_CLIENT_WAIT_HELLO_ACK;
		setSessionState(session, filterState.state.toString());
		session.setAttribute(FILTER_STATE_KEY, filterState);
	}
	
	
	@Override
	public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
		FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY);

		ByteMessage m = (ByteMessage) message;

		switch (filterState.state) {		
		case STATE_HANDSHAKE_CLIENT_WAIT_HELLO_ACK:
			if (!"ACK".equals(m.getString())) {
				throw new Exception("expected 'ACK' when handshaking, but received : " + m.getString());
			}
			if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) {
				logger.debug(context.getAdapterName() + " | AckClientFilter | <RECV> HELLO ACK : " + m.hexDump());
			}			
			filterState.state = State.STATE_MESSAGE;
			setSessionState(session, filterState.state.toString());
			
			nextFilter.sessionCreated(session);
			nextFilter.sessionOpened(session);
			break;
			
		case STATE_WAIT_ACK:
			if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) {
				logger.debug(context.getAdapterName() + " | AckClientFilter | <RECV> ACK : " + m);
			}
			if (!"ACK".equals(m.getString())) {
				throw new Exception("expected 'ACK', but encounterred : " + m.getString());
			}
			filterState.state = State.STATE_MESSAGE;
			setSessionState(session, filterState.state.toString());
			break;

		case STATE_SEND_ACK:
		case STATE_MESSAGE:
			///*
			if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) {
				logger.debug(context.getAdapterName() + " | AckClientFilter | <RECV> : " + m.hexDump());
			}
			//*/
			sendAckMessage(session);
			filterState.state = State.STATE_MESSAGE;
			setSessionState(session, filterState.state.toString());
			nextFilter.messageReceived(session, message);
			break;

			
		default:
			throw new Exception("<RECV> invalid message during handshake .. : " + m);
		}
	}	
}
