package better.jsonrpc.websocket;

import java.io.IOException;
import java.util.logging.Level;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocket.OnTextMessage;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import better.jsonrpc.core.JsonRpcConnection;

public class JsonRpcWsConnection extends JsonRpcConnection implements WebSocket, OnTextMessage {
	
	/** Currently active websocket connection */
	private Connection mConnection;
	
	public JsonRpcWsConnection(ObjectMapper mapper) {
		super(mapper);
	}
	
	@Override
	public boolean isConnected() {
		return mConnection != null && mConnection.isOpen();
	}
	
	public void disconnect() {
		if(mConnection != null && mConnection.isOpen()) {
			mConnection.close();
		}
	}
	
	public void transmit(String data) throws IOException {
        if(LOG.isTraceEnabled()) {
		    LOG.trace("[" + mConnectionId + "] transmitting \"" + data + "\"");
        }
		if(mConnection != null && mConnection.isOpen()) {
			mConnection.sendMessage(data);
		}
	}

	@Override
	public void onOpen(Connection connection) {
        if(LOG.isDebugEnabled()) {
		    LOG.debug("[" + mConnectionId + "] connection open");
        }
		super.onOpen();
		mConnection = connection;
	}

	@Override
	public void onClose(int closeCode, String message) {
        if(LOG.isDebugEnabled()) {
		    LOG.debug("[" + mConnectionId + "] connection close " + closeCode + "/" + message);
        }
		super.onClose();
		mConnection = null;
	}
	
	@Override
	public void onMessage(String data) {
        if(LOG.isTraceEnabled()) {
		    LOG.trace("[" + mConnectionId + "] received \"" + data + "\"");
        }
		try {
			JsonNode message = getMapper().readTree(data);
			if(message.isObject()) {
				ObjectNode messageObj = ObjectNode.class.cast(message);
				
				// requests and notifications
				if(messageObj.has("method")) {
					if(messageObj.has("id")) {
						handleRequest(messageObj);
					} else {
						handleNotification(messageObj);
					}
				}
				// responses
				if(messageObj.has("result") || messageObj.has("error")) {
					if(messageObj.has("id")) {
						handleResponse(messageObj);
					}
				}
			}
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}
	
	@Override
	public void sendRequest(ObjectNode request) throws IOException {
		transmit(request.toString());
	}

	@Override
	public void sendResponse(ObjectNode response) throws IOException {
		transmit(response.toString());
	}
	
	@Override
	public void sendNotification(ObjectNode notification) throws IOException {
		transmit(notification.toString());
	}
	
}

@@ -640,84 +640,1051 @@
 on;%0A
-%09%0A%09public JsonRpcWsConnection(ObjectMapper mapper) %7B%0A%09%09super(mapper);%0A%09%7D%0A%09%0A%09
+%0A    /** Max idle time for the connection */%0A    private int mMaxIdleTime = 300 * 1000;%0A%0A    /** Max test message size */%0A    private int mMaxTextMessageSize = 1 %3C%3C 16;%0A%0A    /** Max binary message size */%0A    private int mMaxBinaryMessageSize = 1 %3C%3C 16;%0A%09%0A%09public JsonRpcWsConnection(ObjectMapper mapper) %7B%0A%09%09super(mapper);%0A%09%7D%0A%0A    public int getMaxIdleTime() %7B%0A        return mMaxIdleTime;%0A    %7D%0A%0A    public void setMaxIdleTime(int maxIdleTime) %7B%0A        this.mMaxIdleTime = maxIdleTime;%0A        applyConnectionParameters();%0A    %7D%0A%0A    public int getMaxTextMessageSize() %7B%0A        return mMaxTextMessageSize;%0A    %7D%0A%0A    public void setMaxTextMessageSize(int maxTextMessageSize) %7B%0A        this.mMaxTextMessageSize = maxTextMessageSize;%0A        applyConnectionParameters();%0A    %7D%0A%0A    public int getMaxBinaryMessageSize() %7B%0A        return mMaxBinaryMessageSize;%0A    %7D%0A%0A    public void setMaxBinaryMessageSize(int maxBinaryMessageSize) %7B%0A        this.mMaxBinaryMessageSize = maxBinaryMessageSize;%0A        applyConnectionParameters();%0A    %7D%0A%0A    
 @Ove
@@ -2369,16 +2369,53 @@
 ection;%0A
+        applyConnectionParameters();%0A
 %09%7D%0A%0A%09@Ov
@@ -3501,24 +3501,316 @@
 ce();%0A%09%09%7D%0A%09%7D
+%0A%0A    private void applyConnectionParameters() %7B%0A        if(mConnection != null) %7B%0A            mConnection.setMaxIdleTime(mMaxIdleTime);%0A            mConnection.setMaxTextMessageSize(mMaxTextMessageSize);%0A            mConnection.setMaxBinaryMessageSize(mMaxBinaryMessageSize);%0A        %7D%0A    %7D
 %0A%09%0A%09@Overrid

Support for websocket connection parameters (idle timeout, max message size)