// Path: siden-core/src/main/java/ninja/siden/Connection.java
// public interface Connection extends AttributeContainer {
// 
// 	// endpoint methods
// 
// 	CompletableFuture<Void> send(String text);
// 
// 	CompletableFuture<Void> send(ByteBuffer payload);
// 
// 	CompletableFuture<Void> ping(ByteBuffer payload);
// 
// 	CompletableFuture<Void> pong(ByteBuffer payload);
// 
// 	CompletableFuture<Void> close();
// 
// 	CompletableFuture<Void> close(int code, String reason);
// 
// 	void sendStream(ExceptionalConsumer<OutputStream, Exception> fn);
// 
// 	void sendWriter(ExceptionalConsumer<Writer, Exception> fn);
// 
// 	// informations
// 
// 	String protocolVersion();
// 
// 	String subProtocol();
// 
// 	boolean secure();
// 
// 	boolean open();
// 
// 	Set<Connection> peers();
// 
// 	// from request
// 
// 	Optional<String> params(String key);
// 
// 	Map<String, String> params();
// 
// 	Optional<String> query(String key);
// 
// 	Optional<String> header(String name);
// 
// 	List<String> headers(String name);
// 
// 	Map<String, List<String>> headers();
// 
// 	Map<String, Cookie> cookies();
// 
// 	Optional<Cookie> cookie(String name);
// 
// 	/**
// 	 * get current session
// 	 * 
// 	 * @return session or empty
// 	 */
// 	Optional<Session> current();
// 
// 	WebSocketChannel raw();
// 
// }
// 
// Path: siden-core/src/main/java/ninja/siden/WebSocket.java
// public interface WebSocket {
// 
// 	default void onConnect(Connection connection) throws Exception {
// 	}
// 
// 	default void onText(String payload) throws Exception {
// 	}
// 
// 	default void onBinary(ByteBuffer[] payload) throws Exception {
// 	}
// 
// 	default void onPong(ByteBuffer[] payload) throws Exception {
// 	}
// 
// 	default void onPing(ByteBuffer[] payload) throws Exception {
// 	}
// 
// 	default void onClose(ByteBuffer[] payload) throws Exception {
// 	}
// }
// 
// Path: siden-core/src/main/java/ninja/siden/WebSocketFactory.java
// public interface WebSocketFactory {
// 
// 	WebSocket create(Connection connection);
// }


import io.undertow.UndertowLogger;
import io.undertow.websockets.WebSocketConnectionCallback;
import io.undertow.websockets.core.WebSocketChannel;
import io.undertow.websockets.spi.WebSocketHttpExchange;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import ninja.siden.Connection;
import ninja.siden.WebSocket;
import ninja.siden.WebSocketFactory;
import org.xnio.IoUtils;
/*
 * Copyright 2014 SATO taichi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package ninja.siden.internal;





/**
 * @author taichi
 */
public class ConnectionCallback implements WebSocketConnectionCallback {

	final WebSocketFactory factory;
	final Set<Connection> peers = Collections
			.newSetFromMap(new ConcurrentHashMap<>());

	public ConnectionCallback(WebSocketFactory factory) {
		this.factory = factory;
	}

	@Override
	public void onConnect(WebSocketHttpExchange exchange,
			WebSocketChannel channel) {
		try {
			Connection connection = new SidenConnection(exchange, channel,
					peers);
// Path: siden-core/src/main/java/ninja/siden/Connection.java
// public interface Connection extends AttributeContainer {
// 
// 	// endpoint methods
// 
// 	CompletableFuture<Void> send(String text);
// 
// 	CompletableFuture<Void> send(ByteBuffer payload);
// 
// 	CompletableFuture<Void> ping(ByteBuffer payload);
// 
// 	CompletableFuture<Void> pong(ByteBuffer payload);
// 
// 	CompletableFuture<Void> close();
// 
// 	CompletableFuture<Void> close(int code, String reason);
// 
// 	void sendStream(ExceptionalConsumer<OutputStream, Exception> fn);
// 
// 	void sendWriter(ExceptionalConsumer<Writer, Exception> fn);
// 
// 	// informations
// 
// 	String protocolVersion();
// 
// 	String subProtocol();
// 
// 	boolean secure();
// 
// 	boolean open();
// 
// 	Set<Connection> peers();
// 
// 	// from request
// 
// 	Optional<String> params(String key);
// 
// 	Map<String, String> params();
// 
// 	Optional<String> query(String key);
// 
// 	Optional<String> header(String name);
// 
// 	List<String> headers(String name);
// 
// 	Map<String, List<String>> headers();
// 
// 	Map<String, Cookie> cookies();
// 
// 	Optional<Cookie> cookie(String name);
// 
// 	/**
// 	 * get current session
// 	 * 
// 	 * @return session or empty
// 	 */
// 	Optional<Session> current();
// 
// 	WebSocketChannel raw();
// 
// }
// 
// Path: siden-core/src/main/java/ninja/siden/WebSocket.java
// public interface WebSocket {
// 
// 	default void onConnect(Connection connection) throws Exception {
// 	}
// 
// 	default void onText(String payload) throws Exception {
// 	}
// 
// 	default void onBinary(ByteBuffer[] payload) throws Exception {
// 	}
// 
// 	default void onPong(ByteBuffer[] payload) throws Exception {
// 	}
// 
// 	default void onPing(ByteBuffer[] payload) throws Exception {
// 	}
// 
// 	default void onClose(ByteBuffer[] payload) throws Exception {
// 	}
// }
// 
// Path: siden-core/src/main/java/ninja/siden/WebSocketFactory.java
// public interface WebSocketFactory {
// 
// 	WebSocket create(Connection connection);
// }


// Path: siden-core/src/main/java/ninja/siden/internal/ConnectionCallback.java
import io.undertow.UndertowLogger;
import io.undertow.websockets.WebSocketConnectionCallback;
import io.undertow.websockets.core.WebSocketChannel;
import io.undertow.websockets.spi.WebSocketHttpExchange;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import ninja.siden.Connection;
import ninja.siden.WebSocket;
import ninja.siden.WebSocketFactory;
import org.xnio.IoUtils;

/*
 * Copyright 2014 SATO taichi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package ninja.siden.internal;





/**
 * @author taichi
 */
public class ConnectionCallback implements WebSocketConnectionCallback {

	final WebSocketFactory factory;
	final Set<Connection> peers = Collections
			.newSetFromMap(new ConcurrentHashMap<>());

	public ConnectionCallback(WebSocketFactory factory) {
		this.factory = factory;
	}

	@Override
	public void onConnect(WebSocketHttpExchange exchange,
			WebSocketChannel channel) {
		try {
			Connection connection = new SidenConnection(exchange, channel,
					peers);
			WebSocket socket = factory.create(connection);