package com.eactive.eai.adapter.socket2.filter.datacontrol;

import com.eactive.eai.adapter.socket2.config.SocketAdapterContext;
import com.eactive.eai.adapter.socket2.config.SocketLoggerManager;
import com.eactive.eai.adapter.socket2.protocol.ByteMessage;
import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.StringUtil;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoFilterAdapter;
import org.apache.mina.common.IoSession;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class DataControlFilter extends IoFilterAdapter {
	final protected Logger logger;
    final protected Logger errLogger;

    protected SocketAdapterContext context;
	protected ISocketAdapter adapter;
	
	public DataControlFilter(ISocketAdapter adapter) {
		this.adapter = adapter;
		this.context = adapter.getContext();

	    logger    = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName());
	    errLogger = SocketLoggerManager.getInstance().getErrLogger();
	}		
	
	
	@Override
	public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
		ByteMessage m = (ByteMessage) message;
		ByteMessage mm = null ;
		
		/**
		 * datacontrol.rule
		 */
		if (!"".equals(context.getDataControlRule())) {
			Matcher matcher = Pattern.compile("\\[([ ]*[0-9]+)[ ]*,([ ]*[0-9]+)[ ]*\\][ ]*=[ ]*(.+)").matcher(context.getDataControlRule().trim());
			if (matcher.find()) {
			    int offset = Integer.parseInt(matcher.group(1).trim());
			    int length = Integer.parseInt(matcher.group(2).trim());
			    String re = matcher.group(3).trim();

			    
				mm = (new ByteMessage())
                .append(m.getBytes(0, offset))
                .append(m.getBytes(offset + length));			    	


			} else {
				throw new Exception(context.getAdapterName() + " | datacontrol.rule format is invalid : " + context.getDataControlRule());
			}
		}

		/**
		 * next filter
		 */
		nextFilter.messageReceived(session, mm);
	}
	@Override
	public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
		ByteMessage m = null;
		
		if (writeRequest.getMessage() instanceof byte[]) {
			m = new ByteMessage((byte[]) writeRequest.getMessage());
		} else if (writeRequest.getMessage() instanceof ByteMessage) {
			m = (ByteMessage) writeRequest.getMessage();
		} else if (writeRequest.getMessage() instanceof String) {
			m = new ByteMessage((String) writeRequest.getMessage());
		} else if (writeRequest.getMessage() instanceof ByteBuffer) {
			m = new ByteMessage((ByteBuffer) writeRequest.getMessage());
		} else {
			throw new Exception("Unknown data format");
		}		
		
		ByteMessage mm = null ;
		
		/**
		 * datacontrol.rule
		 */
		if (!"".equals(context.getDataControlRule())) {
			Matcher matcher = Pattern.compile("\\[([ ]*[0-9]+)[ ]*,([ ]*[0-9]+)[ ]*\\][ ]*=[ ]*(.+)").matcher(context.getDataControlRule().trim());
			if (matcher.find()) {
			    int offset = Integer.parseInt(matcher.group(1).trim());
			    int length = Integer.parseInt(matcher.group(2).trim());
			    String re = matcher.group(3).trim();
			    if (re != null && length != re.length()){
			    	re = StringUtil.stringFormat(re, false, ' ', length);
			    }
			    if (re != null){
			    	byte[] org = m.getBytes(offset,length);

			    	if (re.equals(new String(org))){
			    		//TODO JUN 같은 값이면 추가 안하는 걸로 했는데 바꿔야 할듯
			    		mm = m;
			    	}else{
						mm = (new ByteMessage())
		                .append(m.getBytes(0, offset))
		                .append(re.getBytes())
		                .append(m.getBytes(offset));			    	
			    	}
			    }
			} else {
				throw new Exception(context.getAdapterName() + " | datacontrol.rule format is invalid : " + context.getDataControlRule());
			}
		}		
		
		/**
		 * next filter
		 */
		nextFilter.filterWrite(session, new WriteRequest(mm, writeRequest.getFuture(), writeRequest.getDestination()));
	}	
}
