package com.eactive.eai.adapter.socket2.protocol.http;

import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace;
import com.eactive.eai.adapter.socket2.config.SocketLoggerManager;
import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter;
import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler;
import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest;
import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse;
import com.eactive.eai.common.util.Logger;
import org.apache.mina.common.IdleStatus;
import org.apache.mina.common.IoSession;
import org.apache.mina.util.SessionLog;

import java.util.Hashtable;

public class HttpHandler extends ProtocolHandler {
	static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_");
	
	static String[] servletList = {
			"adapters",    		 "com.eactive.eai.adapter.socket2.protocol.http.servlet.AdaptersServlet",
			"adaptersJson",		 "com.eactive.eai.adapter.socket2.protocol.http.servlet.AdaptersJsonServlet",
			"adapter",     	     "com.eactive.eai.adapter.socket2.protocol.http.servlet.AdapterServlet",
			"adapterJson", 	     "com.eactive.eai.adapter.socket2.protocol.http.servlet.AdapterJsonServlet",
			"adapterInternal",   "com.eactive.eai.adapter.socket2.protocol.http.servlet.AdapterInternalServlet",
			"check",     	     "com.eactive.eai.adapter.socket2.protocol.http.servlet.CheckServlet",
			"thread",      		 "com.eactive.eai.adapter.socket2.protocol.http.servlet.ThreadServlet",
			"memory",      		 "com.eactive.eai.adapter.socket2.protocol.http.servlet.MemoryServlet",
			"error",       	     "com.eactive.eai.adapter.socket2.protocol.http.servlet.ErrorServlet",
			"file",        	     "com.eactive.eai.adapter.socket2.protocol.http.servlet.FileServlet",
			"prop",        	     "com.eactive.eai.adapter.socket2.protocol.http.servlet.PropServlet",
			"groovy",    		 "com.eactive.eai.adapter.socket2.protocol.http.servlet.GroovyServlet",
			"transformer", 		 "com.eactive.eai.transformer.servlet.TransformerServlet",
			"message",     		 "com.eactive.eai.transformer.servlet.LayoutServlet",
			"layout",      	     "com.eactive.eai.transformer.servlet.LayoutServlet",
			"transform",   		 "com.eactive.eai.transformer.servlet.TransformServlet",
			"function",    		 "com.eactive.eai.transformer.servlet.FunctionServlet",
			"service",    		 "com.eactive.eai.transformer.servlet.ServiceServlet",
			"bizkey",    		 "com.eactive.eai.transformer.servlet.BizKeyServlet",
			"control",    		 "com.eactive.eai.adapter.socket2.protocol.http.servlet.ControlServlet",
			"http",    		     "com.eactive.eai.adapter.http.servlet.HttpAdapterLogServlet",
			"zombies",    		 "com.eactive.eai.adapter.socket2.protocol.http.servlet.ZombieAdaptersServlet",			                                  
			"token",    		 "com.openbanking.eai.common.token.servlet.AccessTokenServlet",
			"rolling",           "com.eactive.kakao.rolling.servlet.RollingServlet"
		};
	
	Hashtable map = new Hashtable();
	
	
	public HttpHandler(ISocketAdapter adapter) {
		super(adapter);

		for (int i=0; i<servletList.length/2; i++) {
			try {
		        HttpServlet servlet = (HttpServlet) Class.forName(servletList[i*2+1]).newInstance();
		        map.put(servletList[i*2], servlet);	        
	        } catch(Exception e) {
	        	logger.warn("cannot load servlet : ", e);	        	 
	        }
		}
	}

    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
    	HttpRequest request = (HttpRequest) message;    	
        HttpResponse response = new HttpResponse();
        
        /**
         * audit
         */
        adapter.incMessageRecv();
        adapter.addRecentRecv(session, request.getURI());
		if (context.getTraceLevel() >= context.TRACE_LEVEL_INFO) {
			logger.info(context.getAdapterName() + " | audit - " + session + " - " + request.getURI());
		}

		/**
		 * sevlet
		 */
        try {
	    	String servletName = "error";
	    	if (!"".equals(request.getContext())) {
	    		servletName = request.getContext();
	    	}
	    	if (servletName.indexOf('/') != -1) {
	    		servletName = servletName.substring(0, servletName.indexOf('/'));
	    	}
	    	
	        HttpServlet servlet = (HttpServlet) map.get(servletName);
	        if (servlet == null) {
	        	if (!servletName.endsWith(".ico"))
	        		logger.warn("404 - > " + servletName);
	        	response.setResponseCode(404);
	        } else {
	        	servlet.service(request, response);
	        }
        } catch(Exception e) {
        	response.appendBody("<pre>");
        	response.appendBody(ExceptionStackTrace.dump(e));
        	response.appendBody("</pre>");
        }
        
        session.write(response).join();
    }

    @Override
    public void sessionIdle(IoSession session, IdleStatus status) {
        SessionLog.info(session, context.getAdapterName() + " | session idle -> disconnect");
		sessionPool.remove(session);
        session.close();
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) {
		sessionPool.remove(session);
        session.close();
    }
}
