package foam.nanos.ws;

import foam.core.*;
import org.java_websocket.server.*;
import org.java_websocket.handshake.*;
import org.java_websocket.*;
import foam.nanos.logger.Logger;

import java.net.InetSocketAddress;

public class WebSocketServer
    extends org.java_websocket.server.WebSocketServer
    implements foam.core.ContextAware
{
    // ContextAware support.
    protected X x;
    public void setX(X x) {
        this.x = x;
    }
    public X getX() {
        return x;
    }

    protected foam.nanos.box.NanoServiceRouter router_ = null;
    protected foam.nanos.box.NanoServiceRouter getRouter() {
        if ( router_ == null ) {
            router_ = getX().create(foam.nanos.box.NanoServiceRouter.class);
        }
        return router_;
    }

    public WebSocketServer(InetSocketAddress address) {
        super(address);
    }

    public void onClose(WebSocket connection, int code, String reason, boolean remote) {
    }

    public void onError(WebSocket conn, Exception ex) {
    }

    public void onMessage(WebSocket conn, String message) {
        Logger                log        = (Logger)getX().get("logger");

        System.out.println("WS Request" + message);
        log.info("Incoming websocket request");

        try {
            String                path       = conn.getResourceDescriptor();
            String[]              urlParts   = path.split("/");
            String                serviceKey = urlParts[1];
            Object                service    = getX().get(serviceKey);
            foam.dao.DAO          nSpecDAO   = (foam.dao.DAO) getX().get("nSpecDAO");
            foam.nanos.boot.NSpec spec       = (foam.nanos.boot.NSpec) nSpecDAO.find(serviceKey);

            if ( spec == null ) {
                log.warning("Request for non-existant service", serviceKey);
                return;
            }

            if ( ! spec.getServe() ) {
                log.warning("Request for service that is not serving.", serviceKey);
                return;
            }

            foam.box.RawWebSocketBox returnBox = getX().create(foam.box.RawWebSocketBox.class);
            returnBox.setSocket(conn);

            X requestContext = getX().put("returnBox", returnBox);

            FObject request = requestContext.create(foam.lib.json.JSONParser.class).parseString(message);

            if ( request == null || ! ( request instanceof foam.box.Message ) ) {
                log.warning("Invalid request");
                return;
            }

            getRouter().service(serviceKey, (foam.box.Message)request);
        } catch(Exception e) {
            log.error("Error handling websocket request", e);
        }
    }

    public void onOpen(WebSocket conn, ClientHandshake handshake) {
        Logger log = (Logger)getX().get("logger");
        log.info("WebSocket client connect.");
    }

    public void onStart() {
    }
}

@@ -2371,10 +2371,124 @@
 ull 
-%7C%7C
+) %7B%0A                log.warning(%22Failed to parse request.%22);%0A                return;%0A            %7D%0A%0A            if (
  ! (
@@ -2563,23 +2563,38 @@
 ng(%22
-Invalid request
+Request was not a box message.
 %22);%0A

Improve logging output from WebSocketServer