package com.eactive.eai.adapter.http.async;

import com.eactive.eai.adapter.RequestDispatcher;
import com.eactive.eai.common.util.Logger;

import javax.servlet.AsyncContext;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.util.Properties;

public class AsyncRequestProcessor implements Runnable {
	private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
	private AsyncContext asyncContext;

    private String adapterGroupName;
    private String adapterName;
    private String encode = "euc-kr";
    
	public AsyncRequestProcessor() {
	}

	public AsyncRequestProcessor(AsyncContext asyncCtx) {
		this.asyncContext = asyncCtx;
		
		// TODO : define adapter name rule
		this.adapterGroupName = "_EAI_IN_HTT_SyS";
		this.adapterName = "_EAI_IN_HTT_SyS{ALL}";
	}

	@Override
	public void run() {
//		System.out.println("Async Supported? "
//				+ asyncContext.getRequest().isAsyncSupported());
		
		ServletRequest request = asyncContext.getRequest();
		
		ServletInputStream sis;
		byte[] requestBytes = null;
		byte[] result = null;
		try {
			sis = request.getInputStream();
		
	    	ByteBuffer bb = ByteBuffer.allocate(1024);
		    int i=0;
		    byte[] cbuf = new byte[1024];
		    while( ( i = sis.read(cbuf, 0, 1024) ) != -1 ) {
		    	if (i==1024){
		    		bb.put(cbuf);
		    	}else{
		    		byte[] tail = new byte[i];
		    		System.arraycopy(cbuf, 0, tail, 0, i);
		    		bb.put(tail);
		    	}
		    }
		    requestBytes = new byte[bb.position()];
		    bb.position(0);
		    bb.get(requestBytes);
		    
            Properties prop = new Properties();
            // call Inbound Proxy
            result = service(requestBytes, prop);
			PrintWriter out = asyncContext.getResponse().getWriter();
			String encodedResponse = new String(result, encode);
			out.write(encodedResponse);
		} catch (IOException e1) {
			logger.error("AsyncRequestProcessor IOException",  e1);
		} catch (Exception e) {
			logger.error("AsyncRequestProcessor Exception",  e);
		}
		finally {
			if(asyncContext != null) {
				asyncContext.complete();
			}
		}
	}

	protected byte[] service(byte[] message, Properties prop) throws Exception {
        Object obj = RequestDispatcher.getRequestDispatcher(this.adapterGroupName).handle(adapterName, message, prop);
        if(obj == null) return null;
        if(obj instanceof byte[]) {
            return (byte[])obj;   
        } else if(obj instanceof String) {
            return ((String)obj).getBytes();
        } else {
            throw new Exception("RECEAIAHA001");
        }
    }
}

