/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 
 */
package org.ocelotds.web;

import org.ocelotds.core.SessionManager;
import org.ocelotds.Constants;
import org.ocelotds.configuration.OcelotRequestConfigurator;
import org.ocelotds.core.services.CallServiceManager;
import org.ocelotds.encoders.MessageToClientEncoder;
import java.io.IOException;
import org.ocelotds.messaging.MessageFromClient;
import java.util.Map;
import javax.inject.Inject;
import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.ocelotds.core.CDIBeanResolver;
import org.ocelotds.annotations.OcelotLogger;
import org.slf4j.Logger;

/**
 * WebSocket endpoint
 *
 * @author hhfrancois
 */
@ServerEndpoint(value = "/ocelot-endpoint", encoders = {MessageToClientEncoder.class}, configurator = OcelotRequestConfigurator.class)
public class OcelotEndpoint {

	@Inject
	@OcelotLogger
	private Logger logger;

	@Inject
	private SessionManager sessionManager;

	@Inject
	private CallServiceManager callServiceManager;

	/**
	 * A connection is open
	 *
	 * @param session
	 * @param config
	 * @throws IOException
	 */
	@OnOpen
	public void handleOpenConnexion(Session session, EndpointConfig config) throws IOException {
		Map<String, Object> configProperties = config.getUserProperties();
		Map<String, Object> sessionProperties = session.getUserProperties();
		// Get subject from config and set in session, only one time by connexion
		sessionProperties.put(Constants.SESSION_BEANS, configProperties.get(Constants.SESSION_BEANS));
		sessionProperties.put(Constants.SECURITY_CONTEXT, configProperties.get(Constants.SECURITY_CONTEXT));
		sessionProperties.put(Constants.LOCALE, configProperties.get(Constants.LOCALE));
	}
	@OnError
	public void onError(Session session, Throwable t) {
		logger.error("Unknow error for session " + session.getId(), t);
	}

	/**
	 * Close a session
	 *
	 * @param session
	 * @param closeReason
	 */
	@OnClose
	public void handleClosedConnection(Session session, CloseReason closeReason) {
		logger.debug("Close connexion for session '{}' : '{}'", session.getId(), closeReason.getCloseCode());
		if (session.isOpen()) {
			try {
				session.close();
			} catch (IllegalStateException | IOException ex) {
			}
			getSessionManager().removeSessionToTopics(session);
		}
	}

	/**
	 * A message is a call service request or subscribe/unsubscribe topic
	 *
	 * @param client
	 * @param json
	 */
	@OnMessage
	public void receiveCommandMessage(Session client, String json) {
		MessageFromClient message = MessageFromClient.createFromJson(json);
		logger.debug("Receive call message '{}' for session '{}'", message.getId(), client.getId());
		getCallServiceManager().sendMessageToClient(message, client);
	}

	SessionManager getSessionManager() {
		if (null == sessionManager) {
			sessionManager = getCDIBeanResolver().getBean(SessionManager.class);
		}
		return sessionManager;
	}

	CallServiceManager getCallServiceManager() {
		if (null == callServiceManager) {
			callServiceManager = getCDIBeanResolver().getBean(CallServiceManager.class);
		}
		return callServiceManager;
	}
	
	CDIBeanResolver getCDIBeanResolver() {
		return new CDIBeanResolver();  // Tomcat exploit
	}

}

@@ -1014,16 +1014,49 @@
 Logger;%0D
+%0Aimport org.slf4j.LoggerFactory;%0D
 %0A%0D%0A/**%0D%0A
@@ -1971,24 +1971,91 @@
 N_BEANS));%0D%0A
+%09%09if(configProperties.containsKey(Constants.SECURITY_CONTEXT)) %7B%0D%0A%09
 %09%09sessionPro
@@ -2146,16 +2146,21 @@
 EXT));%0D%0A
+%09%09%7D%0D%0A
 %09%09sessio
@@ -2306,22 +2306,27 @@
 t) %7B%0D%0A%09%09
-l
+getL
 ogger
+()
 .error(%22
@@ -2554,30 +2554,35 @@
 eason) %7B%0D%0A%09%09
-l
+getL
 ogger
+()
 .debug(%22Clos
@@ -3131,22 +3131,27 @@
 on);%0D%0A%09%09
-l
+getL
 ogger
+()
 .debug(%22
@@ -3301,16 +3301,153 @@
 %0D%0A%09%7D%0D%0A%0D%0A
+%09Logger getLogger() %7B%0D%0A%09%09if (null == logger) %7B%0D%0A%09%09%09logger = LoggerFactory.getLogger(OcelotEndpoint.class);%0D%0A%09%09%7D%0D%0A%09%09return logger;%0D%0A%09%7D%0D%0A%0D%0A
 %09Session

fix bug no injection in tomcatws endpoint fix NPE if securityContext is null