package com.eactive.eai.adapter.socket2.protocol.xecure.sign;

import com.eactive.eai.adapter.socket2.common.SMSLogger;
import com.eactive.eai.adapter.socket2.protocol.ByteMessage;
import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter;
import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants;
import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage;
import com.eactive.eai.adapter.socket2.protocol.xecure.XecureFilter;
import com.sf.xc3.XCException;
import com.sf.xc3.XC_v3;
import org.apache.mina.common.IoSession;

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

public class XecureSignFilter extends XecureFilter {
	protected byte[] cert;
	protected byte[] key;
	
	public XecureSignFilter(ISocketAdapter adapter) {
		super(adapter);
	}
	
	@Override
	public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
		ByteMessage m = null;
		
		if (message instanceof byte[]) {
			m = new ByteMessage((byte[]) message);
		} else if (message instanceof ByteMessage) {
			m = (ByteMessage) message;
		} else if (message instanceof String) {
			m = new ByteMessage((String) message);
		} else {
			throw new Exception("Unknown data format");
		}  

		try {
			FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY);
			XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE);
	
			switch (filterState.state) {		
			case STATE_MESSAGE:			
				m = new ByteMessage(xc.verify(m.getBytes()));
				if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) {
					logger.debug(context.getAdapterName() + " | XecureSignFilter | messageReceived() - after verify - " + m.hexDump());
				}
				break;
		
			default:
				break;
			}
		} catch(XCException e) {
			String xcMessage = "";
			Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage());
			
			if (matcher.find()) {
			    String key = matcher.group(1);
			    xcMessage = XecureErrorMessage.getErrorMessage(key);
			}
			
			adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e);
			logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e);
			errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e);
//			SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012");
			SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012");
			throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage);
		}

		nextFilter.messageReceived(session, m);
	}

	@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 {
			throw new Exception("Unknown data format");
		}  

		try {
			FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY);
			XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE);
	
			switch (filterState.state) {			
			case STATE_MESSAGE:
				String s = xc.sign(m.getBytes(), cert, key, password);
				m = new ByteMessage(s);
				if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) {
					logger.debug(context.getAdapterName() + " | XecureSignFilter | filterWrite() - after sign - " + m.hexDump());
				}
				break;
				
			default:
				break;
			}
		} catch(XCException e) {
			String xcMessage = "";
			Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage());
			if (matcher.find()) {
			    String key = matcher.group(1);
			    xcMessage = XecureErrorMessage.getErrorMessage(key);
			}
			adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e);
			logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e);
			errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e);
//			SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012");
			SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012");
			throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage);
		}

		nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination()));
    }
}
